📄 net_tftpc.c
字号:
{ if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_ACK) { /* save HOST error */ sap_context.host_error = tmp2 ; data[length] = 0 ; strcpy( sap_context.host_error_msg, &data[TFTP_HEADER_BASE + TFTP_HEADER_ERRORMSG] ) ; sprintf( net_diag_msg, "Host returned: ErrorCode = %d, ErrorMsg = %s", sap_context.host_error, sap_context.host_error_msg ); sap_context.error_cause = ERROR_NET_TFTP_WRITE_ERROR ; } if ( (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_NEXT_ACK) || (sap_context.sap_state == TFTPC_SAP_STATE_LAST_BLOCK_WRITE) ) { /* validate 'src_port' */ if (sap_context.dst_port != src_port) { /* Ignore packet, and reply 'unknown TID' */ rcode = NET_TFTPC_unknownTID( src_ip_adr, src_port, sap_context.udp_sp_hd ) ; /* do nothing */ return( ERROR_NET_TFTPC_INVALID_TID ) ; } /* save HOST error */ sap_context.host_error = tmp2 ; data[length] = 0 ; strcpy( sap_context.host_error_msg, &data[TFTP_HEADER_BASE + TFTP_HEADER_ERRORMSG] ) ; sprintf( net_diag_msg, "Host returned: ErrorCode = %d, ErrorMsg = %s", sap_context.host_error, sap_context.host_error_msg ); sap_context.error_cause = ERROR_NET_TFTP_DATA_ERROR ; } /* New state: 'ERROR' */ sap_context.sap_state = TFTPC_SAP_STATE_ERROR ; } /* return, despite if it is not ACK */ return( sap_context.error_cause ) ; } /* We have 'ACK' */ /* Check for 1. 'ACK' and save 'src_port', and src-MAC */ if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_ACK) { sap_context.dst_port = src_port ; memcpy( &sap_context.dst_mac_adr, src_mac_adr, SYS_MAC_ADDR_SIZE ) ; } else { /* validate 'src_port' */ if (sap_context.dst_port != src_port) { /* Ignore packet, and reply 'unknown TID' */ rcode = NET_TFTPC_unknownTID( src_ip_adr, src_port, sap_context.udp_sp_hd ) ; /* do nothing */ return( ERROR_NET_TFTPC_INVALID_TID ) ; } } /* 'TID' is valid */ /* Validate block number */ if (tmp2 != sap_context.block_number) { if (tmp2 == TFTP_HEADER_MAX_BLOCKNUMBER) { /* New state: 'ERROR' */ sap_context.sap_state = TFTPC_SAP_STATE_ERROR ; sap_context.error_cause = ERROR_NET_TFTP_FILE_TOO_BIG ; return( ERROR_NET_TFTP_FILE_TOO_BIG ) ; } /* To avoid the "Sorcerer's Apprentice: do nothing and let timer retransmit if host doesn't */ return( ERROR_NET_TFTPC_INVALID_BLOCK_NUMBER ) ; } if ( sap_context.bytes_left < TFTP_HEADER_DATA_MAX_SIZE ) { if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_ACK) { /* OK, proceed to send first (and last) block */ sap_context.block_number++ ; /* Set timer and retry count */ /* get time now (unit is seconds since 1.1.1970) */ NET_gettime( &sap_context.timeout ) ; sap_context.timeout = sap_context.timeout + TFTPC_SAP_TIMEOUT ; sap_context.retry_left = TFTPC_SAP_MAX_RETRY_COUNT ; /* Set state 'WAIT_NEXT_ACK' */ sap_context.sap_state = TFTPC_SAP_STATE_WAIT_NEXT_ACK ; /* Send DATA */ rcode = NET_TFTPC_sendDATA( &sap_context ) ; } else { /* Last block has been acknowledged */ /* update context */ sap_context.puser = sap_context.puser + sap_context.bytes_left ; sap_context.bytes_left = 0 ; /* Set state 'LAST_BLOCK_WRITE' */ sap_context.sap_state = TFTPC_SAP_STATE_LAST_BLOCK_WRITE ; } } else { if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_ACK) { /* OK, proceed to send first (full) block */ sap_context.block_number++ ; /* Set timer and retry count */ /* get time now (unit is seconds since 1.1.1970) */ NET_gettime( &sap_context.timeout ) ; sap_context.timeout = sap_context.timeout + TFTPC_SAP_TIMEOUT ; sap_context.retry_left = TFTPC_SAP_MAX_RETRY_COUNT ; /* Set state 'WAIT_NEXT_ACK' */ sap_context.sap_state = TFTPC_SAP_STATE_WAIT_NEXT_ACK ; /* Send DATA */ rcode = NET_TFTPC_sendDATA( &sap_context ) ; } else { /* OK, we have just sent a full block, update context */ /* indicate address in alpha-display */ DISP( (UINT32)sap_context.puser ) ; sap_context.bytes_left = sap_context.bytes_left - TFTP_HEADER_DATA_MAX_SIZE ; sap_context.puser = sap_context.puser + TFTP_HEADER_DATA_MAX_SIZE ; /* OK, proceed to send next block */ sap_context.block_number++ ; /* Set timer and retry count */ /* get time now (unit is seconds since 1.1.1970) */ NET_gettime( &sap_context.timeout ) ; sap_context.timeout = sap_context.timeout + TFTPC_SAP_TIMEOUT ; sap_context.retry_left = TFTPC_SAP_MAX_RETRY_COUNT ; /* Set state 'WAIT_NEXT_ACK' */ sap_context.sap_state = TFTPC_SAP_STATE_WAIT_NEXT_ACK ; /* Send DATA */ rcode = NET_TFTPC_sendDATA( &sap_context ) ; } } return( rcode ) ;}/************************************************************************ * * NET_TFTPC_receive_data_block * 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_data_block( 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 ; UINT32 tftp_data_length ; t_FLASH_write_descriptor flash_write ;#ifdef NET_DEBUG int i ; printf("NET_TFTPC_receive_data_block\n") ; printf("src_ip_adr = %x\n", (unsigned)BE32_TO_CPU(src_ip_adr) ) ; printf("src_port = %d\n", BE16_TO_CPU(src_port) ) ; printf("length = %d\n", length ) ; printf("src MAC = " ) ; p = (UINT8*) src_mac_adr ; for (i=0; i<6; i++) { printf(" %02x",*p++ ) ; } printf("\n" ) ;#endif /* 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 ) ; if (opcode != TFTP_HEADER_OPCODE_DATA) { /* We expect nothing else than 'DATA' or 'ERROR' */ /* check for HOST error */ if (opcode == TFTP_HEADER_OPCODE_ERROR) { if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_BLOCK) { /* save HOST error */ sap_context.host_error = tmp2 ; data[length] = 0 ; strcpy( sap_context.host_error_msg, &data[TFTP_HEADER_BASE + TFTP_HEADER_ERRORMSG] ) ; sprintf( net_diag_msg, "Host returned: ErrorCode = %d, ErrorMsg = %s", sap_context.host_error, sap_context.host_error_msg ); sap_context.error_cause = ERROR_NET_TFTP_READ_ERROR ; } if ( (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_NEXT_BLOCK) || (sap_context.sap_state == TFTPC_SAP_STATE_CONGESTION) || (sap_context.sap_state == TFTPC_SAP_STATE_LAST_BLOCK_READ) ) { /* validate 'src_port' */ if (sap_context.dst_port != src_port) { /* Ignore packet, and reply 'unknown TID' */ rcode = NET_TFTPC_unknownTID( src_ip_adr, src_port, sap_context.udp_sp_hd ) ; /* do nothing */ return( ERROR_NET_TFTPC_INVALID_TID ) ; } /* save HOST error */ sap_context.host_error = tmp2 ; data[length] = 0 ; strcpy( sap_context.host_error_msg, &data[TFTP_HEADER_BASE + TFTP_HEADER_ERRORMSG] ) ; sprintf( net_diag_msg, "Host returned: ErrorCode = %d, ErrorMsg = %s", sap_context.host_error, sap_context.host_error_msg ); sap_context.error_cause = ERROR_NET_TFTP_DATA_ERROR ; } /* New state: 'ERROR' */ sap_context.sap_state = TFTPC_SAP_STATE_ERROR ; } /* return, despite if it is not DATA */ return( sap_context.error_cause ) ; } /* We have 'DATA' */ /* Check for 1. Block data and save 'src_port', and src-MAC */ if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_BLOCK) { sap_context.dst_port = src_port ; memcpy( &sap_context.dst_mac_adr, src_mac_adr, SYS_MAC_ADDR_SIZE ) ; } else { /* validate 'src_port' */ if (sap_context.dst_port != src_port) { /* Ignore packet, and reply 'unknown TID' */ rcode = NET_TFTPC_unknownTID( src_ip_adr, src_port, sap_context.udp_sp_hd ) ; /* do nothing */ return( ERROR_NET_TFTPC_INVALID_TID ) ; } } /* 'TID' is valid */ /* Validate block number */ if (tmp2 != (sap_context.block_number + 1) ) { if (tmp2 == TFTP_HEADER_MAX_BLOCKNUMBER) { /* New state: 'ERROR' */ sap_context.sap_state = TFTPC_SAP_STATE_ERROR ; sap_context.error_cause = ERROR_NET_TFTP_FILE_TOO_BIG ; return( ERROR_NET_TFTP_FILE_TOO_BIG ) ; } /* To avoid the "Sorcerer's Apprentice: do nothing and let timer retransmit if host doesn't */ return( ERROR_NET_TFTPC_INVALID_BLOCK_NUMBER ) ; } /* Save data into user buffer */ tftp_data_length = length - (MAC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + TFTP_HEADER_DATA) ; if ( tftp_data_length <= sap_context.bytes_left ) { /* we have space for this block */ /* OK, send ACK now */ sap_context.block_number = tmp2 ; rcode = NET_TFTPC_sendACK( &sap_context ) ; /* save data in user buffer */ if(tftp_data_length) { /* Write data to RAM/FLASH * * dst addr = (UINT32)sap_context.puser * src addr = &data[TFTP_HEADER_BASE + TFTP_HEADER_DATA] */ /* Validate address */ rcode = sys_validate_range( (UINT32)sap_context.puser, tftp_data_length, sizeof(UINT8), TRUE ); if (rcode != OK) goto error_out; flash_write.adr = (UINT32)sap_context.puser; flash_write.length = tftp_data_length ; flash_write.buffer = &data[TFTP_HEADER_BASE + TFTP_HEADER_DATA] ; rcode = IO_write( SYS_MAJOR_FLASH_STRATA, 0, &flash_write ) ; if (rcode != OK) goto error_out; /* indicate address in alpha-display */ DISP( (UINT32)sap_context.puser ) ; } /* update context */ sap_context.bytes_left = sap_context.bytes_left - tftp_data_length ; sap_context.puser = sap_context.puser + tftp_data_length ; if (tftp_data_length < TFTP_HEADER_DATA_MAX_SIZE) { /* Set state 'LAST_BLOCK_READ' */ sap_context.sap_state = TFTPC_SAP_STATE_LAST_BLOCK_READ ; } else { /* Set timer and retry count */ /* get time now (unit is seconds since 1.1.1970) */ NET_gettime( &sap_context.timeout ) ; sap_context.timeout = sap_context.timeout + TFTPC_SAP_TIMEOUT ; sap_context.retry_left = TFTPC_SAP_MAX_RETRY_COUNT ; /* Set state 'WAIT_NEXT_BLOCK' */ sap_context.sap_state = TFTPC_SAP_STATE_WAIT_NEXT_BLOCK ; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -