📄 net_tftpc.c
字号:
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_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_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 rcode, 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-- ;
rcode = 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-- ;
rcode = 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)
{
/* Send 'ACK' */
sap_context.timeout = time_now + TFTPC_SAP_TIMEOUT ;
sap_context.retry_left-- ;
rcode = 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-- ;
rcode = 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 :
* ---------------
* 'OK'
*
************************************************************************/
static
UINT32 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 ;
UINT32 tftp_data_length ;
int i, index ;
/* 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 ;
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)
{
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)
{
/* We should just ignore this packet, */
/* 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)
{
/* We should just ignore this packet, */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -