summaryrefslogtreecommitdiffstats
path: root/main/common/xmodem.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/common/xmodem.c')
-rw-r--r--main/common/xmodem.c1300
1 files changed, 665 insertions, 635 deletions
diff --git a/main/common/xmodem.c b/main/common/xmodem.c
index af1ac3f..70be83c 100644
--- a/main/common/xmodem.c
+++ b/main/common/xmodem.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2013 Alcatel-Lucent
- *
+ *
* Alcatel Lucent licenses this file to You under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. A copy of the License is contained the
@@ -27,12 +27,12 @@
* information about the file being downloaded (in partiuclar, the name).
* YMODEM also supports BATCH downloads (multiple files downloaded in one
* transaction). This code supports incoming BATCH downloads (not tested
- * because I can't find any terminal emulators that do it), but not for
+ * because I can't find any terminal emulators that do it), but not for
* uploads.
* Minicom notes:
* Minicom is the terminal emulation program that comes with Linux.
- * For some reason I had to make some adjustments to the xmodem.c
+ * For some reason I had to make some adjustments to the xmodem.c
* to accommodate Minicom...
* - Minicom sends an initial 0x1a (EOF). Not sure why, so I just absorb
* that now.
@@ -51,7 +51,7 @@
* NAKs buffered up on the TTY. The end result is that if too many
* NAKs have been queued up in the TTY's buffer, Minicom chokes on
* them at startup.
- * Adding the ability to slow down the NAK send rate keeps uMon from
+ * Adding the ability to slow down the NAK send rate keeps uMon from
* sending too many NAKs prior to Minicom actually starting up its
* side of the protocol; hence, Minicom doesn't choke and the transfer
* works ok.
@@ -89,47 +89,47 @@
* support functions (Xup, Xdown, etc..) for reference and update.
*/
struct xinfo {
- uchar sno; /* Sequence number. */
- uchar pad; /* Unused, padding. */
- int xfertot; /* Running total of transfer. */
- int pktlen; /* Length of packet (128 or 1024). */
- int pktcnt; /* Running tally of number of packets processed. */
- int filcnt; /* Number of files transferred by ymodem. */
- long size; /* Size of upload. */
- ulong flags; /* Storage for various runtime flags. */
- ulong base; /* Starting address for data transfer. */
- ulong dataddr; /* Running address for data transfer. */
- int errcnt; /* Keep track of errors (used in verify mode). */
- int nakresend; /* Time between each NAK sent at Xdown startup. */
- char *firsterrat; /* Pointer to location of error detected when */
- /* transfer is in verify mode. */
- char fname[TFSNAMESIZE];
+ uchar sno; /* Sequence number. */
+ uchar pad; /* Unused, padding. */
+ int xfertot; /* Running total of transfer. */
+ int pktlen; /* Length of packet (128 or 1024). */
+ int pktcnt; /* Running tally of number of packets processed. */
+ int filcnt; /* Number of files transferred by ymodem. */
+ long size; /* Size of upload. */
+ ulong flags; /* Storage for various runtime flags. */
+ ulong base; /* Starting address for data transfer. */
+ ulong dataddr; /* Running address for data transfer. */
+ int errcnt; /* Keep track of errors (used in verify mode). */
+ int nakresend; /* Time between each NAK sent at Xdown startup. */
+ char *firsterrat; /* Pointer to location of error detected when */
+ /* transfer is in verify mode. */
+ char fname[TFSNAMESIZE];
};
/* Runtime flags: */
-#define USECRC (1<<0)
-#define VERIFY (1<<1)
-#define YMODEM (1<<2)
+#define USECRC (1<<0)
+#define VERIFY (1<<1)
+#define YMODEM (1<<2)
/* Current xmodem operation: */
-#define XNULL 0
-#define XUP 1
-#define XDOWN 2
+#define XNULL 0
+#define XUP 1
+#define XDOWN 2
/* X/Ymodem protocol: */
-#define SOH 0x01
-#define STX 0x02
-#define EOT 0x04
-#define ACK 0x06
-#define NAK 0x15
-#define CAN 0x18
-#define EOF 0x1a
-#define ESC 0x1b
+#define SOH 0x01
+#define STX 0x02
+#define EOT 0x04
+#define ACK 0x06
+#define NAK 0x15
+#define CAN 0x18
+#define EOF 0x1a
+#define ESC 0x1b
-#define PKTLEN_128 128
-#define PKTLEN_1K 1024
+#define PKTLEN_128 128
+#define PKTLEN_1K 1024
-#define BYTE_TIMEOUT 1000
+#define BYTE_TIMEOUT 1000
static int Xup(struct xinfo *);
static int Xdown(struct xinfo *);
@@ -137,244 +137,252 @@ static int getPacket(uchar *,struct xinfo *);
static int putPacket(uchar *,struct xinfo *);
char *XmodemHelp[] = {
- "Xmodem file transfer",
- "-[a:BcdF:f:i:ks:uvy]",
+ "Xmodem file transfer",
+ "-[a:BcdF:f:i:ks:uvy]",
#if INCLUDE_VERBOSEHELP
- "Options:",
- " -a{##} address (overrides default of APPRAMBASE)",
+ "Options:",
+ " -a{##} address (overrides default of APPRAMBASE)",
#if INCLUDE_FLASH
- " -B boot sector reload",
+ " -B boot sector reload",
#endif
- " -c use crc (default = checksum)",
- " -d download",
+ " -c use crc (default = checksum)",
+ " -d download",
#if INCLUDE_TFS
- " -F{name} filename",
- " -f{flags} file flags (see tfs)",
- " -i{info} file info (see tfs)",
+ " -F{name} filename",
+ " -f{flags} file flags (see tfs)",
+ " -i{info} file info (see tfs)",
#endif
- " -k force packet length to 1K",
- " -s{##} size (overrides computed size)",
- " -u upload",
- " -v verify only",
+ " -k force packet length to 1K",
+ " -s{##} size (overrides computed size)",
+ " -u upload",
+ " -v verify only",
#if INCLUDE_TFS
- " -y use Ymodem extensions",
+ " -y use Ymodem extensions",
#endif
- "Notes:",
- " * Either -d or -u must be specified (-B implies -d).",
- " * Each additional 'd' option cuts the nak-resend rate in half.",
- " * XMODEM forces a 128-byte modulo on file size. The -s option",
- " can be used to override this when transferring a file to TFS.",
- " * File upload requires no address or size (size will be mod 128).",
- " * When using -B, it should be the ONLY command line option,",
- " it's purpose is to reprogram the boot sector, so be careful!",
+ "Notes:",
+ " * Either -d or -u must be specified (-B implies -d).",
+ " * Each additional 'd' option cuts the nak-resend rate in half.",
+ " * XMODEM forces a 128-byte modulo on file size. The -s option",
+ " can be used to override this when transferring a file to TFS.",
+ " * File upload requires no address or size (size will be mod 128).",
+ " * When using -B, it should be the ONLY command line option,",
+ " it's purpose is to reprogram the boot sector, so be careful!",
#endif
- (char *)0,
+ (char *)0,
};
int
Xmodem(int argc,char *argv[])
{
- int opt, xop;
- struct xinfo xi;
+ int opt, xop;
+ struct xinfo xi;
#if INCLUDE_TFS
- char *info = (char *)0;
+ char *info = (char *)0;
char *flags = (char *)0;
- TFILE *tfp;
+ TFILE *tfp;
#endif
#if INCLUDE_FLASH
- int newboot = 0;
+ int newboot = 0;
#endif
#if INCLUDE_ETHERNET
- int eon;
+ int eon;
#endif
- xop = XNULL;
- xi.fname[0] = 0;
- xi.size = 0;
- xi.flags = 0;
- xi.filcnt = 0;
- xi.nakresend = 2;
- xi.pktlen = PKTLEN_128;
- xi.base = xi.dataddr = getAppRamStart();
- while ((opt=getopt(argc,argv,"a:BcdF:f:i:ks:uvy")) != -1) {
- switch(opt) {
- case 'a':
- xi.dataddr = xi.base = strtoul(optarg,(char **)0,0);
- break;
- case 'B':
- xop = XDOWN;
+ xop = XNULL;
+ xi.fname[0] = 0;
+ xi.size = 0;
+ xi.flags = 0;
+ xi.filcnt = 0;
+ xi.nakresend = 2;
+ xi.pktlen = PKTLEN_128;
+ xi.base = xi.dataddr = getAppRamStart();
+ while((opt=getopt(argc,argv,"a:BcdF:f:i:ks:uvy")) != -1) {
+ switch(opt) {
+ case 'a':
+ xi.dataddr = xi.base = strtoul(optarg,(char **)0,0);
+ break;
+ case 'B':
+ xop = XDOWN;
#if INCLUDE_FLASH
- newboot = 1;
+ newboot = 1;
#endif
- break;
- case 'c':
- xi.flags |= USECRC;
- break;
- case 'd':
- xi.nakresend *= 2; /* -ddd increases Xdown() resend delay */
- xop = XDOWN;
- break;
+ break;
+ case 'c':
+ xi.flags |= USECRC;
+ break;
+ case 'd':
+ xi.nakresend *= 2; /* -ddd increases Xdown() resend delay */
+ xop = XDOWN;
+ break;
#if INCLUDE_TFS
- case 'F':
- strncpy(xi.fname,optarg,TFSNAMESIZE);
- break;
- case 'f':
- flags = optarg;
- break;
- case 'i':
- info = optarg;
- break;
+ case 'F':
+ strncpy(xi.fname,optarg,TFSNAMESIZE);
+ break;
+ case 'f':
+ flags = optarg;
+ break;
+ case 'i':
+ info = optarg;
+ break;
#endif
- case 'k':
- xi.pktlen = PKTLEN_1K;
- break;
- case 's':
- xi.size = strtol(optarg,(char **)0,0);
- break;
- case 'u':
- xop = XUP;
- break;
- case 'v':
- xi.flags |= VERIFY;
- break;
+ case 'k':
+ xi.pktlen = PKTLEN_1K;
+ break;
+ case 's':
+ xi.size = strtol(optarg,(char **)0,0);
+ break;
+ case 'u':
+ xop = XUP;
+ break;
+ case 'v':
+ xi.flags |= VERIFY;
+ break;
#if INCLUDE_TFS
- case 'y':
- xi.flags |= (YMODEM | USECRC);
- xi.pktlen = PKTLEN_1K;
- break;
+ case 'y':
+ xi.flags |= (YMODEM | USECRC);
+ xi.pktlen = PKTLEN_1K;
+ break;
#endif
- default:
- return(CMD_PARAM_ERROR);
- }
- }
-
- /* There should be no arguments after the option list. */
- if (argc != optind)
- return(CMD_PARAM_ERROR);
-
- if (xop == XUP) {
- if ((xi.flags & YMODEM) && !(xi.fname[0]))
- printf("Ymodem upload needs filename\n");
- else {
- if (xi.fname[0]) { /* Causes -a and -s options to be ignored. */
+ default:
+ return(CMD_PARAM_ERROR);
+ }
+ }
+
+ /* There should be no arguments after the option list. */
+ if(argc != optind) {
+ return(CMD_PARAM_ERROR);
+ }
+
+ if(xop == XUP) {
+ if((xi.flags & YMODEM) && !(xi.fname[0])) {
+ printf("Ymodem upload needs filename\n");
+ } else {
+ if(xi.fname[0]) { /* Causes -a and -s options to be ignored. */
#if INCLUDE_TFS
- tfp = tfsstat(xi.fname);
- if (!tfp) {
- printf("%s: file not found\n",xi.fname);
- return(CMD_FAILURE);
- }
- xi.base = xi.dataddr = (ulong)TFS_BASE(tfp);
- xi.size = TFS_SIZE(tfp);
+ tfp = tfsstat(xi.fname);
+ if(!tfp) {
+ printf("%s: file not found\n",xi.fname);
+ return(CMD_FAILURE);
+ }
+ xi.base = xi.dataddr = (ulong)TFS_BASE(tfp);
+ xi.size = TFS_SIZE(tfp);
#endif
- }
-#ifdef DONT_DISABLE_ENET_IN_XMODEM /* See note at top of file */
- Xup(&xi);
+ }
+#ifdef DONT_DISABLE_ENET_IN_XMODEM /* See note at top of file */
+ Xup(&xi);
#else
#if INCLUDE_ETHERNET
- eon = DisableEthernet();
+ eon = DisableEthernet();
#endif
- Xup(&xi);
+ Xup(&xi);
#if INCLUDE_ETHERNET
- if (eon)
- EthernetStartup(0,0);
+ if(eon) {
+ EthernetStartup(0,0);
+ }
#endif
#endif
- }
- }
- else if (xop == XDOWN) {
- long tmpsize;
+ }
+ } else if(xop == XDOWN) {
+ long tmpsize;
- if ((xi.flags & YMODEM) && (xi.fname[0]))
- printf("Ymodem download gets name from protocol, '%s' ignored\n",
- xi.fname);
+ if((xi.flags & YMODEM) && (xi.fname[0]))
+ printf("Ymodem download gets name from protocol, '%s' ignored\n",
+ xi.fname);
-#ifdef DONT_DISABLE_ENET_IN_XMODEM /* See note at top of file */
- tmpsize = (long)Xdown(&xi);
+#ifdef DONT_DISABLE_ENET_IN_XMODEM /* See note at top of file */
+ tmpsize = (long)Xdown(&xi);
#else
#if INCLUDE_ETHERNET
- eon = DisableEthernet();
+ eon = DisableEthernet();
#endif
- tmpsize = (long)Xdown(&xi);
+ tmpsize = (long)Xdown(&xi);
#if INCLUDE_ETHERNET
- if (eon)
- EthernetStartup(0,0);
+ if(eon) {
+ EthernetStartup(0,0);
+ }
#endif
#endif
- if (tmpsize == -1)
- return(CMD_FAILURE);
- if ((!xi.size) || (tmpsize < 0))
- xi.size = tmpsize;
+ if(tmpsize == -1) {
+ return(CMD_FAILURE);
+ }
+ if((!xi.size) || (tmpsize < 0)) {
+ xi.size = tmpsize;
+ }
#if INCLUDE_TFS
- if ((xi.fname[0]) && (xi.size > 0)) {
- int err;
-
- printf("Writing to file '%s'...\n",xi.fname);
- err = tfsadd(xi.fname,info,flags,(uchar *)xi.base,xi.size);
- if (err != TFS_OKAY) {
- printf("%s: %s\n",xi.fname,(char *)tfsctrl(TFS_ERRMSG,err,0));
- return(CMD_FAILURE);
- }
- }
+ if((xi.fname[0]) && (xi.size > 0)) {
+ int err;
+
+ printf("Writing to file '%s'...\n",xi.fname);
+ err = tfsadd(xi.fname,info,flags,(uchar *)xi.base,xi.size);
+ if(err != TFS_OKAY) {
+ printf("%s: %s\n",xi.fname,(char *)tfsctrl(TFS_ERRMSG,err,0));
+ return(CMD_FAILURE);
+ }
+ }
#if INCLUDE_FLASH
- else
+ else
#endif
#endif
#if INCLUDE_FLASH
- if ((newboot) && (xi.size > 0)) {
- extern int FlashProtectWindow;
- int rc;
- char *bb;
- ulong bootbase;
-
- bb = getenv("BOOTROMBASE");
- if (bb)
- bootbase = strtoul(bb,0,0);
- else
- bootbase = BOOTROM_BASE;
+ if((newboot) && (xi.size > 0)) {
+ extern int FlashProtectWindow;
+ int rc;
+ char *bb;
+ ulong bootbase;
+
+ bb = getenv("BOOTROMBASE");
+ if(bb) {
+ bootbase = strtoul(bb,0,0);
+ } else {
+ bootbase = BOOTROM_BASE;
+ }
#ifdef TO_FLASH_ADDR
- /* The address the program is linked to is not necessarily the
- * physical address where flash operations can be performed on.
- * A typical use could be that the program is linked to run in
- * a cacheable region but writing to the flash can only be done
- * in an uncached region.
- * "config.h" is a good place to define the TO_FLASH_ADDR macro.
- */
- bootbase = (ulong)TO_FLASH_ADDR(bootbase);
+ /* The address the program is linked to is not necessarily the
+ * physical address where flash operations can be performed on.
+ * A typical use could be that the program is linked to run in
+ * a cacheable region but writing to the flash can only be done
+ * in an uncached region.
+ * "config.h" is a good place to define the TO_FLASH_ADDR macro.
+ */
+ bootbase = (ulong)TO_FLASH_ADDR(bootbase);
#endif
- printf("Reprogramming boot @ 0x%lx from 0x%lx, %ld bytes.\n",
- bootbase,xi.base,xi.size);
- if (askuser("OK?")) {
- int first, last;
-
- /* If sector(s) need to be unlocked, do that now...
- */
- if (addrtosector((uchar *)bootbase,&first,0,0) == -1)
- return(CMD_FAILURE);
-
- if (addrtosector((uchar *)bootbase+xi.size-1,&last,0,0) == -1)
- return(CMD_FAILURE);
-
- if (flashlock(first,FLASH_LOCKABLE) != -1) {
- FlashProtectWindow = 1;
- while(first < last)
- flashlock(first++,FLASH_UNLOCK);
- }
-
- FlashProtectWindow = 1;
- rc = flashewrite((uchar *)bootbase,(uchar *)xi.base,xi.size);
- if (rc == -1) {
- printf("failed\n");
- return(CMD_FAILURE);
- }
- }
- }
+ printf("Reprogramming boot @ 0x%lx from 0x%lx, %ld bytes.\n",
+ bootbase,xi.base,xi.size);
+ if(askuser("OK?")) {
+ int first, last;
+
+ /* If sector(s) need to be unlocked, do that now...
+ */
+ if(addrtosector((uchar *)bootbase,&first,0,0) == -1) {
+ return(CMD_FAILURE);
+ }
+
+ if(addrtosector((uchar *)bootbase+xi.size-1,&last,0,0) == -1) {
+ return(CMD_FAILURE);
+ }
+
+ if(flashlock(first,FLASH_LOCKABLE) != -1) {
+ FlashProtectWindow = 1;
+ while(first < last) {
+ flashlock(first++,FLASH_UNLOCK);
+ }
+ }
+
+ FlashProtectWindow = 1;
+ rc = flashewrite((uchar *)bootbase,(uchar *)xi.base,xi.size);
+ if(rc == -1) {
+ printf("failed\n");
+ return(CMD_FAILURE);
+ }
+ }
+ }
#endif
- }
- else
- return(CMD_PARAM_ERROR);
- shell_sprintf("XMODEMGET","%ld",xi.size);
- return(CMD_SUCCESS);
+ } else {
+ return(CMD_PARAM_ERROR);
+ }
+ shell_sprintf("XMODEMGET","%ld",xi.size);
+ return(CMD_SUCCESS);
}
/* xgetchar():
@@ -384,16 +392,16 @@ Xmodem(int argc,char *argv[])
int
xgetchar(char *cp, int lno)
{
- struct elapsed_tmr tmr;
-
- startElapsedTimer(&tmr,5000);
- while(!msecElapsed(&tmr) && !gotachar());
- if (!gotachar()) {
- Mtrace("Xgetchar tmt %d",lno);
- return(-1);
- }
- *cp = getchar();
- return(0);
+ struct elapsed_tmr tmr;
+
+ startElapsedTimer(&tmr,5000);
+ while(!msecElapsed(&tmr) && !gotachar());
+ if(!gotachar()) {
+ Mtrace("Xgetchar tmt %d",lno);
+ return(-1);
+ }
+ *cp = getchar();
+ return(0);
}
/* putPacket():
@@ -402,49 +410,51 @@ xgetchar(char *cp, int lno)
static int
putPacket(uchar *tmppkt, struct xinfo *xip)
{
- char c;
- int i;
- ushort chksm;
-
- chksm = 0;
-
- if (xip->pktlen == PKTLEN_128)
- PUTCHAR(SOH);
- else
- PUTCHAR(STX);
-
- PUTCHAR((char)(xip->sno));
- PUTCHAR((char)~(xip->sno));
-
- if (xip->flags & USECRC) {
- for(i=0;i<xip->pktlen;i++) {
- PUTCHAR((char)*tmppkt);
- chksm = (chksm<<8)^xcrc16tab[(chksm>>8)^*tmppkt++];
- }
- /* An "endian independent way to extract the CRC bytes. */
- PUTCHAR((char)(chksm >> 8));
- PUTCHAR((char)chksm);
- }
- else {
- for(i=0;i<xip->pktlen;i++) {
- PUTCHAR((char)*tmppkt);
- chksm = ((chksm+*tmppkt++)&0xff);
- }
- PUTCHAR((char)(chksm&0x00ff));
- }
-
- if (xgetchar(&c,__LINE__) == -1) /* Wait for ack */
- return(-1);
-
- /* If pktcnt == -1, then this is the first packet sent by
- * YMODEM (filename) and we must wait for one additional
- * character in the response.
- */
- if (xip->pktcnt == -1) {
- if (xgetchar(&c,__LINE__) == -1)
- return(-1);
- }
- return((int)c);
+ char c;
+ int i;
+ ushort chksm;
+
+ chksm = 0;
+
+ if(xip->pktlen == PKTLEN_128) {
+ PUTCHAR(SOH);
+ } else {
+ PUTCHAR(STX);
+ }
+
+ PUTCHAR((char)(xip->sno));
+ PUTCHAR((char)~(xip->sno));
+
+ if(xip->flags & USECRC) {
+ for(i=0; i<xip->pktlen; i++) {
+ PUTCHAR((char)*tmppkt);
+ chksm = (chksm<<8)^xcrc16tab[(chksm>>8)^*tmppkt++];
+ }
+ /* An "endian independent way to extract the CRC bytes. */
+ PUTCHAR((char)(chksm >> 8));
+ PUTCHAR((char)chksm);
+ } else {
+ for(i=0; i<xip->pktlen; i++) {
+ PUTCHAR((char)*tmppkt);
+ chksm = ((chksm+*tmppkt++)&0xff);
+ }
+ PUTCHAR((char)(chksm&0x00ff));
+ }
+
+ if(xgetchar(&c,__LINE__) == -1) { /* Wait for ack */
+ return(-1);
+ }
+
+ /* If pktcnt == -1, then this is the first packet sent by
+ * YMODEM (filename) and we must wait for one additional
+ * character in the response.
+ */
+ if(xip->pktcnt == -1) {
+ if(xgetchar(&c,__LINE__) == -1) {
+ return(-1);
+ }
+ }
+ return((int)c);
}
/* getPacket():
@@ -453,144 +463,149 @@ putPacket(uchar *tmppkt, struct xinfo *xip)
static int
getPacket(uchar *tmppkt, struct xinfo *xip)
{
- char *pkt;
- int i,rcvd;
- uchar seq[2];
-
- if ((rcvd = getbytes_t((char *)seq,2,BYTE_TIMEOUT)) != 2) {
- PUTCHAR(NAK);
- Mtrace("RCVD %d != 2",rcvd);
- return(0);
- }
-
- if (xip->flags & VERIFY) {
- rcvd = getbytes_t((char *)tmppkt,xip->pktlen,BYTE_TIMEOUT);
- if (rcvd != xip->pktlen) {
- PUTCHAR(NAK);
- Mtrace("RCVD %d != %d",rcvd,xip->pktlen);
- return(0);
- }
- for(i=0;i<xip->pktlen;i++) {
- if (tmppkt[i] != ((char *)xip->dataddr)[i]) {
- if (xip->errcnt++ == 0)
- xip->firsterrat = (char *)(xip->dataddr+i);
- }
- }
- pkt = (char *)tmppkt;
- }
- else {
- rcvd = getbytes_t((char *)xip->dataddr,xip->pktlen,BYTE_TIMEOUT);
- if (rcvd != xip->pktlen) {
- PUTCHAR(NAK);
- Mtrace("RCVD %d != %d",rcvd,xip->pktlen);
- return(0);
- }
- pkt = (char *)xip->dataddr;
- }
-
- if (xip->flags & USECRC) {
- char c;
- ushort crc, xcrc;
-
- /* An "endian independent way to combine the CRC bytes. */
- if (xgetchar(&c,__LINE__) == -1)
- return(0);
- crc = (ushort)c;
- crc <<= 8;
- if (xgetchar(&c,__LINE__) == -1)
- return(0);
- crc += (ushort)c;
- xcrc = xcrc16((uchar *)pkt,(ulong)(xip->pktlen));
- if (crc != xcrc) {
- PUTCHAR(NAK);
- Mtrace("CRC %04x != %04x",crc,xcrc);
- return(0);
- }
- }
- else {
- uchar csum, xcsum;
-
- if (xgetchar((char *)&xcsum,__LINE__) == -1)
- return(0);
- csum = 0;
- for(i=0;i<xip->pktlen;i++)
- csum += *pkt++;
- if (csum != xcsum) {
- PUTCHAR(NAK);
- Mtrace("CSUM %02x != %02x (%d)",csum,xcsum,xip->pktlen);
- return(0);
- }
- Mtrace("CSUM %02x (%d)",csum,xip->pktlen);
- }
-
- /* Test the sequence number compliment...
- */
- if ((uchar)seq[0] != (uchar)~seq[1]) {
- PUTCHAR(NAK);
- Mtrace("SNOCMP %02x != %02x",(uchar)seq[0],(uchar)~(seq[1]));
- return(0);
- }
-
- /* Verify that the incoming sequence number is the expected value...
- */
- if ((uchar)seq[0] != xip->sno) {
- /* If the incoming sequence number is one less than the expected
- * sequence number, then we assume that the sender did not recieve
- * our previous ACK, and they are resending the previously received
- * packet. In that case, we send ACK and don't process the
- * incoming packet...
- */
- if ((uchar)seq[0] == xip->sno-1) {
- Mtrace("R_ACK");
- PUTCHAR(ACK);
- return(0);
- }
-
- /* Otherwise, something's messed up...
- */
- PUTCHAR(CAN);
- Mtrace("SNO: %02x != %02x",seq[0],xip->sno);
- return(-1);
- }
-
- /* First packet of YMODEM contains information about the transfer:
- * FILENAME SP FILESIZE SP MOD_DATE SP FILEMODE SP FILE_SNO
- * Only the FILENAME is required and if others are present, then none
- * can be skipped.
- */
- if ((xip->flags & YMODEM) && (xip->pktcnt == 0)) {
- char *slash, *space, *fname;
-
- slash = strrchr((char *)(xip->dataddr),'/');
- space = strchr((char *)(xip->dataddr),' ');
- if (slash)
- fname = slash+1;
- else
- fname = (char *)(xip->dataddr);
- Mtrace("<fname=%s>",fname);
- if (space) {
- *space = 0;
- xip->size = atoi(space+1);
- }
- strcpy(xip->fname,fname);
- if (fname[0])
- xip->filcnt++;
- }
- else
- xip->dataddr += xip->pktlen;
- xip->sno++;
- xip->pktcnt++;
- xip->xfertot += xip->pktlen;
- Mtrace("ACK");
- PUTCHAR(ACK);
- if (xip->flags & YMODEM) {
- if (xip->fname[0] == 0) {
- printf("\nRcvd %d file%c\n",
- xip->filcnt,xip->filcnt > 1 ? 's' : ' ');
- return(1);
- }
- }
- return(0);
+ char *pkt;
+ int i,rcvd;
+ uchar seq[2];
+
+ if((rcvd = getbytes_t((char *)seq,2,BYTE_TIMEOUT)) != 2) {
+ PUTCHAR(NAK);
+ Mtrace("RCVD %d != 2",rcvd);
+ return(0);
+ }
+
+ if(xip->flags & VERIFY) {
+ rcvd = getbytes_t((char *)tmppkt,xip->pktlen,BYTE_TIMEOUT);
+ if(rcvd != xip->pktlen) {
+ PUTCHAR(NAK);
+ Mtrace("RCVD %d != %d",rcvd,xip->pktlen);
+ return(0);
+ }
+ for(i=0; i<xip->pktlen; i++) {
+ if(tmppkt[i] != ((char *)xip->dataddr)[i]) {
+ if(xip->errcnt++ == 0) {
+ xip->firsterrat = (char *)(xip->dataddr+i);
+ }
+ }
+ }
+ pkt = (char *)tmppkt;
+ } else {
+ rcvd = getbytes_t((char *)xip->dataddr,xip->pktlen,BYTE_TIMEOUT);
+ if(rcvd != xip->pktlen) {
+ PUTCHAR(NAK);
+ Mtrace("RCVD %d != %d",rcvd,xip->pktlen);
+ return(0);
+ }
+ pkt = (char *)xip->dataddr;
+ }
+
+ if(xip->flags & USECRC) {
+ char c;
+ ushort crc, xcrc;
+
+ /* An "endian independent way to combine the CRC bytes. */
+ if(xgetchar(&c,__LINE__) == -1) {
+ return(0);
+ }
+ crc = (ushort)c;
+ crc <<= 8;
+ if(xgetchar(&c,__LINE__) == -1) {
+ return(0);
+ }
+ crc += (ushort)c;
+ xcrc = xcrc16((uchar *)pkt,(ulong)(xip->pktlen));
+ if(crc != xcrc) {
+ PUTCHAR(NAK);
+ Mtrace("CRC %04x != %04x",crc,xcrc);
+ return(0);
+ }
+ } else {
+ uchar csum, xcsum;
+
+ if(xgetchar((char *)&xcsum,__LINE__) == -1) {
+ return(0);
+ }
+ csum = 0;
+ for(i=0; i<xip->pktlen; i++) {
+ csum += *pkt++;
+ }
+ if(csum != xcsum) {
+ PUTCHAR(NAK);
+ Mtrace("CSUM %02x != %02x (%d)",csum,xcsum,xip->pktlen);
+ return(0);
+ }
+ Mtrace("CSUM %02x (%d)",csum,xip->pktlen);
+ }
+
+ /* Test the sequence number compliment...
+ */
+ if((uchar)seq[0] != (uchar)~seq[1]) {
+ PUTCHAR(NAK);
+ Mtrace("SNOCMP %02x != %02x",(uchar)seq[0],(uchar)~(seq[1]));
+ return(0);
+ }
+
+ /* Verify that the incoming sequence number is the expected value...
+ */
+ if((uchar)seq[0] != xip->sno) {
+ /* If the incoming sequence number is one less than the expected
+ * sequence number, then we assume that the sender did not recieve
+ * our previous ACK, and they are resending the previously received
+ * packet. In that case, we send ACK and don't process the
+ * incoming packet...
+ */
+ if((uchar)seq[0] == xip->sno-1) {
+ Mtrace("R_ACK");
+ PUTCHAR(ACK);
+ return(0);
+ }
+
+ /* Otherwise, something's messed up...
+ */
+ PUTCHAR(CAN);
+ Mtrace("SNO: %02x != %02x",seq[0],xip->sno);
+ return(-1);
+ }
+
+ /* First packet of YMODEM contains information about the transfer:
+ * FILENAME SP FILESIZE SP MOD_DATE SP FILEMODE SP FILE_SNO
+ * Only the FILENAME is required and if others are present, then none
+ * can be skipped.
+ */
+ if((xip->flags & YMODEM) && (xip->pktcnt == 0)) {
+ char *slash, *space, *fname;
+
+ slash = strrchr((char *)(xip->dataddr),'/');
+ space = strchr((char *)(xip->dataddr),' ');
+ if(slash) {
+ fname = slash+1;
+ } else {
+ fname = (char *)(xip->dataddr);
+ }
+ Mtrace("<fname=%s>",fname);
+ if(space) {
+ *space = 0;
+ xip->size = atoi(space+1);
+ }
+ strcpy(xip->fname,fname);
+ if(fname[0]) {
+ xip->filcnt++;
+ }
+ } else {
+ xip->dataddr += xip->pktlen;
+ }
+ xip->sno++;
+ xip->pktcnt++;
+ xip->xfertot += xip->pktlen;
+ Mtrace("ACK");
+ PUTCHAR(ACK);
+ if(xip->flags & YMODEM) {
+ if(xip->fname[0] == 0) {
+ printf("\nRcvd %d file%c\n",
+ xip->filcnt,xip->filcnt > 1 ? 's' : ' ');
+ return(1);
+ }
+ }
+ return(0);
}
/* Xup():
@@ -600,111 +615,116 @@ getPacket(uchar *tmppkt, struct xinfo *xip)
static int
Xup(struct xinfo *xip)
{
- uchar c, buf[PKTLEN_128];
- int tmp, done, pktlen;
-
- Mtrace("Xup starting");
-
- if (xip->size & 0x7f) {
- xip->size += 128;
- xip->size &= 0xffffff80L;
- }
-
- printf("Upload %ld bytes from 0x%lx\n",xip->size,(ulong)xip->base);
-
- /* Startup synchronization... */
- /* Wait to receive a NAK or 'C' from receiver. */
- done = 0;
- while(!done) {
- if (xgetchar((char *)&c,__LINE__) == -1)
- return(0);
- switch(c) {
- case NAK:
- done = 1;
- Mtrace("CSM");
- break;
- case 'C':
- xip->flags |= USECRC;
- done = 1;
- Mtrace("CRC");
- break;
- case 'q': /* ELS addition, not part of XMODEM spec. */
- return(0);
- default:
- break;
- }
- }
-
- rawon();
-
- if (xip->flags & YMODEM) {
- Mtrace("SNO_0");
- xip->sno = 0;
- xip->pktcnt = -1;
- memset((char *)buf,0,PKTLEN_128);
- sprintf((char *)buf,"%s",xip->fname);
- pktlen = xip->pktlen;
- xip->pktlen = PKTLEN_128;
- if (putPacket(buf,xip) == -1)
- return(0);
- xip->pktlen = pktlen;
- }
-
- done = 0;
- xip->sno = 1;
- xip->pktcnt = 0;
- while(!done) {
- if ((tmp = putPacket((uchar *)(xip->dataddr),xip)) == -1)
- return(0);
- c = (uchar)tmp;
- switch(c) {
- case ACK:
- xip->sno++;
- xip->pktcnt++;
- xip->size -= xip->pktlen;
- xip->dataddr += xip->pktlen;
- Mtrace("A");
- break;
- case NAK:
- Mtrace("N");
- break;
- case CAN:
- done = -1;
- Mtrace("C");
- break;
- case EOT:
- done = -1;
- Mtrace("E");
- break;
- default:
- done = -1;
- Mtrace("<%02x>",c);
- break;
- }
- if (xip->size <= 0) {
- char tmp;
-
- PUTCHAR(EOT);
- if (xgetchar(&tmp,__LINE__) == -1) /* Flush the ACK */
- return(0);
- break;
- }
- Mtrace("!");
- }
-
- Mtrace("Xup_almost");
- if ((done != -1) && (xip->flags & YMODEM)) {
- xip->sno = 0;
- memset((char *)buf,0,PKTLEN_128);
- pktlen = xip->pktlen;
- xip->pktlen = PKTLEN_128;
- if (putPacket(buf,xip) == -1)
- return(0);
- xip->pktlen = pktlen;
- }
- Mtrace("Xup_done.");
- rawoff();
- return(0);
+ uchar c, buf[PKTLEN_128];
+ int tmp, done, pktlen;
+
+ Mtrace("Xup starting");
+
+ if(xip->size & 0x7f) {
+ xip->size += 128;
+ xip->size &= 0xffffff80L;
+ }
+
+ printf("Upload %ld bytes from 0x%lx\n",xip->size,(ulong)xip->base);
+
+ /* Startup synchronization... */
+ /* Wait to receive a NAK or 'C' from receiver. */
+ done = 0;
+ while(!done) {
+ if(xgetchar((char *)&c,__LINE__) == -1) {
+ return(0);
+ }
+ switch(c) {
+ case NAK:
+ done = 1;
+ Mtrace("CSM");
+ break;
+ case 'C':
+ xip->flags |= USECRC;
+ done = 1;
+ Mtrace("CRC");
+ break;
+ case 'q': /* ELS addition, not part of XMODEM spec. */
+ return(0);
+ default:
+ break;
+ }
+ }
+
+ rawon();
+
+ if(xip->flags & YMODEM) {
+ Mtrace("SNO_0");
+ xip->sno = 0;
+ xip->pktcnt = -1;
+ memset((char *)buf,0,PKTLEN_128);
+ sprintf((char *)buf,"%s",xip->fname);
+ pktlen = xip->pktlen;
+ xip->pktlen = PKTLEN_128;
+ if(putPacket(buf,xip) == -1) {
+ return(0);
+ }
+ xip->pktlen = pktlen;
+ }
+
+ done = 0;
+ xip->sno = 1;
+ xip->pktcnt = 0;
+ while(!done) {
+ if((tmp = putPacket((uchar *)(xip->dataddr),xip)) == -1) {
+ return(0);
+ }
+ c = (uchar)tmp;
+ switch(c) {
+ case ACK:
+ xip->sno++;
+ xip->pktcnt++;
+ xip->size -= xip->pktlen;
+ xip->dataddr += xip->pktlen;
+ Mtrace("A");
+ break;
+ case NAK:
+ Mtrace("N");
+ break;
+ case CAN:
+ done = -1;
+ Mtrace("C");
+ break;
+ case EOT:
+ done = -1;
+ Mtrace("E");
+ break;
+ default:
+ done = -1;
+ Mtrace("<%02x>",c);
+ break;
+ }
+ if(xip->size <= 0) {
+ char tmp;
+
+ PUTCHAR(EOT);
+ if(xgetchar(&tmp,__LINE__) == -1) { /* Flush the ACK */
+ return(0);
+ }
+ break;
+ }
+ Mtrace("!");
+ }
+
+ Mtrace("Xup_almost");
+ if((done != -1) && (xip->flags & YMODEM)) {
+ xip->sno = 0;
+ memset((char *)buf,0,PKTLEN_128);
+ pktlen = xip->pktlen;
+ xip->pktlen = PKTLEN_128;
+ if(putPacket(buf,xip) == -1) {
+ return(0);
+ }
+ xip->pktlen = pktlen;
+ }
+ Mtrace("Xup_done.");
+ rawoff();
+ return(0);
}
@@ -719,135 +739,145 @@ Xup(struct xinfo *xip)
static int
Xdown(struct xinfo *xip)
{
- struct elapsed_tmr tmr;
- char c, *tmppkt;
- int i, done;
+ struct elapsed_tmr tmr;
+ char c, *tmppkt;
+ int i, done;
#if !INCLUDE_MALLOC
- static char pkt[PKTLEN_128];
+ static char pkt[PKTLEN_128];
- tmppkt = pkt;
+ tmppkt = pkt;
#else
- tmppkt = malloc(PKTLEN_1K);
- if (!tmppkt) {
- Mtrace("malloc failed");
- return(-1);
- }
+ tmppkt = malloc(PKTLEN_1K);
+ if(!tmppkt) {
+ Mtrace("malloc failed");
+ return(-1);
+ }
#endif
- rawon();
+ rawon();
nextfile:
- if (xip->flags & YMODEM)
- xip->sno = 0x00;
- else
- xip->sno = 0x01;
- xip->pktcnt = 0;
- xip->errcnt = 0;
- xip->xfertot = 0;
- xip->firsterrat = 0;
-
- /* Startup synchronization... */
- /* Continuously send NAK or 'C' until sender responds. */
+ if(xip->flags & YMODEM) {
+ xip->sno = 0x00;
+ } else {
+ xip->sno = 0x01;
+ }
+ xip->pktcnt = 0;
+ xip->errcnt = 0;
+ xip->xfertot = 0;
+ xip->firsterrat = 0;
+
+ /* Startup synchronization... */
+ /* Continuously send NAK or 'C' until sender responds. */
restart:
- Mtrace("Xdown");
- for(i=0;i<32;i++) {
- if (xip->flags & USECRC)
- PUTCHAR('C');
- else
- PUTCHAR(NAK);
-
- startElapsedTimer(&tmr,xip->nakresend * 1000);
- while(!msecElapsed(&tmr) && !gotachar());
- if (gotachar())
- break;
- }
- if (i == 32) {
- Mtrace("Giveup @ %d",__LINE__);
- return(-1);
- }
-
- done = 0;
- Mtrace("Got response");
- while(done == 0) {
- if (xgetchar(&c,__LINE__) == -1)
- return(-1);
- switch(c) {
- case SOH: /* 128-byte incoming packet */
- Mtrace("O");
- xip->pktlen = 128;
- done = getPacket((uchar *)tmppkt,xip);
- if (done < 0)
- Mtrace("GP_%d",done);
- if (!done && (xip->pktcnt == 1) && (xip->flags & YMODEM))
- goto restart;
- break;
+ Mtrace("Xdown");
+ for(i=0; i<32; i++) {
+ if(xip->flags & USECRC) {
+ PUTCHAR('C');
+ } else {
+ PUTCHAR(NAK);
+ }
+
+ startElapsedTimer(&tmr,xip->nakresend * 1000);
+ while(!msecElapsed(&tmr) && !gotachar());
+ if(gotachar()) {
+ break;
+ }
+ }
+ if(i == 32) {
+ Mtrace("Giveup @ %d",__LINE__);
+ return(-1);
+ }
+
+ done = 0;
+ Mtrace("Got response");
+ while(done == 0) {
+ if(xgetchar(&c,__LINE__) == -1) {
+ return(-1);
+ }
+ switch(c) {
+ case SOH: /* 128-byte incoming packet */
+ Mtrace("O");
+ xip->pktlen = 128;
+ done = getPacket((uchar *)tmppkt,xip);
+ if(done < 0) {
+ Mtrace("GP_%d",done);
+ }
+ if(!done && (xip->pktcnt == 1) && (xip->flags & YMODEM)) {
+ goto restart;
+ }
+ break;
#if INCLUDE_MALLOC
- case STX: /* 1024-byte incoming packet */
- Mtrace("T");
- xip->pktlen = 1024;
- done = getPacket((uchar *)tmppkt,xip);
- if (done < 0)
- Mtrace("GP_%d",done);
- if (!done && (xip->pktcnt == 1) && (xip->flags & YMODEM))
- goto restart;
- break;
+ case STX: /* 1024-byte incoming packet */
+ Mtrace("T");
+ xip->pktlen = 1024;
+ done = getPacket((uchar *)tmppkt,xip);
+ if(done < 0) {
+ Mtrace("GP_%d",done);
+ }
+ if(!done && (xip->pktcnt == 1) && (xip->flags & YMODEM)) {
+ goto restart;
+ }
+ break;
#endif
- case CAN:
- Mtrace("C");
- done = -1;
- break;
- case EOT:
- Mtrace("E");
- PUTCHAR(ACK);
- if (xip->flags & YMODEM) {
+ case CAN:
+ Mtrace("C");
+ done = -1;
+ break;
+ case EOT:
+ Mtrace("E");
+ PUTCHAR(ACK);
+ if(xip->flags & YMODEM) {
#if INCLUDE_TFS
- if (!xip->size)
- xip->size = xip->pktcnt * xip->pktlen;
- if (xip->fname[0])
- tfsadd(xip->fname,0,0,(uchar *)xip->base,xip->size);
- xip->dataddr = xip->base;
+ if(!xip->size) {
+ xip->size = xip->pktcnt * xip->pktlen;
+ }
+ if(xip->fname[0]) {
+ tfsadd(xip->fname,0,0,(uchar *)xip->base,xip->size);
+ }
+ xip->dataddr = xip->base;
#endif
- goto nextfile;
- }
- else {
- done = xip->xfertot;
- rawoff();
- printf("\nRcvd %d pkt%c (%d bytes)\n",xip->pktcnt,
- xip->pktcnt > 1 ? 's' : ' ',xip->xfertot);
-
- /* If the transfer is complete and no file add is to
- * be done, then we flush d-cache and invalidate
- * i-cache across the memory space that was just
- * copied to. This is necessary in case the
- * binary data that was just transferred is code.
- */
- flushDcache((char *)xip->base,xip->xfertot);
- invalidateIcache((char *)xip->base,xip->xfertot);
- }
- break;
- case ESC: /* User-invoked abort */
- Mtrace("X");
- done = -1;
- break;
- case EOF: /* 0x1a sent by MiniCom, just ignore it. */
- break;
- default:
- Mtrace("<%02x>",c);
- done = -1;
- break;
- }
- Mtrace("!");
- }
- rawoff();
- if (xip->flags & VERIFY) {
- if (xip->errcnt)
- printf("%d errors, first at 0x%lx\n",
- xip->errcnt,(ulong)(xip->firsterrat));
- else
- printf("verification passed\n");
- }
- free(tmppkt);
- return(done);
+ goto nextfile;
+ } else {
+ done = xip->xfertot;
+ rawoff();
+ printf("\nRcvd %d pkt%c (%d bytes)\n",xip->pktcnt,
+ xip->pktcnt > 1 ? 's' : ' ',xip->xfertot);
+
+ /* If the transfer is complete and no file add is to
+ * be done, then we flush d-cache and invalidate
+ * i-cache across the memory space that was just
+ * copied to. This is necessary in case the
+ * binary data that was just transferred is code.
+ */
+ flushDcache((char *)xip->base,xip->xfertot);
+ invalidateIcache((char *)xip->base,xip->xfertot);
+ }
+ break;
+ case ESC: /* User-invoked abort */
+ Mtrace("X");
+ done = -1;
+ break;
+ case EOF: /* 0x1a sent by MiniCom, just ignore it. */
+ break;
+ default:
+ Mtrace("<%02x>",c);
+ done = -1;
+ break;
+ }
+ Mtrace("!");
+ }
+ rawoff();
+ if(xip->flags & VERIFY) {
+ if(xip->errcnt)
+ printf("%d errors, first at 0x%lx\n",
+ xip->errcnt,(ulong)(xip->firsterrat));
+ else {
+ printf("verification passed\n");
+ }
+ }
+ free(tmppkt);
+ return(done);
}