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;
}
|