⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net_tftpc.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:

    for (i=0; i<TFTPC_SAP_BUFFER_COUNT; i++)
    {
        /* allocate SAP buffer */
        mem.size     = TFTP_HEADER_DATA_MAX_SIZE ;
        mem.boundary = TFTPC_SAP_BUFFER_ALIGNMENT_SIZE ;
        mem.memory   = &(ptmp) ;
        rcode = SYSCON_read( SYSCON_BOARD_MALLOC_ID,
                             &mem,
                             sizeof(t_sys_malloc) ) ;
        if (rcode != OK)
        {
           return( rcode ) ;
        }
        sap_context.buf[i].blink = (UINT8*) KSEG0( (UINT32)ptmp ) ;
    }

    /* initialize SAP */
    rcode = NET_TFTPC_init_sap( &sap_context ) ;

    /* TFTPC-module has now been initialized */
    NET_TFTPC_state = TFTPC_STATE_OPEN ;

    return( rcode ) ;
}


/************************************************************************
 *
 *                          NET_TFTPC_open
 *  Description :
 *  -------------
 *  Allocate a TFTPC-SAP, register user context, 
 *  and request UDP to send 'RRQ'.
 *
 *
 *  Parameters :
 *  ------------
 *  'ip_adr',          IN,    destination ip address (BE)
 *  'filename',        IN,    filename to read
 *  'sp_hd',           OUT,   handle of TFTPC to be used by user by call
 *                            of 'read', 'readbyte' or 'close'
 *
 *  Return values :
 *  ---------------
 *  'ERROR_NET_TFTPC_FATAL_STATE'      A fatal state has been detected in TFTPC.
 *  'ERROR_NET_TFTPC_NOT_INITIALIZED'  TFTPC-'init' has not been called.
 *  'OK'(=0),
 *
 *
 ************************************************************************/
UINT32 NET_TFTPC_open( UINT32     ip_adr,    /* destination ip address (BE) */
                       UINT8      *filename, /* filename to read            */
                       UINT32     *sp_hd )   /* file session handle         */
{
    UINT32  old_ie, time_now ;
    UINT32  rcode = OK ;
    int     len ;

#ifdef NET_DEBUG
    printf("NET_TFTPC_open\n") ;
#endif

    old_ie = sys_disable_int() ;
    switch (NET_TFTPC_state)
    {
        case TFTPC_STATE_CLOSED:
                rcode = ERROR_NET_TFTPC_NOT_INITIALIZED ;
            break;

        case TFTPC_STATE_OPEN:
                /* Reset the one and only SAP */
                *sp_hd = 0 ; /* actually, this is not used */
                rcode = NET_TFTPC_reset_sap( &sap_context,
                                             NET_TFTPC_receive_data_byte ) ;

                /* validate filename length */
                len = strlen(filename) ;
                if (len > TFTP_HEADER_FILENAME_MAX_LENGTH)
                {
                    rcode = ERROR_NET_TFTPC_INVALID_FILENAME ;
                    break;
                }

                /* Save user context to this SAP */
                sap_context.dst_ip_adr = ip_adr ;
                strcpy( sap_context.filename, filename ) ;
                strcpy( &sap_context.filename[len+1], TFTP_HEADER_MODE_OCTET ) ;

                /* Set retry count */
                sap_context.retry_left = TFTPC_SAP_MAX_RETRY_COUNT ;

                /* get time now (unit is seconds since 1.1.1970) */
                NET_gettime( &time_now ) ;
                sap_context.timeout = time_now + TFTPC_SAP_TIMEOUT ;

                /* New state = 'WAIT_FIRST_BLOCK' */
                sap_context.sap_state = TFTPC_SAP_STATE_WAIT_FIRST_BLOCK ;

                /* Send 'RRQ' */
                rcode = NET_TFTPC_sendRRQ( &sap_context ) ;
            break;

        default:
                /* we should never arrive here */
                rcode = ERROR_NET_TFTPC_FATAL_STATE ;
            break;

    }
    if(old_ie) sys_enable_int();
    return( rcode ) ;
}



/************************************************************************
 *
 *                          NET_TFTPC_close
 *  Description :
 *  -------------
 *  Close  TFTPC-SAP.
 *
 *
 *  Parameters :
 *  ------------
 *  -
 *
 *
 *  Return values :
 *  ---------------
 *  'OK'(=0),              TFTPC SAP has been closed
 *
 *
 ************************************************************************/
UINT32 NET_TFTPC_close( UINT32 sp_hd )
{
    UINT32 rcode, old_ie ;

#ifdef NET_DEBUG
    printf("NET_TFTPC_close\n") ;
#endif

    /* Close SAP */

    /* Reset context */
    old_ie = sys_disable_int() ;
    rcode = NET_TFTPC_reset_sap( &sap_context,
                                 NET_TFTPC_receive_data_byte ) ;
    if(old_ie) sys_enable_int();

    return( rcode ) ;
}


/************************************************************************
 *
 *                          NET_TFTPC_readbyte
 *  Description :
 *  -------------
 *  Read one byte of received data.
 *
 *
 *  Parameters :
 *  ------------
 *  -
 *
 *
 *  Return values :
 *  ---------------
 *  'OK'(=0),               Byte has been read.
 *
 *
 ************************************************************************/
UINT32 NET_TFTPC_readbyte( UINT32 sp_hd,
                           UINT8  *byte )
{
    UINT32 old_ie, rcode, time_now, index ;

    if ( sap_context.bytes_left )
    {
        /* Normal case1: We seem to have data */
        sap_context.bytes_left-- ; 
        *byte = *sap_context.pread++ ;
        rcode = OK ;
    }
    else
    {
        /* No data, re-evaluate buffer status */
        old_ie = sys_disable_int() ;
        rcode = ERROR_NET_TFTPC_NO_DATA ;
        index = sap_context.read_idx ;
        if ( sap_context.buf[ index ].ctrl == BUFFER_STATE_READING )
        {
            /* we have just finished another buffer, proceed to next buffer */
            sap_context.buf[ index ].count = 0 ;
            sap_context.buf[ index ].ctrl  = BUFFER_STATE_EMPTY ;
            sap_context.read_idx++ ;
            if (sap_context.read_idx == TFTPC_SAP_BUFFER_COUNT)
            {
                sap_context.read_idx = 0 ;
            }
            index = sap_context.read_idx ;
        }
        
        /* check for data in next buffer */
        if ( sap_context.buf[ index ].ctrl == BUFFER_STATE_FULL )
        {
            /* we just received another buffer, proceed */
            sap_context.pread = sap_context.buf[ index ].blink ;
            sap_context.bytes_left = sap_context.buf[ index ].count ;
            sap_context.buf[ index ].ctrl  = BUFFER_STATE_READING ;

            /* read first byte in next buffer */
            sap_context.bytes_left-- ;
            *byte = *sap_context.pread++ ;
            rcode = OK ;
        }

        /* Last case: no data, evaluate why */
        if ( sap_context.buf[ index ].ctrl == BUFFER_STATE_EMPTY )
        {
            if ( sap_context.sap_state == TFTPC_SAP_STATE_LAST_BLOCK_READ )
            {
                *byte = EOF_SREC ;
                rcode = ERROR_NET_TFTPC_EOF ;
            }

            if ( sap_context.sap_state == TFTPC_SAP_STATE_ERROR)
            {
                *byte = EOF_SREC ;
                rcode = ERROR_NET_TFTPC_SAP_ERROR_STATE ;
            }

            if (sap_context.sap_state == TFTPC_SAP_STATE_CONGESTION)
            {
                /* Set retry count */
                sap_context.retry_left = TFTPC_SAP_MAX_RETRY_COUNT ;

                /* get time now (unit is seconds since 1.1.1970) */
                NET_gettime( &time_now ) ;
                sap_context.timeout = time_now + TFTPC_SAP_TIMEOUT ;

                sap_context.sap_state = TFTPC_SAP_STATE_WAIT_NEXT_BLOCK ;
                NET_TFTPC_sendACK( &sap_context ) ;
            }
        }
        if(old_ie) sys_enable_int();
    }
    return( rcode ) ;
}


/************************************************************************
 *
 *                          NET_TFTPC_file_read
 *  Description :
 *  -------------
 *  Read file ('filename') of host('ipadr') into 'buffer'
 *
 *
 *  Parameters :
 *  ------------
 *  'ip_adr',          IN,    TFTP server host ip address (BE)
 *  'filename',        IN,    name of file to read
 *  'buffer',          IN,    pointer to buffer to write
 *  'size',            IN,    pointer to size of buffer
 *  'poll',            IN,    pointer to poll function to do be called
 *                            during file transfer
 *
 *
 *  Return values :
 *  ---------------
 *  'OK'(=0),                 File has been read.
 *
 *
 ************************************************************************/
UINT32 NET_TFTPC_file_read( UINT32 ipadr,
                            UINT8  *filename,
                            UINT8  *buffer,
                            UINT32 *size,
                            UINT32 (*poll)(void) )
{
    UINT32  old_ie, time_now ;
    UINT32  rcode = OK ;
    int     len ;

#ifdef NET_DEBUG
    printf("NET_TFTPC_file_read\n") ;
#endif

    /* clear error context */
    net_last_error  = OK ;
    net_diag_msg[0] = 0 ;

    old_ie = sys_disable_int() ;
    switch (NET_TFTPC_state)
    {
        case TFTPC_STATE_CLOSED:
                rcode = ERROR_NET_TFTPC_NOT_INITIALIZED ;
            break;

        case TFTPC_STATE_OPEN:
                /* Reset the one and only SAP */
                rcode = NET_TFTPC_reset_sap( &sap_context,
                                             NET_TFTPC_receive_data_block ) ;

                /* validate filename length */
                len = strlen(filename) ;
                if (len > TFTP_HEADER_FILENAME_MAX_LENGTH)
                {
                    rcode = ERROR_NET_TFTPC_INVALID_FILENAME ;
                    break;
                }

                /* Save user context to this SAP */
                sap_context.dst_ip_adr = ipadr ;
                sap_context.puser      = buffer ;
                sap_context.user_size  = *size ;
                sap_context.bytes_left = *size ;
                strcpy( sap_context.filename, filename ) ;
                strcpy( &sap_context.filename[len+1], TFTP_HEADER_MODE_OCTET ) ;

                /* Set retry count */
                sap_context.retry_left = TFTPC_SAP_MAX_RETRY_COUNT ;

                /* get time now (unit is seconds since 1.1.1970) */
                NET_gettime( &time_now ) ;
                sap_context.timeout = time_now + TFTPC_SAP_TIMEOUT ;

                /* New state = 'WAIT_FIRST_BLOCK' */
                sap_context.sap_state = TFTPC_SAP_STATE_WAIT_FIRST_BLOCK ;

                /* Send 'RRQ' */
                rcode = NET_TFTPC_sendRRQ( &sap_context ) ;
            break;

        default:
                /* we should never arrive here */
                rcode = ERROR_NET_TFTPC_FATAL_STATE ;
            break;

    }
    if(old_ie) sys_enable_int();

    while (1)
    {
        if ((rcode !=OK) && (rcode != ERROR_NET_ARP_MAC_NOT_RESOLUTED))
        {
            break ;
        }

        if ( sap_context.sap_state == TFTPC_SAP_STATE_LAST_BLOCK_READ )
        {
            rcode = OK ;
            break ;
        }

        if ( sap_context.sap_state == TFTPC_SAP_STATE_ERROR)
        {
            rcode = sap_context.error_cause ;
            break ;
        }

        (*poll)() ;
    }

    *size = sap_context.user_size - sap_context.bytes_left ;
    NET_TFTPC_close( 0 ) ;
    net_last_error = rcode ;
    return( rcode ) ;
}


/************************************************************************
 *
 *                          NET_TFTPC_file_write
 *  Description :
 *  -------------
 *  Write 'buffer' into file('filename') of host('ipadr')
 *
 *
 *  Parameters :
 *  ------------
 *  'ip_adr',          IN,    TFTP server host ip address (BE)
 *  'filename',        IN,    name of file to write
 *  'buffer',          IN,    pointer to buffer to read into file
 *  'size',            IN,    pointer to size of buffer
 *  'poll',            IN,    pointer to poll function to do be called
 *                            during file transfer
 *
 *
 *  Return values :
 *  ---------------
 *  'OK'(=0),                 Buffer has been written.
 *
 *
 ************************************************************************/
UINT32 NET_TFTPC_file_write( UINT32 ipadr,
                             UINT8  *filename,
                             UINT8  *buffer,
                             UINT32 *size,
                             UINT32 (*poll)(void) )
{
    UINT32  old_ie, time_now ;
    UINT32  rcode = OK ;
    int     len ;

#ifdef NET_DEBUG
    printf("NET_TFTPC_file_write\n") ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -