2 * Copyright (c) 2006 M. Warner Losh. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 * This software is derived from software provide by Kwikbyte who specifically
25 * disclaimed copyright on the code. This version of xmodem has been nearly
26 * completely rewritten, but the CRC is from the original.
33 #define PACKET_SIZE 128
35 /* Line control codes */
36 #define SOH 0x01 /* start of header */
37 #define ACK 0x06 /* Acknowledge */
38 #define NAK 0x15 /* Negative acknowledge */
39 #define CAN 0x18 /* Cancel */
40 #define EOT 0x04 /* end of text */
44 * int GetRecord(char , char *)
45 * This private function receives a x-modem record to the pointer and
46 * returns non-zero on success.
49 GetRecord(char blocknum, char *dest)
57 if ((ch = getc(TO)) == -1)
61 if ((ch = getc(TO)) == -1)
63 if (ch != (~blocknum & 0xff))
66 for (size = 0; size < PACKET_SIZE; ++size) {
67 if ((ch = getc(TO)) == -1)
70 for (j = 0; j < 8; ++j) {
72 chk = chk << 1 ^ 0x1021;
81 if (((ch = getc(TO)) == -1) || ((ch & 0xff) != ((chk >> 8) & 0xFF)))
83 if (((ch = getc(TO)) == -1) || ((ch & 0xff) != (chk & 0xFF)))
90 // We should allow for resend, but we don't.
95 * int xmodem_rx(char *)
96 * This global function receives a x-modem transmission consisting of
97 * (potentially) several blocks. Returns the number of bytes received or
101 xmodem_rx(char *dest)
104 char packetNumber, *startAddress = dest;
112 if (((ch = getc(1)) == -1) || (ch != SOH && ch != EOT))
116 return (dest - startAddress);
119 // Xmodem packets: SOH PKT# ~PKT# 128-bytes CRC16
120 if (!GetRecord(packetNumber, dest))
126 // the loop above should return in all cases