*/
#include <aversive.h>
+#include <aversive/pgmspace.h>
#include <aversive/queue.h>
#include <aversive/endian.h>
{
void *buf = dev->frame;
uint8_t len = dev->frame_len;
+ uint8_t hdrlen;
struct xbee_hdr *hdr = buf;
int i;
uint8_t cksum = 0;
dev->stats.rx_frame++;
+ switch (hdr->type) {
+ case XBEE_TYPE_MODEM_STATUS:
+ case XBEE_TYPE_RECV:
+ case XBEE_TYPE_EXPL_RECV:
+ hdrlen = sizeof(struct xbee_hdr) - 1; /* no frame ID */
+ break;
+ default:
+ hdrlen = sizeof(struct xbee_hdr);
+ break;
+ }
+
/* check frame len */
- if (len < (sizeof(*hdr) + 1)) {
+ if (len < (hdrlen + 1)) {
dev->stats.rx_frame_too_small++;
- fprintf(stderr, "Frame too small\n");
+ fprintf_P(stderr, PSTR("Frame too small\r\n"));
return -1;
}
cksum += ((uint8_t *)buf)[i];
cksum = 0xff - cksum;
if (cksum != ((uint8_t *)buf)[len-1]) {
- fprintf(stderr, "Invalid cksum\n");
+ fprintf_P(stderr, PSTR("Invalid cksum\r\n"));
dev->stats.rx_invalid_cksum++;
return -1;
}
/* execute the callback if any */
if (dev->channel[channel].rx_cb != NULL)
dev->channel[channel].rx_cb(dev, channel, hdr->type,
- buf + sizeof(struct xbee_hdr),
- len - sizeof(struct xbee_hdr) - 1,
+ buf + hdrlen,
+ len - hdrlen - 1,
dev->channel[channel].arg);
return 0;
hdr.type = type;
hdr.id = channel_id;
- if (channel_id < 0 || channel_id >= XBEE_MAX_CHANNEL ||
+ if (channel_id >= XBEE_MAX_CHANNEL ||
dev->channel[channel_id].registered == 0) {
dev->stats.tx_invalid_channel ++;
return -1;
case XBEE_TYPE_RMT_ATRESP:
default:
dev->stats.tx_invalid_type ++;
- fprintf(stderr, "unhandled xmit type=%x\n", hdr.type);
+ fprintf_P(stderr, PSTR("unhandled xmit type=%x\r\n"),
+ hdr.type);
return -1;
}
continue;
}
+ if (dev->frame_len == 0 && c != XBEE_DELIMITER)
+ continue;
+
dev->frame[dev->frame_len++] = c;
/* not enough data to read len */
framelen = ntohs(hdr->len);
framelen += 4; /* 1 for delimiter, 2 for len, 1 for cksum */
+ /* frame too long XXX stats */
+ if (framelen >= XBEE_MAX_FRAME_LEN) {
+ dev->frame_len = 0;
+ continue;
+ }
+
/* not enough data */
if (dev->frame_len < framelen)
continue;
- if (xbee_proto_parse_frame(dev) < 0)
+ if (xbee_proto_parse_frame(dev) < 0) {
;//XXX stats
+ }
dev->frame_len = 0;
}
}