-//==========================================================================
-//
-// xyzModem.c
-//
-// RedBoot stream handler for xyzModem protocol
-//
-//==========================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
-// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-// Copyright (C) 2002 Gary Thomas
-//
-// eCos is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 or (at your option) any later version.
-//
-// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with eCos; if not, write to the Free Software Foundation, Inc.,
-// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// As a special exception, if other files instantiate templates or use macros
-// or inline functions from this file, or you compile this file and link it
-// with other works to produce a work based on this file, this file does not
-// by itself cause the resulting work to be covered by the GNU General Public
-// License. However the source code for this file must still be made available
-// in accordance with section (3) of the GNU General Public License.
-//
-// This exception does not invalidate any other reasons why a work based on
-// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
-// -------------------------------------------
-//####ECOSGPLCOPYRIGHTEND####
-//==========================================================================
-//#####DESCRIPTIONBEGIN####
-//
-// Author(s): gthomas
-// Contributors: gthomas, tsmith, Yoshinori Sato
-// Date: 2000-07-14
-// Purpose:
-// Description:
-//
-// This code is part of RedBoot (tm).
-//
-//####DESCRIPTIONEND####
-//
-//==========================================================================
+/*
+ *==========================================================================
+ *
+ * xyzModem.c
+ *
+ * RedBoot stream handler for xyzModem protocol
+ *
+ *==========================================================================
+ *####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating System.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+ * Copyright (C) 2002 Gary Thomas
+ *
+ * eCos is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 or (at your option) any later version.
+ *
+ * eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with eCos; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+ *
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ *
+ * Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+ * at http: *sources.redhat.com/ecos/ecos-license/
+ * -------------------------------------------
+ *####ECOSGPLCOPYRIGHTEND####
+ *==========================================================================
+ *#####DESCRIPTIONBEGIN####
+ *
+ * Author(s): gthomas
+ * Contributors: gthomas, tsmith, Yoshinori Sato
+ * Date: 2000-07-14
+ * Purpose:
+ * Description:
+ *
+ * This code is part of RedBoot (tm).
+ *
+ *####DESCRIPTIONEND####
+ *
+ *==========================================================================
+ */
- 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;
- 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;
+ }
- if (xyz.crc_mode) {
- res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &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;
- // 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;
+ }
- 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;
- // 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);
+ }
+ }
- 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;
+ }
- // 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);
- // 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;
+ /* 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);
+ /* 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;
- 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"));
- // 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);
- }
+ 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"));
+ /*
+ * 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);
+ }
-//
-// 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);
-#endif
+/*
+ * 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);
+#endif