📄 net_tftpc.c
字号:
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 : * --------------- * 'ERROR_NET_TFTP_FILE_TOO_BIG' * 'ERROR_NET_TFTPC_NOT_INITIALIZED' * 'ERROR_NET_TFTPC_INVALID_FILENAME' * 'ERROR_NET_TFTPC_FATAL_STATE' * 'OK'(=0) * * ************************************************************************/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") ; printf("ipadr = %x\n", (unsigned)(BE32_TO_CPU(ipadr)) ) ; printf("filename = %s\n", filename ) ; printf("size = %d\n", *size ) ;#endif /* clear error context */ net_last_error = OK ; net_diag_msg[0] = 0 ; if (*size > TFTP_FILE_MAX_SIZE) { rcode = ERROR_NET_TFTP_FILE_TOO_BIG ; net_last_error = rcode ; return( rcode ) ; } 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_ack ) ; /* 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_OPEN_RETRY_COUNT ; /* get time now (unit is seconds since 1.1.1970) */ NET_gettime( &time_now ) ; sap_context.timeout = time_now + TFTPC_SAP_OPEN_TIMEOUT ; /* New state = 'WAIT_FIRST_ACK' */ sap_context.sap_state = TFTPC_SAP_STATE_WAIT_FIRST_ACK ; /* Send 'WRQ' */ rcode = NET_TFTPC_sendWRQ( &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_WRITE ) { 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_poll * Description : * ------------- * Do timer managemnt of TFTPC-SAP's. or inquire state * * * Parameters : * ------------ * - * * * Return values : * --------------- * 'OK'(=0), * * ************************************************************************/UINT32 NET_TFTPC_poll( UINT32 *state, UINT32 *last_io_compl, UINT32 *cause ){ UINT32 time_now ; UINT32 old_ie ; if ( sap_context.sap_state == TFTPC_SAP_STATE_BOUND_TO_UDP ) { /* No TFTP-client session active; do nothing */ return( OK ) ; } /* Check for inquire */ if ( state != NULL ) { old_ie = sys_disable_int() ; *state = sap_context.sap_state ; *last_io_compl = sap_context.send_rc ; *cause = sap_context.error_cause ; if(old_ie) sys_enable_int(); return( OK ) ; } /* get time now (unit is seconds since 1.1.1970) */ NET_gettime( &time_now ) ; old_ie = sys_disable_int() ; switch (sap_context.sap_state) { case TFTPC_SAP_STATE_WAIT_FIRST_BLOCK: { /* Check for 'RRQ' retry */ if ( time_now >= sap_context.timeout ) { /* Check for any retries */ if (sap_context.retry_left) { /* Send 'RRQ' */ sap_context.timeout = time_now + TFTPC_SAP_OPEN_TIMEOUT ; sap_context.retry_left-- ; NET_TFTPC_sendRRQ( &sap_context ) ; } else { sap_context.sap_state = TFTPC_SAP_STATE_ERROR ; if (sap_context.send_rc == ERROR_NET_ARP_MAC_NOT_RESOLUTED) { sap_context.error_cause = ERROR_NET_ARP_TIME_OUT ; } else { sap_context.error_cause = ERROR_NET_TFTP_READ_TIMEOUT_ERROR ; } } } } break ; case TFTPC_SAP_STATE_WAIT_FIRST_ACK: { /* Check for 'WRQ' retry */ if ( time_now >= sap_context.timeout ) { /* Check for any retries */ if (sap_context.retry_left) { /* Send 'WRQ' */ sap_context.timeout = time_now + TFTPC_SAP_OPEN_TIMEOUT ; sap_context.retry_left-- ; NET_TFTPC_sendWRQ( &sap_context ) ; } else { sap_context.sap_state = TFTPC_SAP_STATE_ERROR ; if (sap_context.send_rc == ERROR_NET_ARP_MAC_NOT_RESOLUTED) { sap_context.error_cause = ERROR_NET_ARP_TIME_OUT ; } else { sap_context.error_cause = ERROR_NET_TFTP_WRITE_TIMEOUT_ERROR ; } } } } break ; case TFTPC_SAP_STATE_WAIT_NEXT_BLOCK: { /* Check for 'ACK' retry */ if ( time_now >= sap_context.timeout ) { /* Check for any retries */ if (sap_context.retry_left) { if (sap_context.retry_left == 1) { /* Set 'CLOSE' timeout */ sap_context.timeout = time_now + TFTPC_SAP_CLOSE_TIMEOUT ; sap_context.retry_left-- ; } else { /* Send 'ACK' */ sap_context.timeout = time_now + TFTPC_SAP_TIMEOUT ; sap_context.retry_left-- ; NET_TFTPC_sendACK( &sap_context ) ; } } else { sap_context.sap_state = TFTPC_SAP_STATE_ERROR ; sap_context.error_cause = ERROR_NET_TFTP_DATA_TIMEOUT_ERROR ; } } } break ; case TFTPC_SAP_STATE_WAIT_NEXT_ACK: { /* Check for 'DATA' retry */ if ( time_now >= sap_context.timeout ) { /* Check for any retries */ if (sap_context.retry_left) { /* Send 'DATA' */ sap_context.timeout = time_now + TFTPC_SAP_TIMEOUT ; sap_context.retry_left-- ; NET_TFTPC_sendDATA( &sap_context ) ; } else { sap_context.sap_state = TFTPC_SAP_STATE_ERROR ; sap_context.error_cause = ERROR_NET_TFTP_DATA_TIMEOUT_ERROR ; } } } default: /* we should never arrive here */ break; } if(old_ie) sys_enable_int(); return( OK ) ;}/************************************************************************ * Implementation : Static functions ************************************************************************//************************************************************************ * * NET_TFTPC_receive_ack * Description : * ------------- * This function is registered in the UDP-module and linked with a * unique UDP-'port', idnetifying our SAP. This allows the UDP to call * us back with an reference to the received frame, * containing a TFTP-frame. * * * * Parameters : * ------------ * 'src_ip_adr': senders IP-address in BE-format * 'src_port': senders UDP-port in BE-format * 'src_mac_adr': senders MAC-address * 'udp_sp_hd': UDP defined handle, identifying our SAP (i.e. port) * 'length': length of received ethernet frame * 'data': pointer for received ethernet frame (in driver's space) * * * Return values : * --------------- * 'ERROR_NET_TFTPC_SAP_ERROR_STATE' * 'ERROR_NET_TFTPC_INVALID_TID' * 'ERROR_NET_TFTP_FILE_TOO_BIG' * 'ERROR_NET_TFTPC_INVALID_BLOCK_NUMBER' * 'OK' * ************************************************************************/staticUINT32 NET_TFTPC_receive_ack( UINT32 src_ip_adr, /* IP BE-format */ UINT16 src_port, /* port BE-format */ t_mac_addr *src_mac_adr,/* MAC */ UINT32 udp_sp_hd, /* handle of open */ UINT32 length, /* total length */ UINT8 *data ) /* start of frame */{ UINT32 rcode = OK ; UINT8 *p ; UINT16 opcode ; UINT16 tmp2 ; /* We already registered an ERROR */ if (sap_context.sap_state == TFTPC_SAP_STATE_ERROR) { /* do nothing */ return(ERROR_NET_TFTPC_SAP_ERROR_STATE) ; } /* get TFTP-'opcode'-field of this received frame */ p = (data + TFTP_HEADER_BASE + TFTP_HEADER_OPCODE) ; get2( p, opcode) ; opcode = BE16_TO_CPU( opcode ) ; get2( p, tmp2) ; /* NOTE: 'tmp2' now keeps block-number or host-error */ tmp2 = BE16_TO_CPU( tmp2 ) ;#ifdef NET_DEBUG printf("NET_TFTPC_receive_ack\n") ; printf("src_ip_adr = %x\n", (unsigned)BE32_TO_CPU(src_ip_adr) ) ; printf("src_port = %d\n", (unsigned)BE16_TO_CPU(src_port) ) ; printf("length = %d\n", length ) ; printf("src MAC = " ) ; p = (UINT8*) src_mac_adr ; { int i ; for (i=0; i<6; i++) { printf(" %02x",*p++ ) ; } } printf("\n" ) ; printf("opcode = %d\n", (unsigned)opcode) ; printf("block nr. = %d\n", (unsigned)tmp2 ) ; printf("bytes_left = %d\n", (unsigned)sap_context.bytes_left ) ;#endif if (opcode != TFTP_HEADER_OPCODE_ACK) { /* We expect nothing else than 'ACK' or 'ERROR' */ /* check for HOST error */ if (opcode == TFTP_HEADER_OPCODE_ERROR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -