1 /*
2 * avrdude - A Downloader/Uploader for AVR device programmers
3 * Copyright (C) 2015-2020 David Sainty
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /* $Id: xbee.c 1477 2021-11-22 21:35:26Z joerg_wunsch $ */
20
21 /*
22 * avrdude interface for AVR devices Over-The-Air programmable via an
23 * XBee Series 2 device.
24 *
25 * The XBee programmer is STK500v1 (optiboot) encapsulated in the XBee
26 * API protocol. The bootloader supporting this protocol is available at:
27 *
28 * https://github.com/davidsainty/xbeeboot
29 */
30
31 #include "ac_cfg.h"
32
33 #include <sys/time.h> /* gettimeofday() */
34
35 #include <stdio.h> /* sscanf() */
36 #include <stdlib.h> /* malloc() */
37 #include <string.h> /* memmove() etc. */
38 #include <unistd.h> /* usleep() */
39
40 #include "avrdude.h"
41 #include "libavrdude.h"
42 #include "stk500_private.h"
43 #include "stk500.h"
44 #include "xbee.h"
45
46 /*
47 * For non-direct mode (Over-The-Air) we need to issue XBee commands
48 * to the remote XBee in order to reset the AVR CPU and initiate the
49 * XBeeBoot bootloader.
50 *
51 * XBee IO port 3 is a somewhat-arbitrarily chosen pin that can be
52 * connected directly to the AVR reset pin.
53 *
54 * Note that port 7 was not used because it is the only pin that can
55 * be used as a CTS flow control output. Port 6 is the only pin that
56 * can be used as an RTS flow control input.
57 *
58 * Some off-the-shelf Arduino shields select a different pin. For
59 * example this one uses XBee IO port 7.
60 *
61 * https://wiki.dfrobot.com/Xbee_Shield_For_Arduino__no_Xbee___SKU_DFR0015_
62 */
63 #ifndef XBEE_DEFAULT_RESET_PIN
64 #define XBEE_DEFAULT_RESET_PIN 3
65 #endif
66
67 /*
68 * After eight seconds the AVR bootloader watchdog will kick in. But
69 * to allow for the possibility of eight seconds upstream and another
70 * eight seconds downstream, allow for 16 retries (of roughly one
71 * second each).
72 */
73 #ifndef XBEE_MAX_RETRIES
74 #define XBEE_MAX_RETRIES 16
75 #endif
76
77 /*
78 * Maximum chunk size, which is the maximum encapsulated payload to be
79 * delivered to the remote CPU.
80 *
81 * There is an additional overhead of 3 bytes encapsulation, one
82 * "REQUEST" byte, one sequence number byte, and one
83 * "FIRMWARE_DELIVER" request type.
84 *
85 * The ZigBee maximum (unfragmented) payload is 84 bytes. Source
86 * routing decreases that by two bytes overhead, plus two bytes per
87 * hop. Maximum hop support is for 11 or 25 hops depending on
88 * firmware.
89 *
90 * Network layer encryption decreases the maximum payload by 18 bytes.
91 * APS end-to-end encryption decreases the maximum payload by 9 bytes.
92 * Both these layers are available in concert, as seen in the section
93 * "Network and APS layer encryption", decreasing our maximum payload
94 * by both 18 bytes and 9 bytes.
95 *
96 * Our maximum payload size should therefore ideally be 84 - 18 - 9 =
97 * 57 bytes, and therefore a chunk size of 54 bytes for zero hops.
98 *
99 * Source: XBee X2C manual: "Maximum RF payload size" section for most
100 * details; "Network layer encryption and decryption" section for the
101 * reference to 18 bytes of overhead; and "Enable APS encryption" for
102 * the reference to 9 bytes of overhead.
103 */
104 #ifndef XBEEBOOT_MAX_CHUNK
105 #define XBEEBOOT_MAX_CHUNK 54
106 #endif
107
108 /*
109 * Maximum source route intermediate hops. This is described in the
110 * documentation variously as 40 hops (routing table); OR 25 hops
111 * (firmware 4x58 or later); OR 11 hops (firmware earlier than 4x58).
112 *
113 * What isn't described is how to know if a given source route length
114 * is actually supported by the mesh for our target device.
115 */
116 #ifndef XBEE_MAX_INTERMEDIATE_HOPS
117 #define XBEE_MAX_INTERMEDIATE_HOPS 40
118 #endif
119
120 /* Protocol */
121 #define XBEEBOOT_PACKET_TYPE_ACK 0
122 #define XBEEBOOT_PACKET_TYPE_REQUEST 1
123
124 /*
125 * Read signature bytes - Direct copy of the Arduino behaviour to
126 * satisfy Optiboot.
127 */
xbee_read_sig_bytes(PROGRAMMER * pgm,AVRPART * p,AVRMEM * m)128 static int xbee_read_sig_bytes(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m)
129 {
130 unsigned char buf[32];
131
132 /* Signature byte reads are always 3 bytes. */
133
134 if (m->size < 3) {
135 avrdude_message(MSG_INFO, "%s: memsize too small for sig byte read\n",
136 progname);
137 return -1;
138 }
139
140 buf[0] = Cmnd_STK_READ_SIGN;
141 buf[1] = Sync_CRC_EOP;
142
143 serial_send(&pgm->fd, buf, 2);
144
145 if (serial_recv(&pgm->fd, buf, 5) < 0)
146 return -1;
147 if (buf[0] == Resp_STK_NOSYNC) {
148 avrdude_message(MSG_INFO, "%s: stk500_cmd(): programmer is out of sync\n",
149 progname);
150 return -1;
151 } else if (buf[0] != Resp_STK_INSYNC) {
152 avrdude_message(MSG_INFO,
153 "\n%s: xbee_read_sig_bytes(): (a) protocol error, "
154 "expect=0x%02x, resp=0x%02x\n",
155 progname, Resp_STK_INSYNC, buf[0]);
156 return -2;
157 }
158 if (buf[4] != Resp_STK_OK) {
159 avrdude_message(MSG_INFO,
160 "\n%s: xbee_read_sig_bytes(): (a) protocol error, "
161 "expect=0x%02x, resp=0x%02x\n",
162 progname, Resp_STK_OK, buf[4]);
163 return -3;
164 }
165
166 m->buf[0] = buf[1];
167 m->buf[1] = buf[2];
168 m->buf[2] = buf[3];
169
170 return 3;
171 }
172
173 struct XBeeSequenceStatistics {
174 struct timeval sendTime;
175 };
176
177 struct XBeeStaticticsSummary {
178 struct timeval minimum;
179 struct timeval maximum;
180 struct timeval sum;
181 unsigned long samples;
182 };
183
184 #define XBEE_STATS_GROUPS 4
185 #define XBEE_STATS_FRAME_LOCAL 0
186 #define XBEE_STATS_FRAME_REMOTE 1
187 #define XBEE_STATS_TRANSMIT 2
188 #define XBEE_STATS_RECEIVE 3
189
190 static const char* groupNames[] =
191 {
192 "FRAME_LOCAL",
193 "FRAME_REMOTE",
194 "TRANSMIT",
195 "RECEIVE"
196 };
197
198 struct XBeeBootSession {
199 struct serial_device *serialDevice;
200 union filedescriptor serialDescriptor;
201
202 unsigned char xbee_address[10];
203 int directMode;
204 unsigned char outSequence;
205 unsigned char inSequence;
206
207 /*
208 * XBee API frame sequence number.
209 */
210 unsigned char txSequence;
211
212 /*
213 * Set to non-zero if the transport is broken to the point it is
214 * considered unusable.
215 */
216 int transportUnusable;
217
218 int xbeeResetPin;
219
220 size_t inInIndex;
221 size_t inOutIndex;
222 unsigned char inBuffer[256];
223
224 int sourceRouteHops; /* -1 if unset */
225 int sourceRouteChanged;
226
227 /*
228 * The source route is an array of intermediate 16 bit addresses,
229 * starting with the address nearest to the target address, and
230 * finishing with the address closest to our local device.
231 */
232 unsigned char sourceRoute[2 * XBEE_MAX_INTERMEDIATE_HOPS];
233
234 struct XBeeSequenceStatistics sequenceStatistics[256 * XBEE_STATS_GROUPS];
235 struct XBeeStaticticsSummary groupSummary[XBEE_STATS_GROUPS];
236 };
237
xbeeStatsReset(struct XBeeStaticticsSummary * summary)238 static void xbeeStatsReset(struct XBeeStaticticsSummary *summary)
239 {
240 summary->minimum.tv_sec = 0;
241 summary->minimum.tv_usec = 0;
242 summary->maximum.tv_sec = 0;
243 summary->maximum.tv_usec = 0;
244 summary->sum.tv_sec = 0;
245 summary->sum.tv_usec = 0;
246 summary->samples = 0;
247 }
248
xbeeStatsAdd(struct XBeeStaticticsSummary * summary,struct timeval const * sample)249 static void xbeeStatsAdd(struct XBeeStaticticsSummary *summary,
250 struct timeval const *sample)
251 {
252 summary->sum.tv_usec += sample->tv_usec;
253 if (summary->sum.tv_usec > 1000000) {
254 summary->sum.tv_usec -= 1000000;
255 summary->sum.tv_sec++;
256 }
257 summary->sum.tv_sec += sample->tv_sec;
258
259 if (summary->samples == 0 ||
260 summary->minimum.tv_sec > sample->tv_sec ||
261 (summary->minimum.tv_sec == sample->tv_sec &&
262 summary->minimum.tv_usec > sample->tv_usec)) {
263 summary->minimum = *sample;
264 }
265
266 if (summary->maximum.tv_sec < sample->tv_sec ||
267 (summary->maximum.tv_sec == sample->tv_sec &&
268 summary->maximum.tv_usec < sample->tv_usec)) {
269 summary->maximum = *sample;
270 }
271
272 summary->samples++;
273 }
274
xbeeStatsSummarise(struct XBeeStaticticsSummary const * summary)275 static void xbeeStatsSummarise(struct XBeeStaticticsSummary const *summary)
276 {
277 avrdude_message(MSG_NOTICE, "%s: Minimum response time: %lu.%06lu\n",
278 progname, summary->minimum.tv_sec, summary->minimum.tv_usec);
279 avrdude_message(MSG_NOTICE, "%s: Maximum response time: %lu.%06lu\n",
280 progname, summary->maximum.tv_sec, summary->maximum.tv_usec);
281
282 struct timeval average;
283
284 const unsigned long samples = summary->samples;
285 average.tv_sec = summary->sum.tv_sec / samples;
286
287 unsigned long long usecs = summary->sum.tv_usec;
288 usecs += (summary->sum.tv_sec % samples) * 1000000;
289 usecs = usecs / samples;
290 average.tv_sec += usecs / 1000000;
291 average.tv_usec = usecs % 1000000;
292
293 avrdude_message(MSG_NOTICE, "%s: Average response time: %lu.%06lu\n",
294 progname, average.tv_sec, average.tv_usec);
295 }
296
XBeeBootSessionInit(struct XBeeBootSession * xbs)297 static void XBeeBootSessionInit(struct XBeeBootSession *xbs) {
298 xbs->serialDevice = &serial_serdev;
299 xbs->directMode = 1;
300 xbs->xbeeResetPin = XBEE_DEFAULT_RESET_PIN;
301 xbs->outSequence = 0;
302 xbs->inSequence = 0;
303 xbs->txSequence = 0;
304 xbs->transportUnusable = 0;
305 xbs->inInIndex = 0;
306 xbs->inOutIndex = 0;
307 xbs->sourceRouteHops = -1;
308 xbs->sourceRouteChanged = 0;
309
310 int group;
311 for (group = 0; group < 3; group++) {
312 int index;
313 for (index = 0; index < 256; index++)
314 xbs->sequenceStatistics[group * 256 + index].sendTime.tv_sec = (time_t)0;
315 xbeeStatsReset(&xbs->groupSummary[group]);
316 }
317 }
318
319 #define xbeebootsession(fdp) (struct XBeeBootSession*)((fdp)->pfd)
320
xbeedev_setresetpin(union filedescriptor * fdp,int xbeeResetPin)321 static void xbeedev_setresetpin(union filedescriptor *fdp, int xbeeResetPin)
322 {
323 struct XBeeBootSession *xbs = xbeebootsession(fdp);
324 xbs->xbeeResetPin = xbeeResetPin;
325 }
326
327 enum xbee_stat_is_retry_enum {XBEE_STATS_NOT_RETRY, XBEE_STATS_IS_RETRY};
328 typedef enum xbee_stat_is_retry_enum xbee_stat_is_retry;
329
xbeedev_stats_send(struct XBeeBootSession * xbs,char const * detail,int detailSequence,unsigned int group,unsigned char sequence,xbee_stat_is_retry retry,struct timeval const * sendTime)330 static void xbeedev_stats_send(struct XBeeBootSession *xbs,
331 char const *detail,
332 int detailSequence,
333 unsigned int group, unsigned char sequence,
334 xbee_stat_is_retry retry,
335 struct timeval const *sendTime)
336 {
337 struct XBeeSequenceStatistics *stats =
338 &xbs->sequenceStatistics[group * 256 + sequence];
339
340 if (retry == XBEE_STATS_NOT_RETRY)
341 stats->sendTime = *sendTime;
342
343 if (detailSequence >= 0) {
344 avrdude_message(MSG_NOTICE2,
345 "%s: Stats: Send Group %s Sequence %u : "
346 "Send %lu.%06lu %s Sequence %d\n",
347 progname, groupNames[group],
348 (unsigned int)sequence,
349 (unsigned long)sendTime->tv_sec,
350 (unsigned long)sendTime->tv_usec,
351 detail, detailSequence);
352 } else {
353 avrdude_message(MSG_NOTICE2,
354 "%s: Stats: Send Group %s Sequence %u : "
355 "Send %lu.%06lu %s\n",
356 progname, groupNames[group],
357 (unsigned int)sequence,
358 (unsigned long)sendTime->tv_sec,
359 (unsigned long)sendTime->tv_usec,
360 detail);
361 }
362 }
363
xbeedev_stats_receive(struct XBeeBootSession * xbs,char const * detail,unsigned int group,unsigned char sequence,struct timeval const * receiveTime)364 static void xbeedev_stats_receive(struct XBeeBootSession *xbs,
365 char const *detail,
366 unsigned int group, unsigned char sequence,
367 struct timeval const *receiveTime)
368 {
369 struct XBeeSequenceStatistics *stats =
370 &xbs->sequenceStatistics[group * 256 + sequence];
371 struct timeval delay;
372 time_t secs;
373 long usecs;
374
375 secs = receiveTime->tv_sec - stats->sendTime.tv_sec;
376 usecs = receiveTime->tv_usec - stats->sendTime.tv_usec;
377
378 if (usecs < 0) {
379 usecs += 1000000;
380 secs--;
381 }
382
383 delay.tv_sec = secs;
384 delay.tv_usec = usecs;
385
386 avrdude_message(MSG_NOTICE2,
387 "%s: Stats: Receive Group %s Sequence %u : "
388 "Send %lu.%06lu Receive %lu.%06lu Delay %lu.%06lu %s\n",
389 progname, groupNames[group],
390 (unsigned int)sequence,
391 (unsigned long)stats->sendTime.tv_sec,
392 (unsigned long)stats->sendTime.tv_usec,
393 (unsigned long)receiveTime->tv_sec,
394 (unsigned long)receiveTime->tv_usec,
395 (unsigned long)secs,
396 (unsigned long)usecs,
397 detail);
398
399 xbeeStatsAdd(&xbs->groupSummary[group], &delay);
400 }
401
sendAPIRequest(struct XBeeBootSession * xbs,unsigned char apiType,int txSequence,int apiOption,int prePayload1,int prePayload2,int packetType,int sequence,int appType,char const * detail,int detailSequence,unsigned int frameGroup,xbee_stat_is_retry retry,unsigned int dataLength,const unsigned char * data)402 static int sendAPIRequest(struct XBeeBootSession *xbs,
403 unsigned char apiType,
404 int txSequence,
405 int apiOption,
406 int prePayload1,
407 int prePayload2,
408 int packetType,
409 int sequence,
410 int appType,
411 char const *detail,
412 int detailSequence,
413 unsigned int frameGroup,
414 xbee_stat_is_retry retry,
415 unsigned int dataLength,
416 const unsigned char *data)
417 {
418 unsigned char frame[256];
419
420 unsigned char *fp = &frame[5];
421 unsigned char *dataStart = fp;
422 unsigned char checksum = 0xff;
423 unsigned char length = 0;
424 struct timeval time;
425
426 gettimeofday(&time, NULL);
427
428 avrdude_message(MSG_NOTICE2,
429 "%s: sendAPIRequest(): %lu.%06lu %d, %d, %d, %d %s\n",
430 progname, (unsigned long)time.tv_sec,
431 (unsigned long)time.tv_usec,
432 (int)packetType, (int)sequence, appType,
433 data == NULL ? -1 : (int)*data, detail);
434
435 #define fpput(x) \
436 do { \
437 const unsigned char v = (x); \
438 if (v == 0x7d || v == 0x7e || v == 0x11 || v == 0x13) { \
439 *fp++ = 0x7d; \
440 *fp++ = v ^ 0x20; \
441 } else { \
442 *fp++ = v; \
443 } \
444 checksum -= v; \
445 length++; \
446 } while (0)
447
448 fpput(apiType); /* ZigBee Receive Packet or ZigBee Transmit Request */
449
450 if (apiOption >= 0)
451 fpput(apiOption); /* Receive options (RX) */
452
453 if (txSequence >= 0) {
454 fpput(txSequence); /* Delivery sequence (TX/AT) */
455
456 /*
457 * Record the frame send time. Note that frame sequences are
458 * never retries.
459 */
460 xbeedev_stats_send(xbs, detail, detailSequence,
461 frameGroup, txSequence, 0, &time);
462 }
463
464 if (apiType != 0x08) {
465 /* Automatically inhibit addressing for local AT command requests. */
466 size_t index;
467 for (index = 0; index < 10; index++) {
468 const unsigned char val = xbs->xbee_address[index];
469 fpput(val);
470 }
471
472 /*
473 * If this is an API call with remote address, but is not a Create
474 * Source Route request, consider prefixing it with source routing
475 * instructions.
476 */
477 if (apiType != 0x21 && xbs->sourceRouteChanged) {
478 avrdude_message(MSG_NOTICE2, "%s: sendAPIRequest(): "
479 "Issuing Create Source Route request with %d hops\n",
480 progname, xbs->sourceRouteHops);
481
482 int rc = sendAPIRequest(xbs, 0x21, /* Create Source Route */
483 0, -1, 0, xbs->sourceRouteHops,
484 -1, -1, -1,
485 "Create Source Route for FRAME_REMOTE",
486 txSequence,
487 XBEE_STATS_FRAME_LOCAL, /* Local, no response */
488 0, /* Not a retry */
489 xbs->sourceRouteHops * 2,
490 xbs->sourceRoute);
491 if (rc != 0)
492 return rc;
493
494 xbs->sourceRouteChanged = 0;
495 }
496 }
497
498 if (prePayload1 >= 0)
499 fpput(prePayload1); /* Transmit broadcast radius */
500
501 if (prePayload2 >= 0)
502 fpput(prePayload2); /* Transmit options */
503
504 if (packetType >= 0)
505 fpput(packetType); /* XBEEBOOT_PACKET_TYPE_{ACK,REQUEST} */
506
507 if (sequence >= 0) {
508 fpput(sequence);
509
510 /* Record the send time */
511 if (packetType == XBEEBOOT_PACKET_TYPE_REQUEST)
512 xbeedev_stats_send(xbs, detail, sequence, XBEE_STATS_TRANSMIT,
513 sequence, retry, &time);
514 }
515
516 if (appType >= 0)
517 fpput(appType); /* FIRMWARE_DELIVER */
518
519 {
520 size_t index;
521 for (index = 0; index < dataLength; index++)
522 fpput(data[index]);
523 }
524
525 /* Length BEFORE checksum byte */
526 const unsigned char unescapedLength = length;
527
528 fpput(checksum);
529
530 /* Length AFTER checksum byte */
531 const unsigned int finalLength = fp - dataStart;
532
533 frame[0] = 0x7e;
534 fp = &frame[1];
535 fpput(0);
536 fpput(unescapedLength);
537 const unsigned int prefixLength = fp - frame;
538 unsigned char *frameStart = dataStart - prefixLength;
539 memmove(frameStart, frame, prefixLength);
540
541 return xbs->serialDevice->send(&xbs->serialDescriptor,
542 frameStart, finalLength + prefixLength);
543 }
544
sendPacket(struct XBeeBootSession * xbs,const char * detail,unsigned char packetType,unsigned char sequence,xbee_stat_is_retry retry,int appType,unsigned int dataLength,const unsigned char * data)545 static int sendPacket(struct XBeeBootSession *xbs,
546 const char *detail,
547 unsigned char packetType,
548 unsigned char sequence,
549 xbee_stat_is_retry retry,
550 int appType,
551 unsigned int dataLength,
552 const unsigned char *data)
553 {
554 unsigned char apiType;
555 int prePayload1;
556 int prePayload2;
557
558 if (xbs->directMode) {
559 /*
560 * In direct mode we are pretending to be an XBee device
561 * forwarding on data received from the transmitting XBee. We
562 * therefore format the data as a remote XBee would, encapsulated
563 * in a 0x90 packet.
564 */
565 apiType = 0x90; /* ZigBee Receive Packet */
566 prePayload1 = -1;
567 prePayload2 = -1;
568 } else {
569 /*
570 * In normal mode we are requesting a payload delivery,
571 * encapsulated in a 0x10 packet.
572 */
573 apiType = 0x10; /* ZigBee Transmit Request */
574 prePayload1 = 0;
575 prePayload2 = 0;
576 }
577
578 while ((++xbs->txSequence & 0xff) == 0);
579 return sendAPIRequest(xbs, apiType, xbs->txSequence, -1,
580 prePayload1, prePayload2, packetType,
581 sequence, appType,
582 detail, sequence,
583 XBEE_STATS_FRAME_REMOTE, retry,
584 dataLength, data);
585 }
586
587 #define XBEE_LENGTH_LEN 2
588 #define XBEE_CHECKSUM_LEN 1
589 #define XBEE_APITYPE_LEN 1
590 #define XBEE_APISEQUENCE_LEN 1
591 #define XBEE_ADDRESS_64BIT_LEN 8
592 #define XBEE_ADDRESS_16BIT_LEN 2
593 #define XBEE_RADIUS_LEN 1
594 #define XBEE_TXOPTIONS_LEN 1
595 #define XBEE_RXOPTIONS_LEN 1
596
xbeedev_record16Bit(struct XBeeBootSession * xbs,const unsigned char * rx16Bit)597 static void xbeedev_record16Bit(struct XBeeBootSession *xbs,
598 const unsigned char *rx16Bit)
599 {
600 /*
601 * We don't start out knowing what the 16-bit device address is, but
602 * we should receive it on the return packets, and re-use it from
603 * that point on.
604 */
605 unsigned char * const tx16Bit =
606 &xbs->xbee_address[XBEE_ADDRESS_64BIT_LEN];
607 if (memcmp(rx16Bit, tx16Bit, XBEE_ADDRESS_16BIT_LEN) != 0) {
608 avrdude_message(MSG_NOTICE2, "%s: xbeedev_record16Bit(): "
609 "New 16-bit address: %02x%02x\n",
610 progname,
611 (unsigned int)rx16Bit[0],
612 (unsigned int)rx16Bit[1]);
613 memcpy(tx16Bit, rx16Bit, XBEE_ADDRESS_16BIT_LEN);
614 }
615 }
616
617 /*
618 * Return 0 on success.
619 * Return -1 on generic error (normally serial timeout).
620 * Return -512 + XBee AT Response code
621 */
622 #define XBEE_AT_RETURN_CODE(x) (((x) >= -512 && (x) <= -256) ? (x) + 512 : -1)
xbeedev_poll(struct XBeeBootSession * xbs,unsigned char ** buf,size_t * buflen,int waitForAck,int waitForSequence)623 static int xbeedev_poll(struct XBeeBootSession *xbs,
624 unsigned char **buf, size_t *buflen,
625 int waitForAck,
626 int waitForSequence)
627 {
628 for (;;) {
629 unsigned char byte;
630 unsigned char frame[256];
631 unsigned int frameSize;
632
633 before_frame:
634 do {
635 const int rc = xbs->serialDevice->recv(&xbs->serialDescriptor, &byte, 1);
636 if (rc < 0)
637 return rc;
638 } while (byte != 0x7e);
639
640 start_of_frame:
641 {
642 size_t index = 0;
643 int escaped = 0;
644 frameSize = XBEE_LENGTH_LEN;
645 do {
646 const int rc = xbs->serialDevice->recv(&xbs->serialDescriptor,
647 &byte, 1);
648 if (rc < 0)
649 return rc;
650
651 if (byte == 0x7e)
652 /*
653 * No matter when we receive a frame start byte, we should
654 * abort parsing and start a fresh frame.
655 */
656 goto start_of_frame;
657
658 if (escaped) {
659 byte ^= 0x20;
660 escaped = 0;
661 } else if (byte == 0x7d) {
662 escaped = 1;
663 continue;
664 }
665
666 if (index >= sizeof(frame))
667 goto before_frame;
668
669 frame[index++] = byte;
670
671 if (index == XBEE_LENGTH_LEN) {
672 /* Length plus the two length bytes, plus the checksum byte */
673 frameSize = (frame[0] << 8 | frame[1]) +
674 XBEE_LENGTH_LEN + XBEE_CHECKSUM_LEN;
675
676 if (frameSize >= sizeof(frame))
677 /* Too long - immediately give up on this frame */
678 goto before_frame;
679 }
680 } while (index < frameSize);
681
682 /* End of frame */
683 unsigned char checksum = 1;
684 size_t cIndex;
685 for (cIndex = 2; cIndex < index; cIndex++) {
686 checksum += frame[cIndex];
687 }
688
689 if (checksum) {
690 /* Checksum didn't match */
691 avrdude_message(MSG_NOTICE2,
692 "%s: xbeedev_poll(): Bad checksum %d\n",
693 progname, (int)checksum);
694 continue;
695 }
696 }
697
698 const unsigned char frameType = frame[2];
699
700 struct timeval receiveTime;
701 gettimeofday(&receiveTime, NULL);
702
703 avrdude_message(MSG_NOTICE2,
704 "%s: xbeedev_poll(): %lu.%06lu Received frame type %x\n",
705 progname, (unsigned long)receiveTime.tv_sec,
706 (unsigned long)receiveTime.tv_usec,
707 (unsigned int)frameType);
708
709 if (frameType == 0x97 && frameSize > 16) {
710 /* Remote command response */
711 unsigned char txSequence = frame[3];
712 unsigned char resultCode = frame[16];
713
714 xbeedev_stats_receive(xbs, "Remote AT command response",
715 XBEE_STATS_FRAME_REMOTE, txSequence, &receiveTime);
716
717 avrdude_message(MSG_NOTICE,
718 "%s: xbeedev_poll(): Remote command %d result code %d\n",
719 progname, (int)txSequence, (int)resultCode);
720
721 if (waitForSequence >= 0 && waitForSequence == frame[3])
722 /* Received result for our sequence numbered request */
723 return -512 + resultCode;
724 } else if (frameType == 0x88 && frameSize > 6) {
725 /* Local command response */
726 unsigned char txSequence = frame[3];
727
728 xbeedev_stats_receive(xbs, "Local AT command response",
729 XBEE_STATS_FRAME_LOCAL, txSequence, &receiveTime);
730
731 avrdude_message(MSG_NOTICE,
732 "%s: xbeedev_poll(): Local command %c%c result code %d\n",
733 progname, frame[4], frame[5], (int)frame[6]);
734
735 if (waitForSequence >= 0 && waitForSequence == txSequence)
736 /* Received result for our sequence numbered request */
737 return 0;
738 } else if (frameType == 0x8b && frameSize > 7) {
739 /* Transmit status */
740 unsigned char txSequence = frame[3];
741
742 xbeedev_stats_receive(xbs, "Transmit status", XBEE_STATS_FRAME_REMOTE,
743 txSequence, &receiveTime);
744
745 avrdude_message(MSG_NOTICE2,
746 "%s: xbeedev_poll(): Transmit status %d result code %d\n",
747 progname, (int)frame[3], (int)frame[7]);
748 } else if (frameType == 0xa1 &&
749 frameSize >= XBEE_LENGTH_LEN + XBEE_APITYPE_LEN +
750 XBEE_ADDRESS_64BIT_LEN +
751 XBEE_ADDRESS_16BIT_LEN + 2 + XBEE_CHECKSUM_LEN) {
752 /* Route Record Indicator */
753 if (memcmp(&frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN],
754 xbs->xbee_address, XBEE_ADDRESS_64BIT_LEN) != 0) {
755 /* Not from our target device */
756 avrdude_message(MSG_NOTICE2, "%s: xbeedev_poll(): "
757 "Route Record Indicator from other XBee\n");
758 continue;
759 }
760
761 /*
762 * We don't start out knowing what the 16-bit device address is,
763 * but we should receive it on the return packets, and re-use it
764 * from that point on.
765 */
766 {
767 const unsigned char *rx16Bit =
768 &frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN +
769 XBEE_ADDRESS_64BIT_LEN];
770 xbeedev_record16Bit(xbs, rx16Bit);
771 }
772
773 const unsigned int header = XBEE_LENGTH_LEN + XBEE_APITYPE_LEN +
774 XBEE_ADDRESS_64BIT_LEN +
775 XBEE_ADDRESS_16BIT_LEN;
776
777 const unsigned char receiveOptions = frame[header];
778 const unsigned char hops = frame[header + 1];
779
780 avrdude_message(MSG_NOTICE2, "%s: xbeedev_poll(): "
781 "Route Record Indicator from target XBee: "
782 "hops=%d options=%d\n",
783 progname, (int)hops, (int)receiveOptions);
784
785 if (frameSize < header + 2 + hops * 2 + XBEE_CHECKSUM_LEN)
786 /* Bounds check: Frame is too small */
787 continue;
788
789 const unsigned int tableOffset = header + 2;
790
791 unsigned char index;
792 for (index = 0; index < hops; index++) {
793 avrdude_message(MSG_NOTICE2, "%s: xbeedev_poll(): "
794 "Route Intermediate Hop %d : %02x%02x\n",
795 progname, (int)index,
796 (int)frame[tableOffset + index * 2],
797 (int)frame[tableOffset + index * 2 + 1]);
798 }
799
800 if (hops <= XBEE_MAX_INTERMEDIATE_HOPS) {
801 if (xbs->sourceRouteHops != (int)hops ||
802 memcmp(&frame[tableOffset], xbs->sourceRoute, hops * 2) != 0) {
803 memcpy(xbs->sourceRoute, &frame[tableOffset], hops * 2);
804 xbs->sourceRouteHops = hops;
805 xbs->sourceRouteChanged = 1;
806
807 avrdude_message(MSG_NOTICE2, "%s: xbeedev_poll(): "
808 "Route has changed\n",
809 progname);
810 }
811 }
812 } else if (frameType == 0x10 || frameType == 0x90) {
813 unsigned char *dataStart;
814 unsigned int dataLength;
815
816 if (frameType == 0x10) {
817 /* Direct mode frame */
818 const unsigned int header = XBEE_LENGTH_LEN +
819 XBEE_APITYPE_LEN + XBEE_APISEQUENCE_LEN +
820 XBEE_ADDRESS_64BIT_LEN + XBEE_ADDRESS_16BIT_LEN +
821 XBEE_RADIUS_LEN + XBEE_TXOPTIONS_LEN;
822
823 if (frameSize <= header + XBEE_CHECKSUM_LEN)
824 /* Bounds check: Frame is too small */
825 continue;
826
827 dataLength = frameSize - header - XBEE_CHECKSUM_LEN;
828 dataStart = &frame[header];
829 } else {
830 /* Remote reply frame */
831 const unsigned int header = XBEE_LENGTH_LEN +
832 XBEE_APITYPE_LEN + XBEE_ADDRESS_64BIT_LEN + XBEE_ADDRESS_16BIT_LEN +
833 XBEE_RXOPTIONS_LEN;
834
835 if (frameSize <= header + XBEE_CHECKSUM_LEN)
836 /* Bounds check: Frame is too small */
837 continue;
838
839 dataLength = frameSize - header - XBEE_CHECKSUM_LEN;
840 dataStart = &frame[header];
841
842 if (memcmp(&frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN],
843 xbs->xbee_address, XBEE_ADDRESS_64BIT_LEN) != 0) {
844 /*
845 * This packet is not from our target device. Unlikely
846 * to ever happen, but if it does we have to ignore
847 * it.
848 */
849 continue;
850 }
851
852 /*
853 * We don't start out knowing what the 16-bit device address
854 * is, but we should receive it on the return packets, and
855 * re-use it from that point on.
856 */
857 {
858 const unsigned char *rx16Bit =
859 &frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN +
860 XBEE_ADDRESS_64BIT_LEN];
861 xbeedev_record16Bit(xbs, rx16Bit);
862 }
863 }
864
865 if (dataLength >= 2) {
866 const unsigned char protocolType = dataStart[0];
867 const unsigned char sequence = dataStart[1];
868
869 avrdude_message(MSG_NOTICE2, "%s: xbeedev_poll(): "
870 "%lu.%06lu Packet %d #%d\n",
871 progname, (unsigned long)receiveTime.tv_sec,
872 (unsigned long)receiveTime.tv_usec,
873 (int)protocolType, (int)sequence);
874
875 if (protocolType == XBEEBOOT_PACKET_TYPE_ACK) {
876 /* ACK */
877 xbeedev_stats_receive(xbs, "XBeeBoot ACK",
878 XBEE_STATS_TRANSMIT, sequence,
879 &receiveTime);
880
881 /*
882 * We can't update outSequence here, we already do that
883 * somewhere else.
884 */
885 if (waitForAck >= 0 && waitForAck == sequence)
886 return 0;
887 } else if (protocolType == XBEEBOOT_PACKET_TYPE_REQUEST &&
888 dataLength >= 4 && dataStart[2] == 24) {
889 /* REQUEST FRAME_REPLY */
890 xbeedev_stats_receive(xbs, "XBeeBoot Receive", XBEE_STATS_RECEIVE,
891 sequence, &receiveTime);
892
893 unsigned char nextSequence = xbs->inSequence;
894 while ((++nextSequence & 0xff) == 0);
895 if (sequence == nextSequence) {
896 xbs->inSequence = nextSequence;
897
898 const size_t textLength = dataLength - 3;
899 size_t index;
900 for (index = 0; index < textLength; index++) {
901 const unsigned char data = dataStart[3 + index];
902 if (buflen != NULL && *buflen > 0) {
903 /* If we are receiving right now, and have a buffer... */
904 *(*buf)++ = data;
905 (*buflen)--;
906 } else {
907 xbs->inBuffer[xbs->inInIndex++] = data;
908 if (xbs->inInIndex == sizeof(xbs->inBuffer))
909 xbs->inInIndex = 0;
910 if (xbs->inInIndex == xbs->inOutIndex) {
911 /* Should be impossible */
912 avrdude_message(MSG_INFO, "%s: Buffer overrun\n", progname);
913 xbs->transportUnusable = 1;
914 return -1;
915 }
916 }
917 }
918
919 /*avrdude_message(MSG_INFO, "ACK %x\n", (unsigned int)sequence);*/
920 sendPacket(xbs, "Transmit Request ACK for RECEIVE",
921 XBEEBOOT_PACKET_TYPE_ACK, sequence,
922 XBEE_STATS_NOT_RETRY,
923 -1, 0, NULL);
924
925 if (buf != NULL && *buflen == 0)
926 /* Input buffer has been filled */
927 return 0;
928
929 /*
930 * Input buffer has NOT been filled, we are still in a
931 * receive. Not a retry, this is the first point we know
932 * for sure for this sequence number.
933 */
934 while ((++nextSequence & 0xff) == 0);
935 xbeedev_stats_send(xbs, "poll() implies pending RECEIVE",
936 nextSequence,
937 XBEE_STATS_RECEIVE,
938 nextSequence, XBEE_STATS_NOT_RETRY,
939 &receiveTime);
940 }
941 }
942 }
943 }
944 }
945 }
946
947 /*
948 * @return
949 * 0 on success, a negative value on failure, or a positive
950 * value indicating the sequence number associated with the
951 * request.
952 */
localAsyncAT(struct XBeeBootSession * xbs,char const * detail,unsigned char at1,unsigned char at2,int value)953 static int localAsyncAT(struct XBeeBootSession *xbs, char const *detail,
954 unsigned char at1, unsigned char at2, int value)
955 {
956 if (xbs->directMode)
957 /*
958 * Remote XBee AT commands make no sense in direct mode - there is
959 * no XBee device to communicate with.
960 *
961 * Return success, no sequence number.
962 */
963 return 0;
964
965 while ((++xbs->txSequence & 0xff) == 0);
966 const unsigned char sequence = xbs->txSequence;
967
968 unsigned char buf[3];
969 size_t length = 0;
970
971 buf[length++] = at1;
972 buf[length++] = at2;
973
974 if (value >= 0)
975 buf[length++] = (unsigned char)value;
976
977 avrdude_message(MSG_NOTICE, "%s: Local AT command: %c%c\n",
978 progname, at1, at2);
979
980 /* Local AT command 0x08 */
981 int rc = sendAPIRequest(xbs, 0x08, sequence, -1, -1, -1, -1, -1, -1,
982 detail, -1, XBEE_STATS_FRAME_LOCAL,
983 XBEE_STATS_NOT_RETRY,
984 length, buf);
985 if (rc < 0)
986 /* Failed */
987 return rc;
988
989 /* Success, positive sequence number */
990 return (int)sequence;
991 }
992
localAT(struct XBeeBootSession * xbs,char const * detail,unsigned char at1,unsigned char at2,int value)993 static int localAT(struct XBeeBootSession *xbs, char const *detail,
994 unsigned char at1, unsigned char at2, int value)
995 {
996 int result = localAsyncAT(xbs, detail, at1, at2, value);
997
998 if (result <= 0)
999 /* Failure, or success without a sequence number */
1000 return result;
1001
1002 unsigned char sequence = (unsigned char)result;
1003
1004 int retries;
1005 for (retries = 0; retries < 5; retries++) {
1006 const int rc = xbeedev_poll(xbs, NULL, NULL, -1, sequence);
1007 if (rc == 0)
1008 return 0;
1009 }
1010
1011 return -1;
1012 }
1013
1014 /*
1015 * Return 0 on success.
1016 * Return -1 on generic error (normally serial timeout).
1017 * Return -512 + XBee AT Response code
1018 */
sendAT(struct XBeeBootSession * xbs,char const * detail,unsigned char at1,unsigned char at2,int value)1019 static int sendAT(struct XBeeBootSession *xbs, char const *detail,
1020 unsigned char at1, unsigned char at2, int value)
1021 {
1022 if (xbs->directMode)
1023 /*
1024 * Remote XBee AT commands make no sense in direct mode - there is
1025 * no XBee device to communicate with.
1026 */
1027 return 0;
1028
1029 while ((++xbs->txSequence & 0xff) == 0);
1030 const unsigned char sequence = xbs->txSequence;
1031
1032 unsigned char buf[3];
1033 size_t length = 0;
1034
1035 buf[length++] = at1;
1036 buf[length++] = at2;
1037
1038 if (value >= 0)
1039 buf[length++] = (unsigned char)value;
1040
1041 avrdude_message(MSG_NOTICE,
1042 "%s: Remote AT command: %c%c\n", progname, at1, at2);
1043
1044 /* Remote AT command 0x17 with Apply Changes 0x02 */
1045 sendAPIRequest(xbs, 0x17, sequence, -1,
1046 -1, -1, -1,
1047 0x02, -1,
1048 detail, -1, XBEE_STATS_FRAME_REMOTE,
1049 XBEE_STATS_NOT_RETRY,
1050 length, buf);
1051
1052 int retries;
1053 for (retries = 0; retries < 30; retries++) {
1054 const int rc = xbeedev_poll(xbs, NULL, NULL, -1, sequence);
1055 const int xbeeRc = XBEE_AT_RETURN_CODE(rc);
1056 if (xbeeRc == 0)
1057 /* Translate to normal success code */
1058 return 0;
1059 if (rc != -1)
1060 return rc;
1061 }
1062
1063 return -1;
1064 }
1065
1066 /*
1067 * Return 0 on no error recognised, 1 if error was detected and
1068 * reported.
1069 */
xbeeATError(int rc)1070 static int xbeeATError(int rc) {
1071 const int xbeeRc = XBEE_AT_RETURN_CODE(rc);
1072 if (xbeeRc < 0)
1073 return 0;
1074
1075 if (xbeeRc == 1) {
1076 avrdude_message(MSG_INFO, "%s: Error communicating with Remote XBee\n",
1077 progname);
1078 } else if (xbeeRc == 2) {
1079 avrdude_message(MSG_INFO, "%s: Remote XBee command error: "
1080 "Invalid command\n",
1081 progname);
1082 } else if (xbeeRc == 3) {
1083 avrdude_message(MSG_INFO, "%s: Remote XBee command error: "
1084 "Invalid parameter\n",
1085 progname);
1086 } else if (xbeeRc == 4) {
1087 avrdude_message(MSG_INFO, "%s: Remote XBee error: "
1088 "Transmission failure\n",
1089 progname);
1090 } else {
1091 avrdude_message(MSG_INFO, "%s: Unrecognised remote XBee error code %d\n",
1092 progname, xbeeRc);
1093 }
1094 return 1;
1095 }
1096
xbeedev_free(struct XBeeBootSession * xbs)1097 static void xbeedev_free(struct XBeeBootSession *xbs)
1098 {
1099 xbs->serialDevice->close(&xbs->serialDescriptor);
1100 free(xbs);
1101 }
1102
xbeedev_close(union filedescriptor * fdp)1103 static void xbeedev_close(union filedescriptor *fdp)
1104 {
1105 struct XBeeBootSession *xbs = xbeebootsession(fdp);
1106 xbeedev_free(xbs);
1107 }
1108
xbeedev_open(char * port,union pinfo pinfo,union filedescriptor * fdp)1109 static int xbeedev_open(char *port, union pinfo pinfo,
1110 union filedescriptor *fdp)
1111 {
1112 /*
1113 * The syntax for XBee devices is defined as:
1114 *
1115 * -P <XBeeAddress>@[serialdevice]
1116 *
1117 * ... or ...
1118 *
1119 * -P @[serialdevice]
1120 *
1121 * ... for a direct connection.
1122 */
1123 char *ttySeparator = strchr(port, '@');
1124 if (ttySeparator == NULL) {
1125 avrdude_message(MSG_INFO,
1126 "%s: XBee: Bad port syntax: "
1127 "require \"<xbee-address>@<serial-device>\"\n",
1128 progname);
1129 return -1;
1130 }
1131
1132 struct XBeeBootSession *xbs = malloc(sizeof(struct XBeeBootSession));
1133 if (xbs == NULL) {
1134 avrdude_message(MSG_INFO, "%s: xbeedev_open(): out of memory\n",
1135 progname);
1136 return -1;
1137 }
1138
1139 XBeeBootSessionInit(xbs);
1140
1141 char *tty = &ttySeparator[1];
1142
1143 if (ttySeparator == port) {
1144 /* Direct connection */
1145 memset(xbs->xbee_address, 0, 8);
1146 xbs->directMode = 1;
1147 } else {
1148 size_t addrIndex = 0;
1149 int nybble = -1;
1150 char const *address = port;
1151 while (address != ttySeparator) {
1152 char hex = *address++;
1153 unsigned int val;
1154 if (hex >= '0' && hex <= '9') {
1155 val = hex - '0';
1156 } else if (hex >= 'A' && hex <= 'F') {
1157 val = hex - 'A' + 10;
1158 } else if (hex >= 'a' && hex <= 'f') {
1159 val = hex - 'a' + 10;
1160 } else {
1161 break;
1162 }
1163 if (nybble == -1) {
1164 nybble = val;
1165 } else {
1166 xbs->xbee_address[addrIndex++] = (nybble * 16) | val;
1167 nybble = -1;
1168 if (addrIndex == 8)
1169 break;
1170 }
1171 }
1172
1173 if (addrIndex != 8 || address != ttySeparator || nybble != -1) {
1174 avrdude_message(MSG_INFO,
1175 "%s: XBee: Bad XBee address: "
1176 "require 16-character hexadecimal address\"\n",
1177 progname);
1178 free(xbs);
1179 return -1;
1180 }
1181
1182 xbs->directMode = 0;
1183 }
1184
1185 /* Unknown 16 bit address */
1186 xbs->xbee_address[8] = 0xff;
1187 xbs->xbee_address[9] = 0xfe;
1188
1189 avrdude_message(MSG_TRACE,
1190 "%s: XBee address: %02x%02x%02x%02x%02x%02x%02x%02x\n",
1191 progname,
1192 (unsigned int)xbs->xbee_address[0],
1193 (unsigned int)xbs->xbee_address[1],
1194 (unsigned int)xbs->xbee_address[2],
1195 (unsigned int)xbs->xbee_address[3],
1196 (unsigned int)xbs->xbee_address[4],
1197 (unsigned int)xbs->xbee_address[5],
1198 (unsigned int)xbs->xbee_address[6],
1199 (unsigned int)xbs->xbee_address[7]);
1200
1201 if (pinfo.baud) {
1202 /*
1203 * User supplied the correct baud rate.
1204 */
1205 } else if (xbs->directMode) {
1206 /*
1207 * In direct mode, default to 19200.
1208 *
1209 * Why?
1210 *
1211 * In this mode, we are NOT talking to an XBee, we are talking
1212 * directly to an AVR device that thinks it is talking to an XBee
1213 * itself.
1214 *
1215 * Because, an XBee is a 3.3V device defaulting to 9600baud, and
1216 * the Atmel328P is only rated at a maximum clock rate of 8MHz
1217 * with a 3.3V supply, so there's a high likelihood a remote
1218 * Atmel328P will be clocked at 8MHz.
1219 *
1220 * With a direct connection, there's a good chance we're talking
1221 * to an Arduino clocked at 16MHz with an XBee-enabled chip
1222 * plugged in. The doubled clock rate means a doubled serial
1223 * rate. Double 9600 baud == 19200 baud.
1224 */
1225 pinfo.baud = 19200;
1226 } else {
1227 /*
1228 * In normal mode, default to 9600.
1229 *
1230 * Why?
1231 *
1232 * XBee devices default to 9600 baud. In this mode we are talking
1233 * to the XBee device, not the far-end device, so it's the local
1234 * XBee baud rate we should select. The baud rate of the AVR
1235 * device is irrelevant.
1236 */
1237 pinfo.baud = 9600;
1238 }
1239
1240 avrdude_message(MSG_NOTICE, "%s: Baud %ld\n", progname, (long)pinfo.baud);
1241
1242 {
1243 const int rc = xbs->serialDevice->open(tty, pinfo,
1244 &xbs->serialDescriptor);
1245 if (rc < 0) {
1246 free(xbs);
1247 return rc;
1248 }
1249 }
1250
1251 if (!xbs->directMode) {
1252 /* Attempt to ensure the local XBee is in API mode 2 */
1253 {
1254 const int rc = localAT(xbs, "AT AP=2", 'A', 'P', 2);
1255 if (rc < 0) {
1256 avrdude_message(MSG_INFO, "%s: Local XBee is not responding.\n",
1257 progname);
1258 xbeedev_free(xbs);
1259 return rc;
1260 }
1261 }
1262
1263 /*
1264 * At this point we want to set the remote XBee parameters as
1265 * required for talking to XBeeBoot. Ideally we would start with
1266 * an "FR" full reset, but because that causes the XBee to
1267 * disappear off the mesh for a significant period and become
1268 * unresponsive, we don't do that.
1269 */
1270
1271 /*
1272 * Issue an "Aggregate Routing Notification" to enable many-to-one
1273 * routing to this device. This has two effects:
1274 *
1275 * - Establishes a route from the remote XBee attached to the CPU
1276 * being programmed back to the local XBee.
1277 *
1278 * - Enables the 0xa1 Route frames so that we can make use of
1279 * Source Routing to deliver packets directly to the remote
1280 * XBee.
1281 *
1282 * Under "RF packet routing" subsection "Many-to-One routing", the
1283 * XBee S2C manual states "Applications that require multiple data
1284 * collectors can also use many-to-one routing. If more than one
1285 * data collector device sends a many-to-one broadcast, devices
1286 * create one reverse routing table entry for each collector."
1287 *
1288 * Under "RF packet routing" subsection "Source routing", the XBee
1289 * S2C manual states "To use source routing, a device must use the
1290 * API mode, and it must send periodic many-to-one route request
1291 * broadcasts (AR command) to create a many-to-one route to it on
1292 * all devices".
1293 */
1294 {
1295 const int rc = localAT(xbs, "AT AR=0", 'A', 'R', 0);
1296 if (rc < 0) {
1297 avrdude_message(MSG_INFO, "%s: Local XBee is not responding.\n",
1298 progname);
1299 xbeedev_free(xbs);
1300 return rc;
1301 }
1302 }
1303
1304 /*
1305 * Disable RTS input on the remote XBee, just in case it is
1306 * enabled by default. XBeeBoot doesn't attempt to support flow
1307 * control, and so it may not correctly drive this pin if RTS mode
1308 * is the default configuration.
1309 *
1310 * XBee IO port 6 is the only pin that supports RTS mode, so there
1311 * is no need to support any alternative pin.
1312 */
1313 const int rc = sendAT(xbs, "AT D6=0", 'D', '6', 0);
1314 if (rc < 0) {
1315 xbeedev_free(xbs);
1316
1317 if (xbeeATError(rc))
1318 return -1;
1319
1320 avrdude_message(MSG_INFO, "%s: Remote XBee is not responding.\n",
1321 progname);
1322 return rc;
1323 }
1324 }
1325
1326 fdp->pfd = xbs;
1327
1328 return 0;
1329 }
1330
xbeedev_send(union filedescriptor * fdp,const unsigned char * buf,size_t buflen)1331 static int xbeedev_send(union filedescriptor *fdp,
1332 const unsigned char *buf, size_t buflen)
1333 {
1334 struct XBeeBootSession *xbs = xbeebootsession(fdp);
1335
1336 if (xbs->transportUnusable)
1337 /* Don't attempt to continue on an unusable transport layer */
1338 return -1;
1339
1340 while (buflen > 0) {
1341 unsigned char sequence = xbs->outSequence;
1342 while ((++sequence & 0xff) == 0);
1343 xbs->outSequence = sequence;
1344
1345 /*
1346 * We are about to send some data, and that might lead potentially
1347 * to received data before we see the ACK for this transmission.
1348 * As this might be the trigger seen before the next "recv"
1349 * operation, record that we have delivered this potential
1350 * trigger.
1351 */
1352 {
1353 unsigned char nextSequence = xbs->inSequence;
1354 while ((++nextSequence & 0xff) == 0);
1355
1356 struct timeval sendTime;
1357 gettimeofday(&sendTime, NULL);
1358
1359 /*
1360 * Optimistic records should never be treated as retries,
1361 * because they might simply be guessing too optimistically.
1362 */
1363 xbeedev_stats_send(xbs, "send() hints possible triggered RECEIVE",
1364 nextSequence,
1365 XBEE_STATS_RECEIVE,
1366 nextSequence, 0, &sendTime);
1367 }
1368
1369 /*
1370 * Chunk the data into chunks of up to XBEEBOOT_MAX_CHUNK bytes.
1371 */
1372 unsigned char maximum_chunk = XBEEBOOT_MAX_CHUNK;
1373
1374 /*
1375 * Source routing incurs a two byte fixed overhead, plus a two
1376 * byte additional cost per intermediate hop.
1377 *
1378 * We are attempting to avoid fragmentation here, so resize our
1379 * maximum size to anticipate the overhead of the current number
1380 * of hops. If our maximum chunk would be less than one, just
1381 * give up and hope fragmentation will somehow save us.
1382 */
1383 const int hops = xbs->sourceRouteHops;
1384 if (hops > 0 && (hops * 2 + 2) < XBEEBOOT_MAX_CHUNK)
1385 maximum_chunk -= hops * 2 + 2;
1386
1387 const unsigned char blockLength =
1388 (buflen > maximum_chunk) ? maximum_chunk : buflen;
1389
1390 int pollRc = 0;
1391
1392 /* Repeatedly send whilst timing out waiting for ACK responses. */
1393 int retries;
1394 for (retries = 0; retries < XBEE_MAX_RETRIES; retries++) {
1395 int sendRc =
1396 sendPacket(xbs,
1397 "Transmit Request Data, expect ACK for TRANSMIT",
1398 XBEEBOOT_PACKET_TYPE_REQUEST, sequence,
1399 retries > 0 ? XBEE_STATS_IS_RETRY : XBEE_STATS_NOT_RETRY,
1400 23 /* FIRMWARE_DELIVER */,
1401 blockLength, buf);
1402 if (sendRc < 0) {
1403 /* There is no way to recover from a failure mid-send */
1404 xbs->transportUnusable = 1;
1405 return sendRc;
1406 }
1407
1408 pollRc = xbeedev_poll(xbs, NULL, NULL, sequence, -1);
1409 if (pollRc == 0) {
1410 /* Send was ACK'd */
1411 buflen -= blockLength;
1412 buf += blockLength;
1413 break;
1414 }
1415
1416 /*
1417 * Test the connection to the local XBee by repeatedly
1418 * requesting local configuration details. This functionally
1419 * has no effect, but will allow us to measure any reliability
1420 * issues on this link.
1421 */
1422 localAsyncAT(xbs, "Local XBee ping [send]", 'A', 'P', -1);
1423
1424 /*
1425 * If we don't receive an ACK it might be because the chip
1426 * missed an ACK from us. Resend that too after a timeout,
1427 * unless it's zero which is an illegal sequence number.
1428 */
1429 if (xbs->inSequence != 0) {
1430 int ackRc = sendPacket(xbs,
1431 "Transmit Request ACK [Retry in send] "
1432 "for RECEIVE",
1433 XBEEBOOT_PACKET_TYPE_ACK,
1434 xbs->inSequence,
1435 XBEE_STATS_IS_RETRY,
1436 -1, 0, NULL);
1437 if (ackRc < 0) {
1438 /* There is no way to recover from a failure mid-send */
1439 xbs->transportUnusable = 1;
1440 return ackRc;
1441 }
1442 }
1443 }
1444
1445 if (pollRc < 0) {
1446 /* There is no way to recover from a failure mid-send */
1447 xbs->transportUnusable = 1;
1448 return pollRc;
1449 }
1450 }
1451
1452 return 0;
1453 }
1454
xbeedev_recv(union filedescriptor * fdp,unsigned char * buf,size_t buflen)1455 static int xbeedev_recv(union filedescriptor *fdp,
1456 unsigned char *buf, size_t buflen)
1457 {
1458 struct XBeeBootSession *xbs = xbeebootsession(fdp);
1459
1460 /*
1461 * First de-buffer anything previously received in a chunk that
1462 * couldn't be immediately delievered.
1463 */
1464 while (xbs->inInIndex != xbs->inOutIndex) {
1465 *buf++ = xbs->inBuffer[xbs->inOutIndex++];
1466 if (xbs->inOutIndex == sizeof(xbs->inBuffer))
1467 xbs->inOutIndex = 0;
1468 if (--buflen == 0)
1469 return 0;
1470 }
1471
1472 if (xbs->transportUnusable)
1473 /* Don't attempt to continue on an unusable transport layer */
1474 return -1;
1475
1476 /*
1477 * When we expect to receive data, that is the time to start the
1478 * clock.
1479 */
1480 {
1481 unsigned char nextSequence = xbs->inSequence;
1482 while ((++nextSequence & 0xff) == 0);
1483
1484 struct timeval sendTime;
1485 gettimeofday(&sendTime, NULL);
1486
1487 /*
1488 * Not a retry - in fact this is the first stage we know for sure
1489 * a RECEIVE is due.
1490 */
1491 xbeedev_stats_send(xbs, "recv() implies pending RECEIVE",
1492 nextSequence,
1493 XBEE_STATS_RECEIVE,
1494 nextSequence,
1495 XBEE_STATS_NOT_RETRY,
1496 &sendTime);
1497 }
1498
1499 int retries;
1500 for (retries = 0; retries < XBEE_MAX_RETRIES; retries++) {
1501 const int rc = xbeedev_poll(xbs, &buf, &buflen, -1, -1);
1502 if (rc == 0)
1503 return 0;
1504
1505 if (xbs->transportUnusable)
1506 /* Don't attempt to continue on an unusable transport layer */
1507 return -1;
1508
1509 /*
1510 * Test the connection to the local XBee by repeatedly
1511 * requesting local configuration details. This functionally
1512 * has no effect, but will allow us to measure any reliability
1513 * issues on this link.
1514 */
1515 localAsyncAT(xbs, "Local XBee ping [recv]", 'A', 'P', -1);
1516
1517 /*
1518 * The chip may have missed an ACK from us. Resend after a
1519 * timeout.
1520 */
1521 if (xbs->inSequence != 0)
1522 sendPacket(xbs, "Transmit Request ACK [Retry in recv] for RECEIVE",
1523 XBEEBOOT_PACKET_TYPE_ACK, xbs->inSequence,
1524 XBEE_STATS_IS_RETRY,
1525 -1, 0, NULL);
1526 }
1527 return -1;
1528 }
1529
xbeedev_drain(union filedescriptor * fdp,int display)1530 static int xbeedev_drain(union filedescriptor *fdp, int display)
1531 {
1532 struct XBeeBootSession *xbs = xbeebootsession(fdp);
1533
1534 if (xbs->transportUnusable)
1535 /* Don't attempt to continue on an unusable transport layer */
1536 return -1;
1537
1538 /*
1539 * Flushing the local serial buffer is unhelpful under this
1540 * protocol.
1541 */
1542 do {
1543 xbs->inOutIndex = xbs->inInIndex = 0;
1544 } while (xbeedev_poll(xbs, NULL, NULL, -1, -1) == 0);
1545
1546 return 0;
1547 }
1548
xbeedev_set_dtr_rts(union filedescriptor * fdp,int is_on)1549 static int xbeedev_set_dtr_rts(union filedescriptor *fdp, int is_on)
1550 {
1551 struct XBeeBootSession *xbs = xbeebootsession(fdp);
1552
1553 if (xbs->directMode)
1554 /* Correct for direct mode */
1555 return xbs->serialDevice->set_dtr_rts(&xbs->serialDescriptor, is_on);
1556
1557 /*
1558 * For non-direct mode (Over-The-Air) we need to issue XBee commands
1559 * to the remote XBee in order to reset the AVR CPU and initiate the
1560 * XBeeBoot bootloader.
1561 */
1562 const int rc = sendAT(xbs, is_on ? "AT [DTR]=low" : "AT [DTR]=high",
1563 'D', '0' + xbs->xbeeResetPin, is_on ? 5 : 4);
1564 if (rc < 0) {
1565 if (xbeeATError(rc))
1566 return -1;
1567
1568 avrdude_message(MSG_INFO,
1569 "%s: Remote XBee is not responding.\n", progname);
1570 return rc;
1571 }
1572
1573 return 0;
1574 }
1575
1576 /*
1577 * Device descriptor for XBee framing.
1578 */
1579 static struct serial_device xbee_serdev_frame = {
1580 .open = xbeedev_open,
1581 .close = xbeedev_close,
1582 .send = xbeedev_send,
1583 .recv = xbeedev_recv,
1584 .drain = xbeedev_drain,
1585 .set_dtr_rts = xbeedev_set_dtr_rts,
1586 .flags = SERDEV_FL_NONE,
1587 };
1588
xbee_getsync(PROGRAMMER * pgm)1589 static int xbee_getsync(PROGRAMMER *pgm)
1590 {
1591 unsigned char buf[2], resp[2];
1592
1593 /*
1594 * Issue sync request as per STK500. Unlike stk500_getsync(), don't
1595 * retry here - the underlying protocol will deal with retries for
1596 * us in xbeedev_send() and should be reliable.
1597 */
1598 buf[0] = Cmnd_STK_GET_SYNC;
1599 buf[1] = Sync_CRC_EOP;
1600
1601 int sendRc = serial_send(&pgm->fd, buf, 2);
1602 if (sendRc < 0) {
1603 avrdude_message(MSG_INFO,
1604 "%s: xbee_getsync(): failed to deliver STK_GET_SYNC "
1605 "to the remote XBeeBoot bootloader\n",
1606 progname);
1607 return sendRc;
1608 }
1609
1610 /*
1611 * The same is true of the receive - it will retry on timeouts until
1612 * the response buffer is full.
1613 */
1614 int recvRc = serial_recv(&pgm->fd, resp, 2);
1615 if (recvRc < 0) {
1616 avrdude_message(MSG_INFO,
1617 "%s: xbee_getsync(): no response to STK_GET_SYNC "
1618 "from the remote XBeeBoot bootloader\n",
1619 progname);
1620 return recvRc;
1621 }
1622
1623 if (resp[0] != Resp_STK_INSYNC) {
1624 avrdude_message(MSG_INFO, "%s: xbee_getsync(): not in sync: resp=0x%02x\n",
1625 progname, (unsigned int)resp[0]);
1626 return -1;
1627 }
1628
1629 if (resp[1] != Resp_STK_OK) {
1630 avrdude_message(MSG_INFO, "%s: xbee_getsync(): in sync, not OK: "
1631 "resp=0x%02x\n",
1632 progname, (unsigned int)resp[1]);
1633 return -1;
1634 }
1635
1636 return 0;
1637 }
1638
xbee_open(PROGRAMMER * pgm,char * port)1639 static int xbee_open(PROGRAMMER *pgm, char *port)
1640 {
1641 union pinfo pinfo;
1642 strcpy(pgm->port, port);
1643 pinfo.baud = pgm->baudrate;
1644
1645 /* Wireless is lossier than normal serial */
1646 serial_recv_timeout = 1000;
1647
1648 serdev = &xbee_serdev_frame;
1649
1650 if (serial_open(port, pinfo, &pgm->fd) == -1) {
1651 return -1;
1652 }
1653
1654 /*
1655 * NB: Because we are making use of the STK500 programmer
1656 * implementation, we can't readily use pgm->cookie ourselves. We
1657 * can use the private "flag" field in the PROGRAMMER though, as
1658 * it's unused by stk500.c.
1659 */
1660 xbeedev_setresetpin(&pgm->fd, pgm->flag);
1661
1662 /* Clear DTR and RTS */
1663 serial_set_dtr_rts(&pgm->fd, 0);
1664 usleep(250*1000);
1665
1666 /* Set DTR and RTS back to high */
1667 serial_set_dtr_rts(&pgm->fd, 1);
1668 usleep(50*1000);
1669
1670 /*
1671 * At this point stk500_drain() and stk500_getsync() calls would
1672 * normally be made. But given that we have a transport layer over
1673 * the serial command stream, the drain and repeated STK_GET_SYNC
1674 * requests are not very helpful. Instead, skip the draining
1675 * entirely, and issue the STK_GET_SYNC ourselves.
1676 */
1677 if (xbee_getsync(pgm) < 0)
1678 return -1;
1679
1680 return 0;
1681 }
1682
xbee_close(PROGRAMMER * pgm)1683 static void xbee_close(PROGRAMMER *pgm)
1684 {
1685 struct XBeeBootSession *xbs = xbeebootsession(&pgm->fd);
1686
1687 /*
1688 * NB: This request is for the target device, not the locally
1689 * connected serial device.
1690 */
1691 serial_set_dtr_rts(&pgm->fd, 0);
1692
1693 /*
1694 * We have tweaked a few settings on the XBee, including the RTS
1695 * mode and the reset pin's configuration. Do a soft full reset,
1696 * restoring the device to its normal power-on settings.
1697 *
1698 * Note that this DOES mean that the remote XBee will be
1699 * uncontactable until it has restarted and re-established
1700 * communications on the mesh.
1701 */
1702 if (!xbs->directMode) {
1703 const int rc = sendAT(xbs, "AT FR", 'F', 'R', -1);
1704 xbeeATError(rc);
1705 }
1706
1707 avrdude_message(MSG_NOTICE, "%s: Statistics for FRAME_LOCAL requests - %s->XBee(local)\n", progname, progname);
1708 xbeeStatsSummarise(&xbs->groupSummary[XBEE_STATS_FRAME_LOCAL]);
1709
1710 avrdude_message(MSG_NOTICE, "%s: Statistics for FRAME_REMOTE requests - %s->XBee(local)->XBee(target)\n", progname, progname);
1711 xbeeStatsSummarise(&xbs->groupSummary[XBEE_STATS_FRAME_REMOTE]);
1712
1713 avrdude_message(MSG_NOTICE, "%s: Statistics for TRANSMIT requests - %s->XBee(local)->XBee(target)->XBeeBoot\n", progname, progname);
1714 xbeeStatsSummarise(&xbs->groupSummary[XBEE_STATS_TRANSMIT]);
1715
1716 avrdude_message(MSG_NOTICE, "%s: Statistics for RECEIVE requests - XBeeBoot->XBee(target)->XBee(local)->%s\n", progname, progname);
1717 xbeeStatsSummarise(&xbs->groupSummary[XBEE_STATS_RECEIVE]);
1718
1719 xbeedev_free(xbs);
1720
1721 pgm->fd.pfd = NULL;
1722 }
1723
xbee_parseextparms(PROGRAMMER * pgm,LISTID extparms)1724 static int xbee_parseextparms(PROGRAMMER *pgm, LISTID extparms)
1725 {
1726 LNODEID ln;
1727 const char *extended_param;
1728 int rc = 0;
1729
1730 for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
1731 extended_param = ldata(ln);
1732
1733 if (strncmp(extended_param,
1734 "xbeeresetpin=", 13 /*strlen("xbeeresetpin=")*/) == 0) {
1735 int resetpin;
1736 if (sscanf(extended_param, "xbeeresetpin=%i", &resetpin) != 1 ||
1737 resetpin <= 0 || resetpin > 7) {
1738 avrdude_message(MSG_INFO, "%s: xbee_parseextparms(): "
1739 "invalid xbeeresetpin '%s'\n",
1740 progname, extended_param);
1741 rc = -1;
1742 continue;
1743 }
1744
1745 pgm->flag = resetpin;
1746 continue;
1747 }
1748
1749 avrdude_message(MSG_INFO, "%s: xbee_parseextparms(): "
1750 "invalid extended parameter '%s'\n",
1751 progname, extended_param);
1752 rc = -1;
1753 }
1754
1755 return rc;
1756 }
1757
1758 const char xbee_desc[] = "XBee Series 2 Over-The-Air (XBeeBoot)";
1759
xbee_initpgm(PROGRAMMER * pgm)1760 void xbee_initpgm(PROGRAMMER *pgm)
1761 {
1762 /*
1763 * This behaves like an Arduino, but with packet encapsulation of
1764 * the serial streams, XBee device management, and XBee GPIO for the
1765 * Auto-Reset feature.
1766 */
1767 stk500_initpgm(pgm);
1768
1769 strncpy(pgm->type, "XBee", sizeof(pgm->type));
1770 pgm->read_sig_bytes = xbee_read_sig_bytes;
1771 pgm->open = xbee_open;
1772 pgm->close = xbee_close;
1773
1774 /*
1775 * NB: Because we are making use of the STK500 programmer
1776 * implementation, we can't readily use pgm->cookie ourselves, nor
1777 * can we override setup() and teardown(). We can use the private
1778 * "flag" field in the PROGRAMMER though, as it's unused by
1779 * stk500.c.
1780 */
1781 pgm->parseextparams = xbee_parseextparms;
1782 pgm->flag = XBEE_DEFAULT_RESET_PIN;
1783 }
1784