コード例 #1
0
ファイル: ota.c プロジェクト: camilorodegheri/fluent-bit
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;
}
コード例 #2
0
ファイル: mode.c プロジェクト: OpenISDM/Lbeacon-zigbee
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;
}
コード例 #3
0
ファイル: sensor.c プロジェクト: OpenISDM/Lbeacon-zigbee
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;
}
コード例 #4
0
ファイル: dataExp.c プロジェクト: bensmith28/EagleEye
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;
}
コード例 #5
0
ファイル: net_handlers.c プロジェクト: bensmith28/EagleEye
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;
}
コード例 #6
0
ファイル: net_handlers.c プロジェクト: C24IO/libxbee3
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;
}
コード例 #7
0
ファイル: dataExp.c プロジェクト: attie/libxbee3
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;
}
コード例 #8
0
ファイル: data.c プロジェクト: OpenISDM/Lbeacon-zigbee
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;
}
コード例 #9
0
ファイル: io.c プロジェクト: OpenISDM/Lbeacon-zigbee
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;
}
コード例 #10
0
ファイル: at.c プロジェクト: OpenISDM/Lbeacon-zigbee
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;
}
コード例 #11
0
ファイル: identify.c プロジェクト: C24IO/libxbee3
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;
}
コード例 #12
0
ファイル: mode.c プロジェクト: OpenISDM/Lbeacon-zigbee
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;
}
コード例 #13
0
ファイル: net_handlers.c プロジェクト: bensmith28/EagleEye
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;
}
コード例 #14
0
ファイル: handlers.c プロジェクト: OpenISDM/Lbeacon-zigbee
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;
}
コード例 #15
0
ファイル: identify.c プロジェクト: OpenISDM/Lbeacon-zigbee
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;
}