diff options
Diffstat (limited to 'common/xyzModem.c')
-rw-r--r-- | common/xyzModem.c | 993 |
1 files changed, 548 insertions, 445 deletions
diff --git a/common/xyzModem.c b/common/xyzModem.c index d1d66e8..a209dfa 100644 --- a/common/xyzModem.c +++ b/common/xyzModem.c @@ -69,135 +69,157 @@ #define BSP 0x08 #define NAK 0x15 #define CAN 0x18 -#define EOF 0x1A /* ^Z for DOS officionados */ +#define EOF 0x1A /* ^Z for DOS officionados */ #define USE_YMODEM_LENGTH /* Data & state local to the protocol */ -static struct { +static struct +{ #ifdef REDBOOT - hal_virtual_comm_table_t* __chan; + hal_virtual_comm_table_t *__chan; #else - int *__chan; + int *__chan; #endif - unsigned char pkt[1024], *bufp; - unsigned char blk,cblk,crc1,crc2; - unsigned char next_blk; /* Expected block */ - int len, mode, total_retries; - int total_SOH, total_STX, total_CAN; - bool crc_mode, at_eof, tx_ack; + unsigned char pkt[1024], *bufp; + unsigned char blk, cblk, crc1, crc2; + unsigned char next_blk; /* Expected block */ + int len, mode, total_retries; + int total_SOH, total_STX, total_CAN; + bool crc_mode, at_eof, tx_ack; #ifdef USE_YMODEM_LENGTH - unsigned long file_length, read_length; + unsigned long file_length, read_length; #endif } xyz; -#define xyzModem_CHAR_TIMEOUT 2000 /* 2 seconds */ +#define xyzModem_CHAR_TIMEOUT 2000 /* 2 seconds */ #define xyzModem_MAX_RETRIES 20 #define xyzModem_MAX_RETRIES_WITH_CRC 10 -#define xyzModem_CAN_COUNT 3 /* Wait for 3 CAN before quitting */ +#define xyzModem_CAN_COUNT 3 /* Wait for 3 CAN before quitting */ -#ifndef REDBOOT /*SB */ +#ifndef REDBOOT /*SB */ typedef int cyg_int32; -int CYGACC_COMM_IF_GETC_TIMEOUT (char chan,char *c) { +int +CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c) +{ #define DELAY 20 - unsigned long counter=0; - while (!tstc() && (counter < xyzModem_CHAR_TIMEOUT*1000/DELAY)) { - udelay(DELAY); - counter++; - } - if (tstc()) { - *c=getc(); - return 1; - } - return 0; + unsigned long counter = 0; + while (!tstc () && (counter < xyzModem_CHAR_TIMEOUT * 1000 / DELAY)) + { + udelay (DELAY); + counter++; + } + if (tstc ()) + { + *c = getc (); + return 1; + } + return 0; } -void CYGACC_COMM_IF_PUTC(char x,char y) { - putc(y); +void +CYGACC_COMM_IF_PUTC (char x, char y) +{ + putc (y); } /* Validate a hex character */ __inline__ static bool -_is_hex(char c) +_is_hex (char c) { - return (((c >= '0') && (c <= '9')) || - ((c >= 'A') && (c <= 'F')) || - ((c >= 'a') && (c <= 'f'))); + return (((c >= '0') && (c <= '9')) || + ((c >= 'A') && (c <= 'F')) || ((c >= 'a') && (c <= 'f'))); } /* Convert a single hex nibble */ __inline__ static int -_from_hex(char c) +_from_hex (char c) { - int ret = 0; - - if ((c >= '0') && (c <= '9')) { - ret = (c - '0'); - } else if ((c >= 'a') && (c <= 'f')) { - ret = (c - 'a' + 0x0a); - } else if ((c >= 'A') && (c <= 'F')) { - ret = (c - 'A' + 0x0A); + int ret = 0; + + if ((c >= '0') && (c <= '9')) + { + ret = (c - '0'); + } + else if ((c >= 'a') && (c <= 'f')) + { + ret = (c - 'a' + 0x0a); } - return ret; + else if ((c >= 'A') && (c <= 'F')) + { + ret = (c - 'A' + 0x0A); + } + return ret; } /* Convert a character to lower case */ __inline__ static char -_tolower(char c) +_tolower (char c) { - if ((c >= 'A') && (c <= 'Z')) { - c = (c - 'A') + 'a'; + if ((c >= 'A') && (c <= 'Z')) + { + c = (c - 'A') + 'a'; } - return c; + return c; } /* Parse (scan) a number */ bool -parse_num(char *s, unsigned long *val, char **es, char *delim) +parse_num (char *s, unsigned long *val, char **es, char *delim) { - bool first = true; - int radix = 10; - char c; - unsigned long result = 0; - int digit; - - while (*s == ' ') s++; - while (*s) { - if (first && (s[0] == '0') && (_tolower(s[1]) == 'x')) { - radix = 16; - s += 2; - } - first = false; - c = *s++; - if (_is_hex(c) && ((digit = _from_hex(c)) < radix)) { - /* Valid digit */ + bool first = true; + int radix = 10; + char c; + unsigned long result = 0; + int digit; + + while (*s == ' ') + s++; + while (*s) + { + if (first && (s[0] == '0') && (_tolower (s[1]) == 'x')) + { + radix = 16; + s += 2; + } + first = false; + c = *s++; + if (_is_hex (c) && ((digit = _from_hex (c)) < radix)) + { + /* Valid digit */ #ifdef CYGPKG_HAL_MIPS - /* FIXME: tx49 compiler generates 0x2539018 for MUL which */ - /* isn't any good. */ - if (16 == radix) - result = result << 4; - else - result = 10 * result; - result += digit; + /* FIXME: tx49 compiler generates 0x2539018 for MUL which */ + /* isn't any good. */ + if (16 == radix) + result = result << 4; + else + result = 10 * result; + result += digit; #else - result = (result * radix) + digit; + result = (result * radix) + digit; #endif - } else { - if (delim != (char *)0) { - /* See if this character is one of the delimiters */ - char *dp = delim; - while (*dp && (c != *dp)) dp++; - if (*dp) break; /* Found a good delimiter */ - } - return false; /* Malformatted number */ - } + } + else + { + if (delim != (char *) 0) + { + /* See if this character is one of the delimiters */ + char *dp = delim; + while (*dp && (c != *dp)) + dp++; + if (*dp) + break; /* Found a good delimiter */ + } + return false; /* Malformatted number */ + } } - *val = result; - if (es != (char **)0) { - *es = s; + *val = result; + if (es != (char **) 0) + { + *es = s; } - return true; + return true; } #endif @@ -211,24 +233,26 @@ parse_num(char *s, unsigned long *val, char **es, char *delim) * messages. */ static int -zm_dprintf(char *fmt, ...) +zm_dprintf (char *fmt, ...) { - int cur_console; - va_list args; + int cur_console; + va_list args; - va_start(args, fmt); + va_start (args, fmt); #ifdef REDBOOT - cur_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - CYGACC_CALL_IF_SET_CONSOLE_COMM(1); + cur_console = + CYGACC_CALL_IF_SET_CONSOLE_COMM + (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + CYGACC_CALL_IF_SET_CONSOLE_COMM (1); #endif - diag_vprintf(fmt, args); + diag_vprintf (fmt, args); #ifdef REDBOOT - CYGACC_CALL_IF_SET_CONSOLE_COMM(cur_console); + CYGACC_CALL_IF_SET_CONSOLE_COMM (cur_console); #endif } static void -zm_flush(void) +zm_flush (void) { } @@ -238,42 +262,43 @@ zm_flush(void) */ #define FINAL #ifdef FINAL -static char *zm_out = (char *)0x00380000; -static char *zm_out_start = (char *)0x00380000; +static char *zm_out = (char *) 0x00380000; +static char *zm_out_start = (char *) 0x00380000; #else static char zm_buf[8192]; -static char *zm_out=zm_buf; +static char *zm_out = zm_buf; static char *zm_out_start = zm_buf; #endif static int -zm_dprintf(char *fmt, ...) +zm_dprintf (char *fmt, ...) { - int len; - va_list args; + int len; + va_list args; - va_start(args, fmt); - len = diag_vsprintf(zm_out, fmt, args); - zm_out += len; - return len; + va_start (args, fmt); + len = diag_vsprintf (zm_out, fmt, args); + zm_out += len; + return len; } static void -zm_flush(void) +zm_flush (void) { #ifdef REDBOOT - char *p = zm_out_start; - while (*p) mon_write_char(*p++); + char *p = zm_out_start; + while (*p) + mon_write_char (*p++); #endif - zm_out = zm_out_start; + zm_out = zm_out_start; } #endif static void -zm_dump_buf(void *buf, int len) +zm_dump_buf (void *buf, int len) { #ifdef REDBOOT - diag_vdump_buf_with_offset(zm_dprintf, buf, len, 0); + diag_vdump_buf_with_offset (zm_dprintf, buf, len, 0); #else #endif @@ -283,22 +308,22 @@ static unsigned char zm_buf[2048]; static unsigned char *zm_bp; static void -zm_new(void) +zm_new (void) { - zm_bp = zm_buf; + zm_bp = zm_buf; } static void -zm_save(unsigned char c) +zm_save (unsigned char c) { - *zm_bp++ = c; + *zm_bp++ = c; } static void -zm_dump(int line) +zm_dump (int line) { - zm_dprintf("Packet at line: %d\n", line); - zm_dump_buf(zm_buf, zm_bp-zm_buf); + zm_dprintf ("Packet at line: %d\n", line); + zm_dump_buf (zm_buf, zm_bp - zm_buf); } #define ZM_DEBUG(x) x @@ -308,439 +333,517 @@ zm_dump(int line) /* Wait for the line to go idle */ static void -xyzModem_flush(void) +xyzModem_flush (void) { - int res; - char c; - while (true) { - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c); - if (!res) return; + int res; + char c; + while (true) + { + res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c); + if (!res) + return; } } static int -xyzModem_get_hdr(void) +xyzModem_get_hdr (void) { - char c; - int res; - bool hdr_found = false; - int i, can_total, hdr_chars; - unsigned short cksum; - - ZM_DEBUG(zm_new()); - /* Find the start of a header */ - can_total = 0; - hdr_chars = 0; - - if (xyz.tx_ack) { - CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); - xyz.tx_ack = false; + char c; + int res; + bool hdr_found = false; + int i, can_total, hdr_chars; + unsigned short cksum; + + ZM_DEBUG (zm_new ()); + /* Find the start of a header */ + can_total = 0; + hdr_chars = 0; + + if (xyz.tx_ack) + { + CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); + xyz.tx_ack = false; } - while (!hdr_found) { - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c); - ZM_DEBUG(zm_save(c)); - if (res) { - hdr_chars++; - switch (c) { - case SOH: - xyz.total_SOH++; - case STX: - if (c == STX) xyz.total_STX++; - hdr_found = true; - break; - case CAN: - xyz.total_CAN++; - ZM_DEBUG(zm_dump(__LINE__)); - if (++can_total == xyzModem_CAN_COUNT) { - return xyzModem_cancel; - } else { - /* Wait for multiple CAN to avoid early quits */ - break; - } - case EOT: - /* EOT only supported if no noise */ - if (hdr_chars == 1) { - CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); - ZM_DEBUG(zm_dprintf("ACK on EOT #%d\n", __LINE__)); - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_eof; - } - default: - /* Ignore, waiting for start of header */ - ; - } - } else { - /* Data stream timed out */ - xyzModem_flush(); /* Toss any current input */ - ZM_DEBUG(zm_dump(__LINE__)); - CYGACC_CALL_IF_DELAY_US((cyg_int32)250000); - return xyzModem_timeout; - } + while (!hdr_found) + { + res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c); + ZM_DEBUG (zm_save (c)); + if (res) + { + hdr_chars++; + switch (c) + { + case SOH: + xyz.total_SOH++; + case STX: + if (c == STX) + xyz.total_STX++; + hdr_found = true; + break; + case CAN: + xyz.total_CAN++; + ZM_DEBUG (zm_dump (__LINE__)); + if (++can_total == xyzModem_CAN_COUNT) + { + return xyzModem_cancel; + } + else + { + /* Wait for multiple CAN to avoid early quits */ + break; + } + case EOT: + /* EOT only supported if no noise */ + if (hdr_chars == 1) + { + CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); + ZM_DEBUG (zm_dprintf ("ACK on EOT #%d\n", __LINE__)); + ZM_DEBUG (zm_dump (__LINE__)); + return xyzModem_eof; + } + default: + /* Ignore, waiting for start of header */ + ; + } + } + else + { + /* Data stream timed out */ + xyzModem_flush (); /* Toss any current input */ + ZM_DEBUG (zm_dump (__LINE__)); + CYGACC_CALL_IF_DELAY_US ((cyg_int32) 250000); + return xyzModem_timeout; + } } - /* Header found, now read the data */ - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, (char *)&xyz.blk); - ZM_DEBUG(zm_save(xyz.blk)); - if (!res) { - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_timeout; + /* Header found, now read the data */ + res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.blk); + ZM_DEBUG (zm_save (xyz.blk)); + if (!res) + { + ZM_DEBUG (zm_dump (__LINE__)); + return xyzModem_timeout; } - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, (char *)&xyz.cblk); - ZM_DEBUG(zm_save(xyz.cblk)); - if (!res) { - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_timeout; + res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.cblk); + ZM_DEBUG (zm_save (xyz.cblk)); + if (!res) + { + ZM_DEBUG (zm_dump (__LINE__)); + return xyzModem_timeout; } - xyz.len = (c == SOH) ? 128 : 1024; - xyz.bufp = xyz.pkt; - for (i = 0; i < xyz.len; i++) { - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c); - ZM_DEBUG(zm_save(c)); - if (res) { - xyz.pkt[i] = c; - } else { - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_timeout; - } + xyz.len = (c == SOH) ? 128 : 1024; + xyz.bufp = xyz.pkt; + for (i = 0; i < xyz.len; i++) + { + res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c); + ZM_DEBUG (zm_save (c)); + if (res) + { + xyz.pkt[i] = c; + } + else + { + ZM_DEBUG (zm_dump (__LINE__)); + return xyzModem_timeout; + } } - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, (char *)&xyz.crc1); - ZM_DEBUG(zm_save(xyz.crc1)); - if (!res) { - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_timeout; + res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.crc1); + ZM_DEBUG (zm_save (xyz.crc1)); + if (!res) + { + ZM_DEBUG (zm_dump (__LINE__)); + return xyzModem_timeout; } - if (xyz.crc_mode) { - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, (char *)&xyz.crc2); - ZM_DEBUG(zm_save(xyz.crc2)); - if (!res) { - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_timeout; - } + if (xyz.crc_mode) + { + res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.crc2); + ZM_DEBUG (zm_save (xyz.crc2)); + if (!res) + { + ZM_DEBUG (zm_dump (__LINE__)); + return xyzModem_timeout; + } } - ZM_DEBUG(zm_dump(__LINE__)); - /* Validate the message */ - if ((xyz.blk ^ xyz.cblk) != (unsigned char)0xFF) { - ZM_DEBUG(zm_dprintf("Framing error - blk: %x/%x/%x\n", xyz.blk, xyz.cblk, (xyz.blk ^ xyz.cblk))); - ZM_DEBUG(zm_dump_buf(xyz.pkt, xyz.len)); - xyzModem_flush(); - return xyzModem_frame; + ZM_DEBUG (zm_dump (__LINE__)); + /* Validate the message */ + if ((xyz.blk ^ xyz.cblk) != (unsigned char) 0xFF) + { + ZM_DEBUG (zm_dprintf + ("Framing error - blk: %x/%x/%x\n", xyz.blk, xyz.cblk, + (xyz.blk ^ xyz.cblk))); + ZM_DEBUG (zm_dump_buf (xyz.pkt, xyz.len)); + xyzModem_flush (); + return xyzModem_frame; } - /* Verify checksum/CRC */ - if (xyz.crc_mode) { - cksum = cyg_crc16(xyz.pkt, xyz.len); - if (cksum != ((xyz.crc1 << 8) | xyz.crc2)) { - ZM_DEBUG(zm_dprintf("CRC error - recvd: %02x%02x, computed: %x\n", - xyz.crc1, xyz.crc2, cksum & 0xFFFF)); - return xyzModem_cksum; - } - } else { - cksum = 0; - for (i = 0; i < xyz.len; i++) { - cksum += xyz.pkt[i]; - } - if (xyz.crc1 != (cksum & 0xFF)) { - ZM_DEBUG(zm_dprintf("Checksum error - recvd: %x, computed: %x\n", xyz.crc1, cksum & 0xFF)); - return xyzModem_cksum; - } + /* Verify checksum/CRC */ + if (xyz.crc_mode) + { + cksum = cyg_crc16 (xyz.pkt, xyz.len); + if (cksum != ((xyz.crc1 << 8) | xyz.crc2)) + { + ZM_DEBUG (zm_dprintf ("CRC error - recvd: %02x%02x, computed: %x\n", + xyz.crc1, xyz.crc2, cksum & 0xFFFF)); + return xyzModem_cksum; + } } - /* If we get here, the message passes [structural] muster */ - return 0; + else + { + cksum = 0; + for (i = 0; i < xyz.len; i++) + { + cksum += xyz.pkt[i]; + } + if (xyz.crc1 != (cksum & 0xFF)) + { + ZM_DEBUG (zm_dprintf + ("Checksum error - recvd: %x, computed: %x\n", xyz.crc1, + cksum & 0xFF)); + return xyzModem_cksum; + } + } + /* If we get here, the message passes [structural] muster */ + return 0; } int -xyzModem_stream_open(connection_info_t *info, int *err) +xyzModem_stream_open (connection_info_t * info, int *err) { #ifdef REDBOOT - int console_chan; + int console_chan; #endif - int stat = 0; - int retries = xyzModem_MAX_RETRIES; - int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC; + int stat = 0; + int retries = xyzModem_MAX_RETRIES; + int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC; /* ZM_DEBUG(zm_out = zm_out_start); */ #ifdef xyzModem_zmodem - if (info->mode == xyzModem_zmodem) { - *err = xyzModem_noZmodem; - return -1; + if (info->mode == xyzModem_zmodem) + { + *err = xyzModem_noZmodem; + return -1; } #endif #ifdef REDBOOT - /* Set up the I/O channel. Note: this allows for using a different port in the future */ - console_chan = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - if (info->chan >= 0) { - CYGACC_CALL_IF_SET_CONSOLE_COMM(info->chan); - } else { - CYGACC_CALL_IF_SET_CONSOLE_COMM(console_chan); + /* Set up the I/O channel. Note: this allows for using a different port in the future */ + console_chan = + CYGACC_CALL_IF_SET_CONSOLE_COMM + (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + if (info->chan >= 0) + { + CYGACC_CALL_IF_SET_CONSOLE_COMM (info->chan); } - xyz.__chan = CYGACC_CALL_IF_CONSOLE_PROCS(); + else + { + CYGACC_CALL_IF_SET_CONSOLE_COMM (console_chan); + } + xyz.__chan = CYGACC_CALL_IF_CONSOLE_PROCS (); - CYGACC_CALL_IF_SET_CONSOLE_COMM(console_chan); - CYGACC_COMM_IF_CONTROL(*xyz.__chan, __COMMCTL_SET_TIMEOUT, xyzModem_CHAR_TIMEOUT); + CYGACC_CALL_IF_SET_CONSOLE_COMM (console_chan); + CYGACC_COMM_IF_CONTROL (*xyz.__chan, __COMMCTL_SET_TIMEOUT, + xyzModem_CHAR_TIMEOUT); #else /* TODO: CHECK ! */ - int dummy; - xyz.__chan=&dummy; + int dummy; + xyz.__chan = &dummy; #endif - xyz.len = 0; - xyz.crc_mode = true; - xyz.at_eof = false; - xyz.tx_ack = false; - xyz.mode = info->mode; - xyz.total_retries = 0; - xyz.total_SOH = 0; - xyz.total_STX = 0; - xyz.total_CAN = 0; + xyz.len = 0; + xyz.crc_mode = true; + xyz.at_eof = false; + xyz.tx_ack = false; + xyz.mode = info->mode; + xyz.total_retries = 0; + xyz.total_SOH = 0; + xyz.total_STX = 0; + xyz.total_CAN = 0; #ifdef USE_YMODEM_LENGTH - xyz.read_length = 0; - xyz.file_length = 0; + xyz.read_length = 0; + xyz.file_length = 0; #endif - CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); + CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); - if (xyz.mode == xyzModem_xmodem) { - /* X-modem doesn't have an information header - exit here */ - xyz.next_blk = 1; - return 0; + if (xyz.mode == xyzModem_xmodem) + { + /* X-modem doesn't have an information header - exit here */ + xyz.next_blk = 1; + return 0; } - while (retries-- > 0) { - stat = xyzModem_get_hdr(); - if (stat == 0) { - /* Y-modem file information header */ - if (xyz.blk == 0) { + while (retries-- > 0) + { + stat = xyzModem_get_hdr (); + if (stat == 0) + { + /* Y-modem file information header */ + if (xyz.blk == 0) + { #ifdef USE_YMODEM_LENGTH - /* skip filename */ - while (*xyz.bufp++); - /* get the length */ - parse_num((char *)xyz.bufp, &xyz.file_length, NULL, " "); + /* skip filename */ + while (*xyz.bufp++); + /* get the length */ + parse_num ((char *) xyz.bufp, &xyz.file_length, NULL, " "); #endif - /* The rest of the file name data block quietly discarded */ - xyz.tx_ack = true; - } - xyz.next_blk = 1; - xyz.len = 0; - return 0; - } else - if (stat == xyzModem_timeout) { - if (--crc_retries <= 0) xyz.crc_mode = false; - CYGACC_CALL_IF_DELAY_US(5*100000); /* Extra delay for startup */ - CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); - xyz.total_retries++; - ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__)); - } - if (stat == xyzModem_cancel) { - break; - } + /* The rest of the file name data block quietly discarded */ + xyz.tx_ack = true; + } + xyz.next_blk = 1; + xyz.len = 0; + return 0; + } + else if (stat == xyzModem_timeout) + { + if (--crc_retries <= 0) + xyz.crc_mode = false; + CYGACC_CALL_IF_DELAY_US (5 * 100000); /* Extra delay for startup */ + CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); + xyz.total_retries++; + ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__)); + } + if (stat == xyzModem_cancel) + { + break; + } } - *err = stat; - ZM_DEBUG(zm_flush()); - return -1; + *err = stat; + ZM_DEBUG (zm_flush ()); + return -1; } int -xyzModem_stream_read(char *buf, int size, int *err) +xyzModem_stream_read (char *buf, int size, int *err) { - int stat, total, len; - int retries; - - total = 0; - stat = xyzModem_cancel; - /* Try and get 'size' bytes into the buffer */ - while (!xyz.at_eof && (size > 0)) { - if (xyz.len == 0) { - retries = xyzModem_MAX_RETRIES; - while (retries-- > 0) { - stat = xyzModem_get_hdr(); - if (stat == 0) { - if (xyz.blk == xyz.next_blk) { - xyz.tx_ack = true; - ZM_DEBUG(zm_dprintf("ACK block %d (%d)\n", xyz.blk, __LINE__)); - xyz.next_blk = (xyz.next_blk + 1) & 0xFF; + int stat, total, len; + int retries; + + total = 0; + stat = xyzModem_cancel; + /* Try and get 'size' bytes into the buffer */ + while (!xyz.at_eof && (size > 0)) + { + if (xyz.len == 0) + { + retries = xyzModem_MAX_RETRIES; + while (retries-- > 0) + { + stat = xyzModem_get_hdr (); + if (stat == 0) + { + if (xyz.blk == xyz.next_blk) + { + xyz.tx_ack = true; + ZM_DEBUG (zm_dprintf + ("ACK block %d (%d)\n", xyz.blk, __LINE__)); + xyz.next_blk = (xyz.next_blk + 1) & 0xFF; #if defined(xyzModem_zmodem) || defined(USE_YMODEM_LENGTH) - if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0) { + if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0) + { #else - if (1) { + if (1) + { #endif - /* Data blocks can be padded with ^Z (EOF) characters */ - /* This code tries to detect and remove them */ - if ((xyz.bufp[xyz.len-1] == EOF) && - (xyz.bufp[xyz.len-2] == EOF) && - (xyz.bufp[xyz.len-3] == EOF)) { - while (xyz.len && (xyz.bufp[xyz.len-1] == EOF)) { - xyz.len--; - } - } - } + /* Data blocks can be padded with ^Z (EOF) characters */ + /* This code tries to detect and remove them */ + if ((xyz.bufp[xyz.len - 1] == EOF) && + (xyz.bufp[xyz.len - 2] == EOF) && + (xyz.bufp[xyz.len - 3] == EOF)) + { + while (xyz.len + && (xyz.bufp[xyz.len - 1] == EOF)) + { + xyz.len--; + } + } + } #ifdef USE_YMODEM_LENGTH - /* - * See if accumulated length exceeds that of the file. - * If so, reduce size (i.e., cut out pad bytes) - * Only do this for Y-modem (and Z-modem should it ever - * be supported since it can fall back to Y-modem mode). - */ - if (xyz.mode != xyzModem_xmodem && 0 != xyz.file_length) { - xyz.read_length += xyz.len; - if (xyz.read_length > xyz.file_length) { - xyz.len -= (xyz.read_length - xyz.file_length); - } - } + /* + * See if accumulated length exceeds that of the file. + * If so, reduce size (i.e., cut out pad bytes) + * Only do this for Y-modem (and Z-modem should it ever + * be supported since it can fall back to Y-modem mode). + */ + if (xyz.mode != xyzModem_xmodem && 0 != xyz.file_length) + { + xyz.read_length += xyz.len; + if (xyz.read_length > xyz.file_length) + { + xyz.len -= (xyz.read_length - xyz.file_length); + } + } #endif - break; - } else if (xyz.blk == ((xyz.next_blk - 1) & 0xFF)) { - /* Just re-ACK this so sender will get on with it */ - CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); - continue; /* Need new header */ - } else { - stat = xyzModem_sequence; - } - } - if (stat == xyzModem_cancel) { - break; - } - if (stat == xyzModem_eof) { - CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); - ZM_DEBUG(zm_dprintf("ACK (%d)\n", __LINE__)); - if (xyz.mode == xyzModem_ymodem) { - CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); - xyz.total_retries++; - ZM_DEBUG(zm_dprintf("Reading Final Header\n")); - stat = xyzModem_get_hdr(); - CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); - ZM_DEBUG(zm_dprintf("FINAL ACK (%d)\n", __LINE__)); - } - xyz.at_eof = true; - break; - } - CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); - xyz.total_retries++; - ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__)); - } - if (stat < 0) { - *err = stat; - xyz.len = -1; - return total; - } - } - /* Don't "read" data from the EOF protocol package */ - if (!xyz.at_eof) { - len = xyz.len; - if (size < len) len = size; - memcpy(buf, xyz.bufp, len); - size -= len; - buf += len; - total += len; - xyz.len -= len; - xyz.bufp += len; - } + break; + } + else if (xyz.blk == ((xyz.next_blk - 1) & 0xFF)) + { + /* Just re-ACK this so sender will get on with it */ + CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); + continue; /* Need new header */ + } + else + { + stat = xyzModem_sequence; + } + } + if (stat == xyzModem_cancel) + { + break; + } + if (stat == xyzModem_eof) + { + CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); + ZM_DEBUG (zm_dprintf ("ACK (%d)\n", __LINE__)); + if (xyz.mode == xyzModem_ymodem) + { + CYGACC_COMM_IF_PUTC (*xyz.__chan, + (xyz.crc_mode ? 'C' : NAK)); + xyz.total_retries++; + ZM_DEBUG (zm_dprintf ("Reading Final Header\n")); + stat = xyzModem_get_hdr (); + CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); + ZM_DEBUG (zm_dprintf ("FINAL ACK (%d)\n", __LINE__)); + } + xyz.at_eof = true; + break; + } + CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); + xyz.total_retries++; + ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__)); + } + if (stat < 0) + { + *err = stat; + xyz.len = -1; + return total; + } + } + /* Don't "read" data from the EOF protocol package */ + if (!xyz.at_eof) + { + len = xyz.len; + if (size < len) + len = size; + memcpy (buf, xyz.bufp, len); + size -= len; + buf += len; + total += len; + xyz.len -= len; + xyz.bufp += len; + } } - return total; + return total; } void -xyzModem_stream_close(int *err) +xyzModem_stream_close (int *err) { - diag_printf("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n", - xyz.crc_mode ? "CRC" : "Cksum", - xyz.total_SOH, xyz.total_STX, xyz.total_CAN, - xyz.total_retries); - ZM_DEBUG(zm_flush()); + diag_printf + ("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n", + xyz.crc_mode ? "CRC" : "Cksum", xyz.total_SOH, xyz.total_STX, + xyz.total_CAN, xyz.total_retries); + ZM_DEBUG (zm_flush ()); } /* Need to be able to clean out the input buffer, so have to take the */ /* getc */ -void xyzModem_stream_terminate(bool abort, int (*getc)(void)) +void +xyzModem_stream_terminate (bool abort, int (*getc) (void)) { int c; - if (abort) { - ZM_DEBUG(zm_dprintf("!!!! TRANSFER ABORT !!!!\n")); - switch (xyz.mode) { + if (abort) + { + ZM_DEBUG (zm_dprintf ("!!!! TRANSFER ABORT !!!!\n")); + switch (xyz.mode) + { case xyzModem_xmodem: case xyzModem_ymodem: /* The X/YMODEM Spec seems to suggest that multiple CAN followed by an equal */ /* number of Backspaces is a friendly way to get the other end to abort. */ - CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); - CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); - CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); - CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); - CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); - CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); - CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); - CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); + CYGACC_COMM_IF_PUTC (*xyz.__chan, CAN); + CYGACC_COMM_IF_PUTC (*xyz.__chan, CAN); + CYGACC_COMM_IF_PUTC (*xyz.__chan, CAN); + CYGACC_COMM_IF_PUTC (*xyz.__chan, CAN); + CYGACC_COMM_IF_PUTC (*xyz.__chan, BSP); + CYGACC_COMM_IF_PUTC (*xyz.__chan, BSP); + CYGACC_COMM_IF_PUTC (*xyz.__chan, BSP); + CYGACC_COMM_IF_PUTC (*xyz.__chan, BSP); /* Now consume the rest of what's waiting on the line. */ - ZM_DEBUG(zm_dprintf("Flushing serial line.\n")); - xyzModem_flush(); - xyz.at_eof = true; - break; + ZM_DEBUG (zm_dprintf ("Flushing serial line.\n")); + xyzModem_flush (); + xyz.at_eof = true; + break; #ifdef xyzModem_zmodem case xyzModem_zmodem: /* Might support it some day I suppose. */ #endif - break; - } - } else { - ZM_DEBUG(zm_dprintf("Engaging cleanup mode...\n")); + break; + } + } + else + { + ZM_DEBUG (zm_dprintf ("Engaging cleanup mode...\n")); /* * Consume any trailing crap left in the inbuffer from * previous recieved blocks. Since very few files are an exact multiple * of the transfer block size, there will almost always be some gunk here. * If we don't eat it now, RedBoot will think the user typed it. */ - ZM_DEBUG(zm_dprintf("Trailing gunk:\n")); - while ((c = (*getc)()) > -1) ; - ZM_DEBUG(zm_dprintf("\n")); + ZM_DEBUG (zm_dprintf ("Trailing gunk:\n")); + while ((c = (*getc) ()) > -1); + ZM_DEBUG (zm_dprintf ("\n")); /* * Make a small delay to give terminal programs like minicom * time to get control again after their file transfer program * exits. */ - CYGACC_CALL_IF_DELAY_US((cyg_int32)250000); - } + CYGACC_CALL_IF_DELAY_US ((cyg_int32) 250000); + } } char * -xyzModem_error(int err) +xyzModem_error (int err) { - switch (err) { + switch (err) + { case xyzModem_access: - return "Can't access file"; - break; + return "Can't access file"; + break; case xyzModem_noZmodem: - return "Sorry, zModem not available yet"; - break; + return "Sorry, zModem not available yet"; + break; case xyzModem_timeout: - return "Timed out"; - break; + return "Timed out"; + break; case xyzModem_eof: - return "End of file"; - break; + return "End of file"; + break; case xyzModem_cancel: - return "Cancelled"; - break; + return "Cancelled"; + break; case xyzModem_frame: - return "Invalid framing"; - break; + return "Invalid framing"; + break; case xyzModem_cksum: - return "CRC/checksum error"; - break; + return "CRC/checksum error"; + break; case xyzModem_sequence: - return "Block sequence error"; - break; + return "Block sequence error"; + break; default: - return "Unknown error"; - break; + return "Unknown error"; + break; } } /* * RedBoot interface */ -#if 0 /* SB */ -GETC_IO_FUNCS(xyzModem_io, xyzModem_stream_open, xyzModem_stream_close, - xyzModem_stream_terminate, xyzModem_stream_read, xyzModem_error); -RedBoot_load(xmodem, xyzModem_io, false, false, xyzModem_xmodem); -RedBoot_load(ymodem, xyzModem_io, false, false, xyzModem_ymodem); +#if 0 /* SB */ +GETC_IO_FUNCS (xyzModem_io, xyzModem_stream_open, xyzModem_stream_close, + xyzModem_stream_terminate, xyzModem_stream_read, + xyzModem_error); +RedBoot_load (xmodem, xyzModem_io, false, false, xyzModem_xmodem); +RedBoot_load (ymodem, xyzModem_io, false, false, xyzModem_ymodem); #endif |