diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/xmodem.c | 173 |
1 files changed, 0 insertions, 173 deletions
diff --git a/src/lib/xmodem.c b/src/lib/xmodem.c deleted file mode 100644 index c3bb1d89f3..0000000000 --- a/src/lib/xmodem.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - Copyright 2006 Arastra, Inc. - Copyright 2001, 2002 Georges Menie (www.menie.org) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include <string.h> -#include <delay.h> -#include <uart8250.h> - -static int _inbyte(int msec) -{ - while (!uart8250_can_rx_byte(CONFIG_TTYS0_BASE)) { - udelay(1000); - if (msec-- <= 0) - return -1; - } - return uart8250_rx_byte(CONFIG_TTYS0_BASE); -} - -static void _outbyte(unsigned char c) -{ - uart8250_tx_byte(CONFIG_TTYS0_BASE, c); -} - -static unsigned short crc16_ccitt(const unsigned char *buf, int sz) -{ - unsigned short crc = 0; - while (--sz >= 0) { - int i; - crc ^= (unsigned short) *buf++ << 8; - for (i = 0; i < 8; i++) - if (crc & 0x8000) - crc = crc << 1 ^ 0x1021; - else - crc <<= 1; - } - return crc; -} - -#define SOH 0x01 -#define STX 0x02 -#define EOT 0x04 -#define ACK 0x06 -#define NAK 0x15 -#define CAN 0x18 -#define CTRLZ 0x1A - -#define DLY_1S 1000 -#define MAXRETRANS 25 - -static int check(int crc, const unsigned char *buf, int sz) -{ - if (crc) { - unsigned short crc = crc16_ccitt(buf, sz); - unsigned short tcrc = (buf[sz]<<8)+buf[sz+1]; - if (crc == tcrc) - return 1; - } - else { - int i; - unsigned char cks = 0; - for (i = 0; i < sz; ++i) { - cks += buf[i]; - } - if (cks == buf[sz]) - return 1; - } - - return 0; -} - -static void flushinput(void) -{ - while (_inbyte(((DLY_1S)*3)>>1) >= 0) - ; -} - -int xmodemReceive(unsigned char *dest, int destsz) -{ - unsigned char xbuff[1030]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */ - unsigned char *p; - int bufsz, crc = 0; - unsigned char trychar = 'C'; - unsigned char packetno = 1; - int i, c, len = 0; - int retry, retrans = MAXRETRANS; - - for(;;) { - for( retry = 0; retry < 16; ++retry) { - if (trychar) _outbyte(trychar); - if ((c = _inbyte((DLY_1S)<<1)) >= 0) { - switch (c) { - case SOH: - bufsz = 128; - goto start_recv; - case STX: - bufsz = 1024; - goto start_recv; - case EOT: - flushinput(); - _outbyte(ACK); - return len; /* normal end */ - case CAN: - if ((c = _inbyte(DLY_1S)) == CAN) { - flushinput(); - _outbyte(ACK); - return -1; /* canceled by remote */ - } - break; - default: - break; - } - } - } - if (trychar == 'C') { trychar = NAK; continue; } - flushinput(); - _outbyte(CAN); - _outbyte(CAN); - _outbyte(CAN); - return -2; /* sync error */ - - start_recv: - if (trychar == 'C') crc = 1; - trychar = 0; - p = xbuff; - *p++ = c; - for (i = 0; i < (bufsz+(crc?1:0)+3); ++i) { - if ((c = _inbyte(DLY_1S)) < 0) goto reject; - *p++ = c; - } - - if (xbuff[1] == (unsigned char)(~xbuff[2]) && - (xbuff[1] == packetno || xbuff[1] == (unsigned char)packetno-1) && - check(crc, &xbuff[3], bufsz)) { - if (xbuff[1] == packetno) { - register int count = destsz - len; - if (count > bufsz) count = bufsz; - if (count > 0) { - memcpy (&dest[len], &xbuff[3], count); - len += count; - } - ++packetno; - retrans = MAXRETRANS+1; - } - if (--retrans <= 0) { - flushinput(); - _outbyte(CAN); - _outbyte(CAN); - _outbyte(CAN); - return -3; /* too many retry error */ - } - _outbyte(ACK); - continue; - } -reject: - flushinput(); - _outbyte(NAK); - } -} |