1 /* XMODEM support for GDB, the GNU debugger.
2 Copyright 1995 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
26 /* These definitions are for xmodem protocol. */
35 static int blknum; /* XMODEM block number */
36 static int crcflag; /* Sez we are using CRC's instead of cksums */
39 readchar (desc, timeout)
45 c = SERIAL_READCHAR (desc, timeout);
48 fputc_unfiltered (c, gdb_stdlog);
53 if (c == SERIAL_TIMEOUT)
54 error ("Timeout reading from remote system.");
56 perror_with_name ("xmodem.c:readchar()");
59 #define CRC16 0x1021 /* Generator polynomial (X^16 + X^12 + X^5 + 1) */
61 static unsigned short *crctab;
63 /* Call this to init the fast CRC-16 calculation table. */
68 static int crctab_inited = 0;
71 if (crctab_inited == 1)
74 crctab = xmalloc (256 * sizeof (short));
76 for (val = 0; val <= 255; val++)
83 for (i = 0; i < 8; ++i)
97 /* Calculate a CRC-16 for the LEN byte message pointed at by P. */
104 unsigned short crc = 0;
107 crc = (crc << 8) ^ crctab[(crc >> 8) ^ *p++];
112 /* Start up the transmit process. Reset state variables. Wait for receiver to
113 send NAK or CRC request. */
116 xmodem_init_xfer (desc)
126 for (i = 1; i <= 10; i++)
128 c = readchar (desc, 6);
137 fprintf_unfiltered (gdb_stderr, "xmodem_init_xfer: Got unexpected character %c (0%o)\n", c, c);
139 case CANCEL: /* target aborted load */
140 fprintf_unfiltered (gdb_stderr, "Got a CANCEL from the target.\n");
144 error ("xmodem_init_xfer: Too many unexpected characters.");
147 /* Take 128 bytes of data and make a packet out of it.
149 * Each packet looks like this:
150 * +-----+-------+-------+------+-----+
151 * | SOH | Seq1. | Seq2. | data | SUM |
152 * +-----+-------+-------+------+-----+
154 * Seq1 = The sequence number.
155 * Seq2 = The complement of the sequence number.
156 * Data = A 128 bytes of data.
157 * SUM = Add the contents of the 128 bytes and use the low-order
158 * 8 bits of the result.
160 * send_xmodem_packet fills in the XMODEM fields of PACKET and sends it to the
161 * remote system. PACKET must be XMODEM_PACKETSIZE bytes long. The data must
162 * start 3 bytes after the beginning of the packet to leave room for the
163 * XMODEM header. LEN is the length of the data portion of the packet (and
164 * must be <= 128 bytes). If it is < 128 bytes, ^Z padding will be added.
168 xmodem_send_packet (desc, packet, len, hashmark)
170 unsigned char *packet;
179 /* build the packet header */
186 if (len <= XMODEM_DATASIZE)
189 datasize = XMODEM_DATASIZE;
191 else if (len <= XMODEM_1KDATASIZE)
194 datasize = XMODEM_1KDATASIZE;
197 abort (); /* Packet way too large */
199 /* Add ^Z padding if packet < 128 (or 1024) bytes */
201 memset (packet + 3 + len, '\026', datasize - len);
207 crc = docrc (packet + 3, datasize);
209 packet[3 + datasize] = crc >> 8;
210 packet[3 + datasize + 1] = crc;
211 pktlen = datasize + 5;
218 for (i = 3; i < datasize + 3; i++)
221 packet[3 + datasize] = sum; /* add the checksum */
222 pktlen = datasize + 4;
225 for (retries = 3; retries >= 0; retries--)
229 SERIAL_WRITE (desc, packet, pktlen);
231 c = readchar (desc, 3);
239 putchar_unfiltered ('-');
240 gdb_flush (gdb_stdout);
243 error ("xmodem_send_packet: Transfer aborted by receiver.");
245 fprintf_unfiltered (gdb_stderr, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c, c);
250 SERIAL_WRITE (desc, "\004", 1); /* Send an EOT */
252 error ("xmodem_send_packet: Excessive retries.");
255 /* Finish off the transfer. Send out the EOT, and wait for an ACK. */
258 xmodem_finish_xfer (desc)
263 for (retries = 10; retries >= 0; retries--)
267 SERIAL_WRITE (desc, "\004", 1); /* Send an EOT */
269 c = readchar (desc, 3);
277 error ("xmodem_finish_xfer: Transfer aborted by receiver.");
279 fprintf_unfiltered (gdb_stderr, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c, c);
284 error ("xmodem_finish_xfer: Excessive retries.");