1 /* XMODEM support for GDB, the GNU debugger.
2 Copyright 1995, 2000, 2001 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 (struct serial
*desc
, int timeout
)
43 c
= serial_readchar (desc
, timeout
);
46 fputc_unfiltered (c
, gdb_stdlog
);
51 if (c
== SERIAL_TIMEOUT
)
52 error ("Timeout reading from remote system.");
54 perror_with_name ("xmodem.c:readchar()");
57 #define CRC16 0x1021 /* Generator polynomial (X^16 + X^12 + X^5 + 1) */
59 static unsigned short *crctab
;
61 /* Call this to init the fast CRC-16 calculation table. */
66 static int crctab_inited
= 0;
69 if (crctab_inited
== 1)
72 crctab
= xmalloc (256 * sizeof (short));
74 for (val
= 0; val
<= 255; val
++)
81 for (i
= 0; i
< 8; ++i
)
95 /* Calculate a CRC-16 for the LEN byte message pointed at by P. */
98 docrc (unsigned char *p
, int len
)
100 unsigned short crc
= 0;
103 crc
= (crc
<< 8) ^ crctab
[(crc
>> 8) ^ *p
++];
108 /* Start up the transmit process. Reset state variables. Wait for receiver to
109 send NAK or CRC request. */
112 xmodem_init_xfer (struct serial
*desc
)
121 for (i
= 1; i
<= 10; i
++)
123 c
= readchar (desc
, 6);
132 fprintf_unfiltered (gdb_stderr
, "xmodem_init_xfer: Got unexpected character %c (0%o)\n", c
, c
);
134 case CANCEL
: /* target aborted load */
135 fprintf_unfiltered (gdb_stderr
, "Got a CANCEL from the target.\n");
139 error ("xmodem_init_xfer: Too many unexpected characters.");
142 /* Take 128 bytes of data and make a packet out of it.
144 * Each packet looks like this:
145 * +-----+-------+-------+------+-----+
146 * | SOH | Seq1. | Seq2. | data | SUM |
147 * +-----+-------+-------+------+-----+
149 * Seq1 = The sequence number.
150 * Seq2 = The complement of the sequence number.
151 * Data = A 128 bytes of data.
152 * SUM = Add the contents of the 128 bytes and use the low-order
153 * 8 bits of the result.
155 * send_xmodem_packet fills in the XMODEM fields of PACKET and sends it to the
156 * remote system. PACKET must be XMODEM_PACKETSIZE bytes long. The data must
157 * start 3 bytes after the beginning of the packet to leave room for the
158 * XMODEM header. LEN is the length of the data portion of the packet (and
159 * must be <= 128 bytes). If it is < 128 bytes, ^Z padding will be added.
163 xmodem_send_packet (struct serial
*desc
, unsigned char *packet
, int len
, int hashmark
)
170 /* build the packet header */
177 if (len
<= XMODEM_DATASIZE
)
180 datasize
= XMODEM_DATASIZE
;
182 else if (len
<= XMODEM_1KDATASIZE
)
185 datasize
= XMODEM_1KDATASIZE
;
188 internal_error (__FILE__
, __LINE__
, "failed internal consistency check"); /* Packet way too large */
190 /* Add ^Z padding if packet < 128 (or 1024) bytes */
192 memset (packet
+ 3 + len
, '\026', datasize
- len
);
198 crc
= docrc (packet
+ 3, datasize
);
200 packet
[3 + datasize
] = crc
>> 8;
201 packet
[3 + datasize
+ 1] = crc
;
202 pktlen
= datasize
+ 5;
209 for (i
= 3; i
< datasize
+ 3; i
++)
212 packet
[3 + datasize
] = sum
; /* add the checksum */
213 pktlen
= datasize
+ 4;
216 for (retries
= 3; retries
>= 0; retries
--)
220 serial_write (desc
, packet
, pktlen
);
222 c
= readchar (desc
, 3);
230 putchar_unfiltered ('-');
231 gdb_flush (gdb_stdout
);
234 error ("xmodem_send_packet: Transfer aborted by receiver.");
236 fprintf_unfiltered (gdb_stderr
, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c
, c
);
241 serial_write (desc
, "\004", 1); /* Send an EOT */
243 error ("xmodem_send_packet: Excessive retries.");
246 /* Finish off the transfer. Send out the EOT, and wait for an ACK. */
249 xmodem_finish_xfer (struct serial
*desc
)
253 for (retries
= 10; retries
>= 0; retries
--)
257 serial_write (desc
, "\004", 1); /* Send an EOT */
259 c
= readchar (desc
, 3);
267 error ("xmodem_finish_xfer: Transfer aborted by receiver.");
269 fprintf_unfiltered (gdb_stderr
, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c
, c
);
274 error ("xmodem_finish_xfer: Excessive retries.");
This page took 0.035647 seconds and 4 git commands to generate.