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