From: Stefan E. <se...@us...> - 2003-03-18 15:05:15
|
Update of /cvsroot/blob/blob/src/lib In directory sc8-pr-cvs1:/tmp/cvs-serv7489 Modified Files: tftp.c Log Message: - changed Russell's code such that we dont have an endless loop on errors, and we have a limited number of retries. - added a byte counter - changed signature of do_ftp(). Now returns error/success status and takes a size argument. Index: tftp.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/tftp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- tftp.c 17 Mar 2003 15:15:29 -0000 1.1 +++ tftp.c 18 Mar 2003 15:05:07 -0000 1.2 @@ -19,6 +19,14 @@ #define printascii( s ) SerialOutputString( s ) #define printch( c ) SerialOutputChar( c ) +#define TFTP_DEBUG +#ifdef TFTP_DEBUG +static int dbg = 1; +# define DBG( x, args... ) if ( dbg>=x ) printf( args ) +#else +# define DBG( x, args... ) ; +#endif + static const unsigned char tftp_txpacket[] = { /*+destination */ /*+source */ @@ -47,6 +55,7 @@ static int serverport; static unsigned int tftp_length; static unsigned int block; +static unsigned long tftp_received; extern unsigned char clientipaddress[4]; extern unsigned char serveripaddress[4]; @@ -56,6 +65,8 @@ unsigned int tftp_off, tftp_sz, nblk; unsigned char *tftp; + DBG( 5, "%s: addr=%p\n", __FUNCTION__, addr ); + tftp_off = ipbits_rcv (tftp_rx, 800, &tftp_sz, serverport, 0x8000); if (!tftp_off || tftp_rx[tftp_off] != 0) return 0; @@ -66,10 +77,10 @@ printascii ("\nTFTP error: "); printascii (tftp + 4); printch ('\n'); - while (1); + return -2; break; - case 3: /* acknowledge block */ + case 3: /* OpCode: DATA, acknowledge block */ if (block == 0) { serverport = (tftp[-8] << 8) | tftp[-7]; /* copy replied-source port */ @@ -77,7 +88,7 @@ tftp_tx[OFF_UDP + 3] = serverport; tftp_tx[OFF_UDP + 5] = 12; tftp_tx[OFF_IP + 3] = 32; - tftp_tx[OFF_TFTP + 1] = 4; /* ack code */ + tftp_tx[OFF_TFTP + 1] = 4; /* OpCode: ACK */ block = 1; tftp_length = 12; } @@ -85,15 +96,19 @@ if (nblk == block) { tftp_tx[OFF_TFTP + 2] = block >> 8; tftp_tx[OFF_TFTP + 3] = block; - ipbits_tx (tftp_tx, 12); + ipbits_tx (tftp_tx, tftp_length ); memcpy((void *)*addr, tftp + 4, tftp_sz - 4); *addr += tftp_sz - 4; - if ((block & 31) == 1) + tftp_received += tftp_sz - 4; + if ((block & 31) == 1) { printch ('.'); + DBG( 5, "%s: nblk=%d, block=%d, sz=%d\n", __FUNCTION__, nblk, block, tftp_sz ); + } block ++; - } else + } else { if (nblk == block - 1) - ipbits_tx (tftp_tx, 12); + ipbits_tx (tftp_tx, tftp_length ); + } if (tftp_sz != 516) return 1; return -1; @@ -102,15 +117,21 @@ } } -void do_tftp(char *file, unsigned long addr) +int do_tftp(char *file, unsigned long addr, unsigned long *size ) { + int ret; + int finished; unsigned int i; + int retry = 8; + + DBG( 1, "%s: file='%s', addr=%08lx\n", __FUNCTION__, file, addr ); do_arp(serverhwaddress, serveripaddress); serverport = -1; tftp_length = 144; block = 0; + tftp_received = 0; memzero(tftp_tx, sizeof (tftp_tx)); memcpy(tftp_tx + 14, tftp_txpacket, sizeof (tftp_txpacket)); @@ -125,17 +146,34 @@ printascii("TFTPing "); printascii(file); + finished = 0; do { - printch('.'); + printch('*'); ipbits_tx(tftp_tx, tftp_length); - for (i = 0; i < 0x00040000; i++) - switch (tftp_rcv(&addr)) { + for (i = 0; i < 0x00040000 && !finished; i++) { + ret = tftp_rcv(&addr); + switch (ret) { case 1: - goto done; + finished = 1; + break; case -1: i = 0; + break; + case -2: + retry = 0; + break; } - } while (1); -done: - printascii(" Ok\n"); + } + } while (retry-- && !finished); + + if ( finished ) { + printf( " OK.\n" ); + printf( "received %d blocks (%ld bytes)\n", block, tftp_received ); + *size = tftp_received; + ret = 0; + } else { + printf( " ERROR\n" ); + ret = -1; + } + return ret; } |