xbee_err xbee_sZB_ota_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (buf->len != 22) return XBEE_ELENGTH; if ((ret = xbee_pktAlloc(&iPkt, NULL, 2)) != XBEE_ENONE) return ret; //#warning TODO - check that these are the correct addresses to be using address->addr64_enabled = 1; memcpy(address->addr64, &(buf->data[1]), 8); address->addr16_enabled = 1; memcpy(address->addr16, &(buf->data[9]), 2); iPkt->options = buf->data[11]; iPkt->dataLen = 2; iPkt->data[0] = buf->data[12]; /* bootloader message type */ iPkt->data[1] = buf->data[13]; /* block number */ iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_s2_transmitStatus_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; int i; xbee_err ret; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; ret = XBEE_ENONE; if (buf->len != 7) { ret = XBEE_ELENGTH; goto die1; } #warning TODO - currently missing out on the resolved network address, retry count, and discovery status frameInfo->active = 1; frameInfo->id = buf->data[1]; frameInfo->retVal = buf->data[5]; if ((ret = xbee_pktAlloc(&iPkt, NULL, 6)) != XBEE_ENONE) return ret; iPkt->dataLen = 6; for (i = 0; i < 6; i++) { iPkt->data[i] = buf->data[i+1]; } iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; goto done; die1: done: return ret; }
xbee_err xbee_s2_sensor_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (buf->len != 22) return XBEE_ELENGTH; if ((ret = xbee_pktAlloc(&iPkt, NULL, 11)) != XBEE_ENONE) return ret; address->addr64_enabled = 1; memcpy(address->addr64, &(buf->data[1]), 8); address->addr16_enabled = 1; memcpy(address->addr16, &(buf->data[9]), 2); iPkt->options = buf->data[11]; iPkt->dataLen = 11; memcpy(iPkt->data, &(buf->data[12]), 11); iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_s2_dataExp_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_buf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (buf->len < 18) return XBEE_ELENGTH; /* ClusterID (2 bytes) */ /* ProfileID (2 bytes) */ if ((ret = xbee_pktAlloc(&iPkt, NULL, buf->len - 18)) != XBEE_ENONE) return ret; address->addr64_enabled = 1; memcpy(address->addr64, &(buf->data[1]), 8); address->addr16_enabled = 1; memcpy(address->addr16, &(buf->data[9]), 2); address->endpoints_enabled = 1; address->endpoint_remote = buf->data[11]; address->endpoint_local = buf->data[12]; iPkt->options = buf->data[17]; iPkt->dataLen = buf->len - 18; if (iPkt->dataLen > 0) { memcpy(iPkt->data, &(buf->data[18]), iPkt->dataLen); } iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_netServer_fc_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_buf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; int pos; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; /* identifier + frameId + address (2 bytes) */ pos = 4; if ((ret = xbee_pktAlloc(&iPkt, NULL, buf->len - pos)) != XBEE_ENONE) return ret; iPkt->frameId = buf->data[1]; address->addr16_enabled = 1; address->addr16[0] = buf->data[2]; address->addr16[1] = buf->data[3]; iPkt->dataLen = buf->len - pos; if (iPkt->dataLen > 0) { memcpy(iPkt->data, &(buf->data[pos]), iPkt->dataLen); } iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_netServer_fc_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { /* see the counterpart Tx function modes/net/handlers.c - xbee_net_frontchannel_tx_func() */ struct xbee_pkt *iPkt; xbee_err ret; int pos; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; /* identifier + frameId + address (2 bytes) */ pos = 4; if ((ret = xbee_pktAlloc(&iPkt, NULL, buf->len - pos)) != XBEE_ENONE) return ret; iPkt->frameId = buf->data[1]; address->addr16_enabled = 1; address->addr16[0] = buf->data[2]; /* (conIdentifier >> 8) & 0xFF */ address->addr16[1] = buf->data[3]; /* conIdentifier & 0xFF */ iPkt->dataLen = buf->len - pos; if (iPkt->dataLen > 0) { memcpy(iPkt->data, &(buf->data[pos]), iPkt->dataLen); } iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_s3_dataExp_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (buf->len < 18) return XBEE_ELENGTH; if ((ret = xbee_pktAlloc(&iPkt, NULL, buf->len - 18)) != XBEE_ENONE) return ret; address->addr64_enabled = 1; memcpy(address->addr64, &(buf->data[1]), 8); address->endpoints_enabled = 1; address->endpoint_remote = buf->data[11]; address->endpoint_local = buf->data[12]; address->cluster_enabled = 1; address->cluster_id = ((buf->data[13] << 8) & 0xFF00) | (buf->data[14] & 0xFF); address->profile_enabled = 1; address->profile_id = ((buf->data[15] << 8) & 0xFF00) | (buf->data[16] & 0xFF); iPkt->options = buf->data[17]; if (iPkt->options & 0x02) address->broadcast = 1; iPkt->dataLen = buf->len - 18; if (iPkt->dataLen > 0) { memcpy(iPkt->data, &(buf->data[18]), iPkt->dataLen); } iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_s3_data_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (buf->len < 12) return XBEE_ELENGTH; if ((ret = xbee_pktAlloc(&iPkt, NULL, buf->len - 12)) != XBEE_ENONE) return ret; address->addr64_enabled = 1; memcpy(address->addr64, &(buf->data[1]), 8); iPkt->options = buf->data[11]; if (iPkt->options & 0x02) address->broadcast = 1; iPkt->dataLen = buf->len - 12; if (iPkt->dataLen > 0) { memcpy(iPkt->data, &(buf->data[12]), iPkt->dataLen); } iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_s6b_io_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (buf->len < 11) return XBEE_ELENGTH; if ((ret = xbee_pktAlloc(&iPkt, NULL, buf->len - 11)) != XBEE_ENONE) return ret; address->addr64_enabled = 1; address->addr64[0] = buf->data[5]; address->addr64[1] = buf->data[6]; address->addr64[2] = buf->data[7]; address->addr64[3] = buf->data[8]; iPkt->rssi = buf->data[9]; iPkt->options = buf->data[10]; iPkt->dataLen = buf->len - 11; if (iPkt->dataLen > 0) { memcpy(iPkt->data, &(buf->data[11]), iPkt->dataLen); } iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_s6b_at_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; int addrLen; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (buf->len < 1) return XBEE_ELENGTH; switch (buf->data[0]) { case 0x88: addrLen = 0; break; /* Local AT */ case 0x87: addrLen = 8; break; /* Remote AT */ default: return XBEE_EINVAL; } if (buf->len < addrLen + 5) return XBEE_ELENGTH; frameInfo->active = 1; frameInfo->id = buf->data[1]; frameInfo->retVal = buf->data[addrLen + 4]; if (frameInfo->retVal != 0) { *pkt = 0; return XBEE_ENONE; } if ((ret = xbee_pktAlloc(&iPkt, NULL, buf->len - addrLen - 5)) != XBEE_ENONE) return ret; iPkt->frameId = frameInfo->id; if (addrLen == 8) { address->addr64_enabled = 1; address->addr64[0] = buf->data[7]; address->addr64[1] = buf->data[8]; address->addr64[2] = buf->data[9]; address->addr64[3] = buf->data[10]; } /* (... - 5) + 2 -> API Identifier + Frame ID + Status */ iPkt->dataLen = (buf->len - addrLen - 5); memcpy(iPkt->atCommand, &(buf->data[addrLen + 2]) , 2); /* copy in the AT command */ if (iPkt->dataLen > 0) { memcpy(iPkt->data, &(buf->data[addrLen + 5]), iPkt->dataLen); /* copy in the response value (if any) */ } iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_sZB_identify_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; struct xbee_conAddress *addr; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (buf->len < 30) return XBEE_ELENGTH; if ((ret = xbee_pktAlloc(&iPkt, NULL, buf->len - 12)) != XBEE_ENONE) return ret; iPkt->options = buf->data[11]; iPkt->dataLen = buf->len - 12; if (iPkt->dataLen > 0) { memcpy(iPkt->data, &(buf->data[12]), iPkt->dataLen); if (iPkt->dataLen > 2) { xbee_pktDataAdd(iPkt, "Address (16-bit)", 0, &(iPkt->data[0]), NULL); } if (iPkt->dataLen > 10) { xbee_pktDataAdd(iPkt, "Address (64-bit)", 0, &(iPkt->data[2]), NULL); if ((addr = malloc(sizeof(*addr))) != NULL) { memset(addr, 0, sizeof(*addr)); addr->addr16_enabled = 1; memcpy(addr->addr16, &(iPkt->data[0]), 2); addr->addr64_enabled = 1; memcpy(addr->addr64, &(iPkt->data[2]), 8); if (xbee_pktDataAdd(iPkt, "Address", 0, addr, free) != XBEE_ENONE) { free(addr); } } } if (iPkt->dataLen > 11) { /* just point into the packet data */ xbee_pktDataAdd(iPkt, "NI", 0, &(iPkt->data[10]), NULL); } } iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_s2_modemStatus_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (buf->len != 2) return XBEE_ELENGTH; if ((ret = xbee_pktAlloc(&iPkt, NULL, 1)) != XBEE_ENONE) return ret; iPkt->dataLen = 1; iPkt->data[0] = buf->data[1]; iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return 0; }
xbee_err xbee_netServer_bc_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_buf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; int pos; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (!arg) { if (buf->len < 4) return XBEE_ELENGTH; /* only in the client, notify about frameID */ frameInfo->active = 1; frameInfo->id = buf->data[2]; frameInfo->retVal = buf->data[3]; pos = 4; } else { if (buf->len < 3) return XBEE_ELENGTH; pos = 3; } if (buf->len == pos && buf->data[1] == 0) { /* the 'start' endpoint may not recieve zero data. this is also handy cos its used for the status updates */ return XBEE_ENONE; } address->endpoints_enabled = 1; address->endpoint_local = buf->data[1]; address->endpoint_remote = buf->data[1]; if ((ret = xbee_pktAlloc(&iPkt, NULL, buf->len - pos)) != XBEE_ENONE) return ret; iPkt->frameId = buf->data[2]; iPkt->dataLen = buf->len - pos; if (iPkt->dataLen > 0) { memcpy(iPkt->data, &(buf->data[pos]), iPkt->dataLen); } iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_net_frontchannel_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { /* see the counterpart Tx function net_handlers.c - xbee_netServer_fc_tx_func() */ struct xbee_pkt *iPkt; xbee_err ret; int pos, required; int dataLen; /* required = identifier + conIdentifier(2) + address flags + timestamp(8) + status + options + rssi + frameId */ required = 16; if (!xbee || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (buf->len < required) return XBEE_ELENGTH; /* buf->data[0] is identifier buf->data[1] is (conIdentifier >> 8) & 0xFF buf->data[2] is conIdentifier & 0xFF */ pos = 3; /* the following data should match the format found in net_callbacks.c - xbee_net_toClient() */ address->addr16_enabled = !!(buf->data[pos] & 0x01); address->addr64_enabled = !!(buf->data[pos] & 0x02); address->endpoints_enabled = !!(buf->data[pos] & 0x04); address->profile_enabled = !!(buf->data[pos] & 0x08); address->cluster_enabled = !!(buf->data[pos] & 0x10); pos++; if (address->addr16_enabled) required += 2; if (address->addr64_enabled) required += 8; if (address->endpoints_enabled) required += 2; if (address->profile_enabled) required += 2; if (address->cluster_enabled) required += 2; /* and the AT command */ required += 2; if (buf->len < required) { return XBEE_ELENGTH; } dataLen = buf->len - required; if ((ret = xbee_pktAlloc(&iPkt, NULL, dataLen)) != XBEE_ENONE) return ret; iPkt->dataLen = dataLen; iPkt->timestamp.tv_sec = (buf->data[pos] << 24); pos++; iPkt->timestamp.tv_sec |= (buf->data[pos] << 16); pos++; iPkt->timestamp.tv_sec |= (buf->data[pos] << 8); pos++; iPkt->timestamp.tv_sec |= (buf->data[pos] ); pos++; iPkt->timestamp.tv_sec &= 0xFFFFFFFF; iPkt->timestamp.tv_nsec = (buf->data[pos] << 24); pos++; iPkt->timestamp.tv_nsec |= (buf->data[pos] << 16); pos++; iPkt->timestamp.tv_nsec |= (buf->data[pos] << 8); pos++; iPkt->timestamp.tv_nsec |= (buf->data[pos] ); pos++; iPkt->timestamp.tv_nsec &= 0xFFFFFFFF; iPkt->status = buf->data[pos]; pos++; iPkt->options = buf->data[pos]; pos++; iPkt->rssi = buf->data[pos]; pos++; iPkt->frameId = buf->data[pos]; pos++; /* -- */ if (address->addr16_enabled) { address->addr16[0] = buf->data[pos]; pos++; address->addr16[1] = buf->data[pos]; pos++; } if (address->addr64_enabled) { address->addr64[0] = buf->data[pos]; pos++; address->addr64[1] = buf->data[pos]; pos++; address->addr64[2] = buf->data[pos]; pos++; address->addr64[3] = buf->data[pos]; pos++; address->addr64[4] = buf->data[pos]; pos++; address->addr64[5] = buf->data[pos]; pos++; address->addr64[6] = buf->data[pos]; pos++; address->addr64[7] = buf->data[pos]; pos++; } if (address->endpoints_enabled) { address->endpoint_local = buf->data[pos]; pos++; address->endpoint_remote = buf->data[pos]; pos++; } if (address->profile_enabled) { address->profile_id = ((buf->data[pos] << 8) & 0xFF00); pos++; address->profile_id |= ((buf->data[pos]) & 0xFF); pos++; } if (address->cluster_enabled) { address->cluster_id = ((buf->data[pos] << 8) & 0xFF00); pos++; address->cluster_id |= ((buf->data[pos]) & 0xFF); pos++; } iPkt->atCommand[0] = buf->data[pos]; pos++; iPkt->atCommand[1] = buf->data[pos]; pos++; if (iPkt->dataLen > 0) { memcpy(iPkt->data, &buf->data[pos], iPkt->dataLen); pos += iPkt->dataLen; } *pkt = iPkt; return XBEE_ENONE; }
xbee_err xbee_sZB_identify_rx_func(struct xbee *xbee, void *arg, unsigned char identifier, struct xbee_tbuf *buf, struct xbee_frameInfo *frameInfo, struct xbee_conAddress *address, struct xbee_pkt **pkt) { struct xbee_pkt *iPkt; xbee_err ret; struct xbee_conAddress *addr; if (!xbee || !frameInfo || !buf || !address || !pkt) return XBEE_EMISSINGPARAM; if (buf->len < 30) return XBEE_ELENGTH; if ((ret = xbee_pktAlloc(&iPkt, NULL, buf->len - 12)) != XBEE_ENONE) return ret; iPkt->options = buf->data[11]; iPkt->dataLen = buf->len - 12; if (iPkt->dataLen > 0) { const int NIstart = 10; int NIend; memcpy(iPkt->data, &(buf->data[12]), iPkt->dataLen); if (iPkt->dataLen < 2) goto done; xbee_pktDataAdd(iPkt, "Address (16-bit)", 0, &(iPkt->data[0]), NULL); if (iPkt->dataLen < 10) goto done; xbee_pktDataAdd(iPkt, "Address (64-bit)", 0, &(iPkt->data[2]), NULL); if ((addr = malloc(sizeof(*addr))) != NULL) { memset(addr, 0, sizeof(*addr)); addr->addr16_enabled = 1; memcpy(addr->addr16, &(iPkt->data[0]), 2); addr->addr64_enabled = 1; memcpy(addr->addr64, &(iPkt->data[2]), 8); if (xbee_pktDataAdd(iPkt, "Address", 0, addr, free) != XBEE_ENONE) { free(addr); } } if (iPkt->dataLen < 11) goto done; /* just point into the packet data */ xbee_pktDataAdd(iPkt, "NI", 0, &(iPkt->data[NIstart]), NULL); for (NIend = NIstart; iPkt->data[NIend] != '\0' && NIend < iPkt->dataLen; NIend++); NIend++; /* step over the nul */ if (iPkt->dataLen < NIend + 2) goto done; xbee_pktDataAdd(iPkt, "Parent Address", 0, &(iPkt->data[NIend]), NULL); if (iPkt->dataLen < NIend + 3) goto done; xbee_pktDataAdd(iPkt, "Device Type", 0, &(iPkt->data[NIend + 2]), NULL); if (iPkt->dataLen < NIend + 4) goto done; xbee_pktDataAdd(iPkt, "Source Event", 0, &(iPkt->data[NIend + 3]), NULL); if (iPkt->dataLen < NIend + 6) goto done; xbee_pktDataAdd(iPkt, "Profile ID", 0, &(iPkt->data[NIend + 4]), NULL); if (iPkt->dataLen < NIend + 8) goto done; xbee_pktDataAdd(iPkt, "Manufacturer ID", 0, &(iPkt->data[NIend + 6]), NULL); } done: iPkt->data[iPkt->dataLen] = '\0'; *pkt = iPkt; return XBEE_ENONE; }