From: Olivier Matz Date: Thu, 7 Nov 2013 19:33:25 +0000 (+0100) Subject: xbee: add a new module X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=4dc5fba2e8aba8e89445fb532f9969a57e24b99c;p=aversive.git xbee: add a new module Signed-off-by: Olivier Matz --- diff --git a/config/Configure.help b/config/Configure.help index d4da4fa..63b9bca 100644 --- a/config/Configure.help +++ b/config/Configure.help @@ -193,6 +193,16 @@ CONFIG_MODULE_CC2420 in wireless sensors. This modules requires SPI to be activated. +CONFIG_MODULE_XBEE + This modules implements the protocol to use a xbee radio chip. + It currently only supports xbee868. + +CONFIG_MODULE_XBEE_STATS + Enable xbee statistics (takes ~100 bytes per device). + +CONFIG_MODULE_XBEE_ATCMD_HELP + Embed help strings of AT commands in program memory. + CONFIG_MODULE_MENU The menu module provides some helpers to create a human-machine interface that uses a tree-organized static menu. diff --git a/config/config.in b/config/config.in index 0e0d83d..8c479c0 100644 --- a/config/config.in +++ b/config/config.in @@ -435,6 +435,14 @@ dep_bool 'CC2420 Radio Device (IEEE 802.15.4) (VERY EXPERIMENTAL)' CONFIG_MODULE dep_bool ' |-- Create Default CC2420 config' CONFIG_MODULE_CC2420_CREATE_CONFIG \ $CONFIG_MODULE_CC2420 +bool 'Xbee Device' CONFIG_MODULE_XBEE + +dep_bool ' |-- Enable xbee stats' CONFIG_MODULE_XBEE_STATS \ + $CONFIG_MODULE_XBEE + +dep_bool ' |-- Embed help strings in program memory' CONFIG_MODULE_XBEE_ATCMD_HELP \ + $CONFIG_MODULE_XBEE + endmenu # radio diff --git a/config/generate_aversive_config b/config/generate_aversive_config index df7d569..f034165 100755 --- a/config/generate_aversive_config +++ b/config/generate_aversive_config @@ -35,6 +35,7 @@ MODULES_LIST="CONFIG_MODULE_BRUSHLESS_3PHASE_DIGITAL_HALL,/devices/brushless_mot CONFIG_MODULE_SCHEDULER,base/scheduler CONFIG_MODULE_SPI,comm/spi CONFIG_MODULE_CC2420,devices/radio/cc2420 + CONFIG_MODULE_XBEE,devices/radio/xbee CONFIG_MODULE_UART,comm/uart CONFIG_MODULE_I2C,comm/i2c CONFIG_MODULE_MF2_CLIENT,comm/mf2_client diff --git a/modules/devices/radio/xbee/Makefile b/modules/devices/radio/xbee/Makefile new file mode 100644 index 0000000..0aa0391 --- /dev/null +++ b/modules/devices/radio/xbee/Makefile @@ -0,0 +1,14 @@ +#-include .config + +TARGET = xbee + +# List C source files here. (C dependencies are automatically generated.) +SRC = xbee.c +SRC += xbee_atcmd.c +SRC += xbee_neighbor.c +SRC += xbee_rxtx.c +SRC += xbee_stats.c + +########################################### + +include $(AVERSIVE_DIR)/mk/aversive_module.mk diff --git a/modules/devices/radio/xbee/xbee.c b/modules/devices/radio/xbee/xbee.c new file mode 100644 index 0000000..9072fdd --- /dev/null +++ b/modules/devices/radio/xbee/xbee.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "xbee_neighbor.h" +#include "xbee_stats.h" +#include "xbee_rxtx.h" +#include "xbee.h" + +int xbee_init(void) +{ + return 0; +} + +int xbee_register_channel(struct xbee_dev *dev, int channel, + xbee_rx_cb_t *rx_cb, void *opaque) +{ + /* user asked for any channel */ + if (channel == XBEE_CHANNEL_ANY) { + int ch; + + /* skip XBEE_DEFAULT_CHANNEL == 0 */ + for (ch = 1; ch < XBEE_MAX_CHANNEL; ch++) { + if (dev->channel[ch].registered == 0) { + channel = ch; + break; + } + } + /* no available channels */ + if (channel == XBEE_CHANNEL_ANY) + return -1; + } + /* user requested a specific channel */ + else if (channel < 0 || channel >= XBEE_MAX_CHANNEL || + dev->channel[channel].registered == 1) + return -1; /* not available */ + + dev->channel[channel].registered = 1; + dev->channel[channel].rx_cb = rx_cb; + dev->channel[channel].arg = opaque; + return channel; +} + +int xbee_unregister_channel(struct xbee_dev *dev, int channel) +{ + if (channel < 0 || channel >= XBEE_MAX_CHANNEL || + dev->channel[channel].registered == 0) + return -1; + dev->channel[channel].registered = 0; + dev->channel[channel].rx_cb = NULL; + dev->channel[channel].arg = NULL; + return 0; +} + +int xbee_set_opaque(struct xbee_dev *dev, int channel, void *opaque) +{ + if (channel < 0 || channel >= XBEE_MAX_CHANNEL || + dev->channel[channel].registered == 0) + return -1; + + dev->channel[channel].arg = opaque; + return 0; +} + +int xbee_open(struct xbee_dev *dev, FILE *xbee_file) +{ + memset(dev, 0, sizeof(*dev)); + dev->file = xbee_file; + xbee_neigh_init(dev); + return 0; +} diff --git a/modules/devices/radio/xbee/xbee.h b/modules/devices/radio/xbee/xbee.h new file mode 100644 index 0000000..87d72ef --- /dev/null +++ b/modules/devices/radio/xbee/xbee.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2011, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _XBEE_H_ +#define _XBEE_H_ + +#include "xbee_neighbor.h" +#include "xbee_atcmd.h" +#include "xbee_stats.h" +#include "xbee_rxtx.h" + +/* Callback when receiving data on a specific channel. The arguments of the + * function are the xbee device, the channel ID, the type of the frame (example: + * XBEE_TYPE_ATRESP), the pointer to the frame, the length of the frame, and an + * opaque pointer (reserved for user). The given length exludes the xbee_hdr + * structure (delimiter, len, type, id) and the cksum. */ +typedef int8_t (xbee_rx_cb_t)(struct xbee_dev *dev, int channel, int type, + void *frame, unsigned len, void *opaque); + +/* an xbee queue */ +struct xbee_channel { + int registered; + xbee_rx_cb_t *rx_cb; + void *arg; +}; + +#define XBEE_DEFAULT_CHANNEL 0 +#define XBEE_MAX_CHANNEL 16 +#define XBEE_CHANNEL_ANY XBEE_MAX_CHANNEL + +/* structure identifying a xbee device */ +struct xbee_dev { + FILE *file; + struct xbee_channel channel[XBEE_MAX_CHANNEL]; + uint8_t frame_len; + char frame[XBEE_MAX_FRAME_LEN]; + struct xbee_neigh_list neigh_list; +#ifdef CONFIG_MODULE_XBEE_STATS + struct xbee_stats stats; +#endif +}; + +/* initialize xbee library */ +int xbee_init(void); + +/* open an xbee device */ +int xbee_open(struct xbee_dev *dev, FILE *xbee_file); + +/* closes an xbee device */ +int xbee_close(struct xbee_dev *dev); + +/* Register a channel, return the ID of the channel or a negative + * value on error. The rx_cb is a pointer to a function that will be + * called by xbee_read() when a frame is received for this channel. If + * rx_cb is NULL, no callback will occur. The "channel" argument can + * be XBEE_CHANNEL_ANY to let the library choose the channel, or a + * channel number to request a specific one. */ +int xbee_register_channel(struct xbee_dev *dev, int channel, + xbee_rx_cb_t *rx_cb, void *opaque); + +/* This function (re)sets the opaque pointer on a registered + * channel. The function returns 0 on success and -1 on error (channel + * not registered). As the opaque pointer can already be set after a + * call to xbee_register_channel(), this function is only useful if + * the opaque pointer has to be modified. */ +int xbee_set_opaque(struct xbee_dev *dev, int channel, void *opaque); + +/* Unregister a channel, return 0 on success */ +int xbee_unregister_channel(struct xbee_dev *dev, int channel_id); + +/* read data from device fd and put it in queue */ +int xbee_read(struct xbee_dev *dev); + +/* process all data in queue */ +int xbee_process_queue(struct xbee_dev *dev); + +#endif /* _XBEE_H_ */ diff --git a/modules/devices/radio/xbee/xbee_atcmd.c b/modules/devices/radio/xbee/xbee_atcmd.c new file mode 100644 index 0000000..f77ecfe --- /dev/null +++ b/modules/devices/radio/xbee/xbee_atcmd.c @@ -0,0 +1,1490 @@ +/* + * Copyright (c) 2011, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include +#include +#include + +#include "xbee_atcmd.h" + +static const char PROGMEM atcmd0_name[] = "WR"; +static const char PROGMEM atcmd0_desc[] = "write-param"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd0_help[] = + "Write parameter values to non-volatile memory."; +#endif + +static const char PROGMEM atcmd1_name[] = "RE"; +static const char PROGMEM atcmd1_desc[] = "restore-defaults"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd1_help[] = + "Restore module parameters to factory defaults."; +#endif + +static const char PROGMEM atcmd2_name[] = "FR"; +static const char PROGMEM atcmd2_desc[] = "soft-reset"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd2_help[] = + "Software Reset. Responds with 'OK' then performs a " + "reset 100ms later."; +#endif + +static const char PROGMEM atcmd3_name[] = "AC"; +static const char PROGMEM atcmd3_desc[] = "apply-changes"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd3_help[] = + "Apply Changes without exiting command mode."; +#endif + +static const char PROGMEM atcmd4_name[] = "R1"; +static const char PROGMEM atcmd4_desc[] = "restore-compiled"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd4_help[] = + "Restore module parameters to compiled defaults."; +#endif + +static const char PROGMEM atcmd5_name[] = "VL"; +static const char PROGMEM atcmd5_desc[] = "version-long"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd5_help[] = + "Shows detailed version information including" + "application build date and time."; +#endif + +static const char PROGMEM atcmd6_name[] = "DH"; +static const char PROGMEM atcmd6_desc[] = "dst-addr-high"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd6_help[] = + "Upper 32 bits of the 64-bit destination address (0 " + "to 0xFFFFFFFF, default is 0x0000FFFF)."; +#endif + +static const char PROGMEM atcmd7_name[] = "DL"; +static const char PROGMEM atcmd7_desc[] = "dst-addr-low"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd7_help[] = + "Lower 32 bits of the 64-bit destination address (0 " + "to 0xFFFFFFFF, default is 0x0000FFFF)."; +#endif + +static const char PROGMEM atcmd8_name[] = "DD"; +static const char PROGMEM atcmd8_desc[] = "device-type-id"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd8_help[] = + "Device Type Identifier, it can be used to differentiate " + "multiple XBee-based products (0 to 0xFFFFFFFF, read-only, " + "default is 0x40000)."; +#endif + +static const char PROGMEM atcmd9_name[] = "SH"; +static const char PROGMEM atcmd9_desc[] = "src-addr-high"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd9_help[] = + "Upper 32 bits of the 64-bit source address (read-only)."; +#endif + +static const char PROGMEM atcmd10_name[] = "SL"; +static const char PROGMEM atcmd10_desc[] = "src-addr-low"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd10_help[] = + "Lower 32 bits of the 64-bit source address (read-only)."; +#endif + +static const char PROGMEM atcmd11_name[] = "SE"; +static const char PROGMEM atcmd11_desc[] = "src-endpoint"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd11_help[] = + "The application source endpoint for all data transmissions " + "(0 to 0xFF, default is 0xE8)."; +#endif + +static const char PROGMEM atcmd12_name[] = "DE"; +static const char PROGMEM atcmd12_desc[] = "dst-endpoint"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd12_help[] = + "The application destination endpoint for all data " + "transmissions (0 to 0xFF, default is 0xE8)."; +#endif + +static const char PROGMEM atcmd13_name[] = "CI"; +static const char PROGMEM atcmd13_desc[] = "cluster-id"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd13_help[] = + "Cluster Identifier for all data transmissions (0 to 0xFFFF, " + "default is 0x11)."; +#endif + +static const char PROGMEM atcmd14_name[] = "NP"; +static const char PROGMEM atcmd14_desc[] = "max-rf-payload"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd14_help[] = + "Maximum RF Payload Bytes that can be sent in a unicast " + "transmission based on the current configuration (0 to " + "0xFFFF)."; +#endif + +static const char PROGMEM atcmd15_name[] = "CE"; +static const char PROGMEM atcmd15_desc[] = "coord-end-device"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd15_help[] = + "Coordinator/End Device, messaging mode of the module " + "(0 - Normal, 1 - Indirect coordinator, 2 - Polling, default " + "is 0)."; +#endif + +static const char PROGMEM atcmd16_name[] = "AP"; +static const char PROGMEM atcmd16_desc[] = "api-mode"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd16_help[] = + "API mode (0 - off, 1 - on, 2 - on with escape sequences)."; +#endif + +static const char PROGMEM atcmd17_name[] = "AO"; +static const char PROGMEM atcmd17_desc[] = "api-output-format"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd17_help[] = + "API Output Format (0 - standard [0x90 for RX], 1 - explicit " + "addressing [0x91 for RX])."; +#endif + +static const char PROGMEM atcmd18_name[] = "BD"; +static const char PROGMEM atcmd18_desc[] = "baud-rate"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd18_help[] = + "Baud rate of serial interface (0-8 select preset standard " + "rates, and 0x39 to 0x1c9c38 select baud rate)."; +#endif + +static const char PROGMEM atcmd19_name[] = "RO"; +static const char PROGMEM atcmd19_desc[] = "packetization-timeout"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd19_help[] = + "Packetization Timeout: the inter-character silence required " + "before packetization specified in character times (0 to 0xFF, " + "default is 3)."; +#endif + +static const char PROGMEM atcmd20_name[] = "FT"; +static const char PROGMEM atcmd20_desc[] = "flow-control-thres"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd20_help[] = + "Flow Control Threshhold. De-assert CTS and/or send XOFF when " + "FT bytes are in the UART receive buffer. Re-assert CTS when " + "less than FT - 16 bytes are in the UART receive buffer (0x11 " + "to 0xEE, default is 0xBE)."; +#endif + +static const char PROGMEM atcmd21_name[] = "NB"; +static const char PROGMEM atcmd21_desc[] = "parity"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd21_help[] = + "Parity (0 - no parity, 1 - even parity, 2 - odd parity, 3 - " + "forced high parity, 4 - forced low parity). Default is 0."; +#endif + +static const char PROGMEM atcmd22_name[] = "D7"; +static const char PROGMEM atcmd22_desc[] = "dio7"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd22_help[] = + "DIO7 Configuration (0 - unmonitored input, 1 - CTS, 3 - " + "digital input, 4 - digital output low, 5 - digital output " + "high, 6 - RS-485 low Tx, 7 - RS-485 high Tx). Default is " + "0."; +#endif + +static const char PROGMEM atcmd23_name[] = "D6"; +static const char PROGMEM atcmd23_desc[] = "dio6"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd23_help[] = + "DIO6 Configuration (0 - unmonitored input, 1 - RTS, 3 - " + "digital input, 4 - digital output low, 5 - digital output " + "high). Default is 0."; +#endif + +static const char PROGMEM atcmd24_name[] = "P0"; +static const char PROGMEM atcmd24_desc[] = "dio10-pwm0"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd24_help[] = + "DIO10/PWM0 Configuration. (0 - unmonitored input, 1 - RSSI, 2 " + "- PWM0, 3 - digital input, 4 - digital output low, 5 - " + "digital output high). Default is 1."; +#endif + +static const char PROGMEM atcmd25_name[] = "P1"; +static const char PROGMEM atcmd25_desc[] = "dio11-pwm1"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd25_help[] = + "DIO11/PWM1 Configuration. (0 - unmonitored input, 2 " + "- PWM1, 3 - digital input, 4 - digital output low, 5 - " + "digital output high). Default is 0."; +#endif + +static const char PROGMEM atcmd26_name[] = "P2"; +static const char PROGMEM atcmd26_desc[] = "dio12"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd26_help[] = + "DIO12 Configuration. (0 - unmonitored input, " + "3 - digital input, 4 - digital output low, 5 - " + "digital output high). Default is 0."; +#endif + +static const char PROGMEM atcmd27_name[] = "RP"; +static const char PROGMEM atcmd27_desc[] = "rssi-pwm"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd27_help[] = + "Time RSSI signal will be output after last transmission. " + "When RP[] = 0xFF, output will always be on (0 - 0xFF, default " + "is 0x28[] = 4 seconds)."; +#endif + +static const char PROGMEM atcmd28_name[] = "1S"; +static const char PROGMEM atcmd28_desc[] = "sensor-sample"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd28_help[] = + "Forces a sample to be taken on an XBee Sensor device."; +#endif + +static const char PROGMEM atcmd29_name[] = "D0"; +static const char PROGMEM atcmd29_desc[] = "dio0-ad0"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd29_help[] = + "AD0/DIO0 Configuration. (0 - unmonitored input, 1 - " + "commission button enabled, 2 - analog input, 3 - digital " + "input, 4 - digital output low, 5 - digital output high). " + "Default is 1."; +#endif + +static const char PROGMEM atcmd30_name[] = "D1"; +static const char PROGMEM atcmd30_desc[] = "dio1-ad1"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd30_help[] = + "AD1/DIO1 Configuration. (0 - unmonitored input, " + "2 - analog input, 3 - digital input, 4 - digital output " + "low, 5 - digital output high). Default is 0."; +#endif + +static const char PROGMEM atcmd31_name[] = "D2"; +static const char PROGMEM atcmd31_desc[] = "dio2-ad2"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd31_help[] = + "AD2/DIO2 Configuration. (0 - unmonitored input, " + "2 - analog input, 3 - digital input, 4 - digital output " + "low, 5 - digital output high). Default is 0."; +#endif + +static const char PROGMEM atcmd32_name[] = "D3"; +static const char PROGMEM atcmd32_desc[] = "dio3-ad3"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd32_help[] = + "AD3/DIO3 Configuration. (0 - unmonitored input, " + "2 - analog input, 3 - digital input, 4 - digital output " + "low, 5 - digital output high). Default is 0."; +#endif + +static const char PROGMEM atcmd33_name[] = "D4"; +static const char PROGMEM atcmd33_desc[] = "dio4-ad4"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd33_help[] = + "AD4/DIO4 Configuration. (0 - unmonitored input, " + "2 - analog input, 3 - digital input, 4 - digital output " + "low, 5 - digital output high). Default is 0."; +#endif + +static const char PROGMEM atcmd34_name[] = "D5"; +static const char PROGMEM atcmd34_desc[] = "dio5-ad5"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd34_help[] = + "AD4/DIO4 Configuration. (0 - unmonitored input, 1 - LED, " + "2 - analog input, 3 - digital input, 4 - digital output " + "low, 5 - digital output high). Default is 1."; +#endif + +static const char PROGMEM atcmd35_name[] = "D8"; +static const char PROGMEM atcmd35_desc[] = "dio8-sleep-rq"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd35_help[] = + "DIO8/SLEEP_RQ Configuration. (0 - unmonitored input, 1 - LED, " + "2 - analog input, 3 - digital input, 4 - digital output " + "low, 5 - digital output high). Default is 0. When used as " + "SLEEP_RQ, the D8 parameter should be configured in mode 0 " + "or 3."; +#endif + +static const char PROGMEM atcmd36_name[] = "D9"; +static const char PROGMEM atcmd36_desc[] = "dio9-on-sleep"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd36_help[] = + "DIO9/ON_SLEEP Configuration. (0 - unmonitored input, 1 - " + "ON/SLEEP, 2 - analog input, 3 - digital input, 4 - digital " + "output low, 5 - digital output high). Default is ?."; +#endif + +static const char PROGMEM atcmd37_name[] = "PR"; +static const char PROGMEM atcmd37_desc[] = "pull-up-resistor"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd37_help[] = + "Pull-up Resistor. Bit field that configures the internal " + "pull-up resistors for the I/O lines (bit set = pull-up " + "enabled). Range is from 0 to 0x1FFF, default is 0x1FFF."; +#endif + +static const char PROGMEM atcmd38_name[] = "M0"; +static const char PROGMEM atcmd38_desc[] = "pwm0-out-level"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd38_help[] = + "PWM0 Output Level. The line should be configured as a PWM " + "output using the P0 command (0 to 0x3FF, default is 0)."; +#endif + +static const char PROGMEM atcmd39_name[] = "M1"; +static const char PROGMEM atcmd39_desc[] = "pwm1-out-level"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd39_help[] = + "PWM1 Output Level. The line should be configured as a PWM " + "output using the P1 command (0 to 0x3FF, default is 0)."; +#endif + +static const char PROGMEM atcmd40_name[] = "LT"; +static const char PROGMEM atcmd40_desc[] = "led-blink-time"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd40_help[] = + "Associate LED Blink Time (should be enabled through D5 "; +#endif + +static const char PROGMEM atcmd41_name[] = "IS"; +static const char PROGMEM atcmd41_desc[] = "force-sample"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd41_help[] = + "Forces a read of all enabled digital and " + "analog input lines."; +#endif + +static const char PROGMEM atcmd42_name[] = "IC"; +static const char PROGMEM atcmd42_desc[] = "digital-change-detect"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd42_help[] = + "I/O Digital Change Detection. If a pin is enabled as a " + "digital input/output, the IC command can be used to " + "force an immediate I/O sample transmission when the DIO " + "state changes. IC is a bitmask, range is 0 to 0xFFFF, " + "default is 0"; +#endif + +static const char PROGMEM atcmd43_name[] = "IR"; +static const char PROGMEM atcmd43_desc[] = "io-sample-rate"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd43_help[] = + "IO Sample Rate for periodic sampling. If zero, periodic " + "sampling is disabled. Else the value is in milliseconds " + "(range 0 to 0xFFFF, default is 0)."; +#endif + +static const char PROGMEM atcmd44_name[] = "CB"; +static const char PROGMEM atcmd44_desc[] = "comissioning-button"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd44_help[] = + "Commissioning Pushbutton, simulate commissioning button " + "in software. The parameter value should be set to the number " + "of button presses to be simulated (range is 0 to 4)."; +#endif + +static const char PROGMEM atcmd45_name[] = "VR"; +static const char PROGMEM atcmd45_desc[] = "firmware-version"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd45_help[] = + "Firmware version of the module (read only)."; +#endif + +static const char PROGMEM atcmd46_name[] = "HV"; +static const char PROGMEM atcmd46_desc[] = "hardware-version"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd46_help[] = + "Hardware version of the module (read only)."; +#endif + +static const char PROGMEM atcmd47_name[] = "CK"; +static const char PROGMEM atcmd47_desc[] = "config-code"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd47_help[] = + "Configuration Code, that can be used as a quick " + "check to determine if a node has been configured as " + "desired (read-only, 0-0xFFFFFFFF)."; +#endif + +static const char PROGMEM atcmd48_name[] = "ER"; +static const char PROGMEM atcmd48_desc[] = "rf-errors"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd48_help[] = + "Number of times a packet was received which contained errors " + "of some sort. Read-only, saturate at 0xFFFF."; +#endif + +static const char PROGMEM atcmd49_name[] = "GD"; +static const char PROGMEM atcmd49_desc[] = "good-packets"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd49_help[] = + "Number of good received frames. Read-only, saturate at " + "0xFFFF."; +#endif + +static const char PROGMEM atcmd50_name[] = "RP"; +static const char PROGMEM atcmd50_desc[] = "rssi-pwm-timer"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd50_help[] = + "RSSI PWM timer, the time in tenth of seconds that the RSSI " + "output indicating signal strength will remain active after " + "the last reception (1 to 0xff, default is 0x20 = 3.2 secs)."; +#endif + +static const char PROGMEM atcmd51_name[] = "TR"; +static const char PROGMEM atcmd51_desc[] = "tx-errors"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd51_help[] = + "Transmission Errors, the number of MAC frames that " + "exhaust MAC retries without ever receiving a MAC " + "acknowledgement message. Read-only, saturate at 0xFFFF."; +#endif + +static const char PROGMEM atcmd52_name[] = "TP"; +static const char PROGMEM atcmd52_desc[] = "temperature"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd52_help[] = + "Temperature. Read module temperature in (tenths of ?) " + "Celsius. Negatives temperatures can be returned (read-only, " + "from 0xff74 [-140] to 0x0258 [600])."; +#endif + +static const char PROGMEM atcmd53_name[] = "DB"; +static const char PROGMEM atcmd53_desc[] = "rx-signal-strength"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd53_help[] = + "Received Signal Strength of the last received RF data " + "packet measured in -dBm. For example if DB returns 0x60, " + "then the RSSI of the last packet received was -96dBm " + "(read-only)."; +#endif + +static const char PROGMEM atcmd54_name[] = "DC"; +static const char PROGMEM atcmd54_desc[] = "duty-cycle"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd54_help[] = + "Duty Cycle. Returns a current usage percentage of the " + "10% duty cycle measured over the period of 1 hour " + "(read-only, from 0 to 0x64)."; +#endif + +static const char PROGMEM atcmd55_name[] = "RC"; +static const char PROGMEM atcmd55_desc[] = "rssi-for-channel"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd55_help[] = + "Reads the dBm level (RSSI) of the designated " + "channel."; +#endif + +static const char PROGMEM atcmd56_name[] = "R#"; +static const char PROGMEM atcmd56_desc[] = "reset-number"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd56_help[] = + "Tells the reason for the last module reset (0 - Power up " + "reset, 2 - Watchdog reset, 3 - Software reset, 4 - Reset " + "line reset, 5 - Brownout reset). Read-only."; +#endif + +static const char PROGMEM atcmd57_name[] = "TA"; +static const char PROGMEM atcmd57_desc[] = "tx-ack-errors"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd57_help[] = + "Transmit Acknowlegement Errors. Incremented once for " + "each failed ack retry (read-only, from 0 to 0xFFFF)."; +#endif + +static const char PROGMEM atcmd58_name[] = "%V"; +static const char PROGMEM atcmd58_desc[] = "supply-voltage"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd58_help[] = + "Voltage on the Vcc pin in mV (read-only, from 0 to 0xF00)."; +#endif + +static const char PROGMEM atcmd59_name[] = "CT"; +static const char PROGMEM atcmd59_desc[] = "cmd-mode-timeout"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd59_help[] = + "Command Mode Timeout: the period of inactivity (no valid " + "commands received) after which the RF module automatically " + "exits AT Command Mode and returns to Idle Mode (2 to 0x1770, " + "default is 0x64)."; +#endif + +static const char PROGMEM atcmd60_name[] = "CN"; +static const char PROGMEM atcmd60_desc[] = "exit-cmd-mode"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd60_help[] = + "Exit Command Mode."; +#endif + +static const char PROGMEM atcmd61_name[] = "GT"; +static const char PROGMEM atcmd61_desc[] = "guard-times"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd61_help[] = + "Guard Times: period of silence in ms before and after the " + "Command Sequence Characters of the AT Command Mode Sequence, " + "used to prevent inadvertent entrance into AT Command Mode " + "(0 to 0xFFFF, default is 0x3E8)."; +#endif + +static const char PROGMEM atcmd62_name[] = "CC"; +static const char PROGMEM atcmd62_desc[] = "command-chars"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd62_help[] = + "Command Character used between guard times of the AT Command " + "Mode Sequence (0 to 0xFF, default is 0x2B)."; +#endif + +static const char PROGMEM atcmd63_name[] = "ID"; +static const char PROGMEM atcmd63_desc[] = "network-id"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd63_help[] = + "Network ID. Nodes must have the same network identifier " + "to communicate (0 to 0x7FFF, default is 0x7FFF)."; +#endif + +static const char PROGMEM atcmd64_name[] = "NT"; +static const char PROGMEM atcmd64_desc[] = "ndisc-timeout"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd64_help[] = + "Node Discover Timeout, time in tenth of secs a node will " + "spend discovering other nodes when ND or DN is issued (0 " + "to 0xFC, default is 0x82)."; +#endif + +static const char PROGMEM atcmd65_name[] = "NI"; +static const char PROGMEM atcmd65_desc[] = "node-id"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd65_help[] = + "Node Identifier in printable ASCII characters. This string is " + "returned as part of the ATND (Network Discover) command. This " + "identifier is also used with the ATDN (Destination Node) " + "command. The string contains up to 20 byte ASCII string, " + "default is a space character."; +#endif + +static const char PROGMEM atcmd66_name[] = "DN"; +static const char PROGMEM atcmd66_desc[] = "disc-node"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd66_help[] = /* XXX */ + "Resolves a Node Identifier string to a physical address " + "(case sensitive). 0xFFFE and the 64bits extended address are " + "returned."; +#endif + +static const char PROGMEM atcmd67_name[] = "ND"; +static const char PROGMEM atcmd67_desc[] = "network-discover"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd67_help[] = "Network Discovery, see doc"; /* XXX */ +#endif + +static const char PROGMEM atcmd68_name[] = "NO"; +static const char PROGMEM atcmd68_desc[] = "ndisc-options"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd68_help[] = + "Network Discovery Options, a bitfield value that changes the " + "behavior of the ND command (bit0 - Append DD value, bit1 - " + "Local device sends ND response frame when ND is issued). " + "Default is 0."; +#endif + +static const char PROGMEM atcmd69_name[] = "EE"; +static const char PROGMEM atcmd69_desc[] = "security enable"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd69_help[] = + "Enable or disable 128-bit AES encryption (0 or 1, 0 is the " + "default)."; +#endif + +static const char PROGMEM atcmd70_name[] = "KY"; /* XXX */; +static const char PROGMEM atcmd70_desc[] = "security-key"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd70_help[] = + "The 128bits security key (the command is write-only)."; +#endif + +static const char PROGMEM atcmd71_name[] = "MT"; +static const char PROGMEM atcmd71_desc[] = "bcast-multi-xmit"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd71_help[] = + "Number of additional MAC-level broadcast transmissions. All " + "broadcast packets are transmitted MT+1 times to ensure " + "it is received (0 to 0xF, default is 3)."; +#endif + +static const char PROGMEM atcmd72_name[] = "RR"; +static const char PROGMEM atcmd72_desc[] = "unicast-retries"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd72_help[] = + "Number of additional MAC-level packet delivery attempts for " + "unicast transactions. If RR is non-zero, packets sent from " + "the radio will request an acknowledgement, and can be resent " + "up to RR times if no acknowledgement is received. (0 to 0xF, " + "default is 10)."; +#endif + +static const char PROGMEM atcmd73_name[] = "PL"; +static const char PROGMEM atcmd73_desc[] = "power-level"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd73_help[] = + "Power Level of RF transmitter (0 - 1mW, 1 - 23mW, 2 - 100mW, " + "3 - 158 mW, 4 - 316 mW). Default is 4."; +#endif + +static const char PROGMEM atcmd74_name[] = "SM"; +static const char PROGMEM atcmd74_desc[] = "sleep-mode"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd74_help[] = + "Sleep Mode (0 - disabled, 1 - pin sleep, 4 - async cyclic " + "sleep, 5 - async cyclic sleep with pin wakeup). Default " + "is 0."; +#endif + +static const char PROGMEM atcmd75_name[] = "SO"; +static const char PROGMEM atcmd75_desc[] = "sleep-options"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd75_help[] = + "Sleep Options bitmask (bit8 - always wake for ST time). " + "Default is 0."; +#endif + +static const char PROGMEM atcmd76_name[] = "ST"; +static const char PROGMEM atcmd76_desc[] = "wake-time"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd76_help[] = + "Wake Time: the amount of time in ms that the module will stay " + "awake after receiving RF or serial data (from 0x45 to " + "0x36EE80, default is 0x7D0 = 2 secs)."; +#endif + +static const char PROGMEM atcmd77_name[] = "SP"; +static const char PROGMEM atcmd77_desc[] = "sleep-period"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd77_help[] = + "Sleep Period: the amount of time in 10ms unit the module will " + "sleep per cycle. For a node operating as an Indirect " + "Messaging Coordinator, this command defines the amount of " + "time that it will hold an indirect message for an end device. " + "The coordinator will hold the message for (2.5 * SP). Range " + "is from 1 to 1440000, default is 200 (2 secs)."; +#endif + +static const char PROGMEM atcmd78_name[] = "SN"; +static const char PROGMEM atcmd78_desc[] = "num-sleep-periods"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd78_help[] = + "Number of Sleep Periods that must elapse between assertions " + "of the ON_SLEEP line during the wake time of asynchronous " + "cyclic sleep (1 to 0xFFFF, default is 1)."; +#endif + +static const char PROGMEM atcmd79_name[] = "WH"; +static const char PROGMEM atcmd79_desc[] = "wake-host"; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP +static const char PROGMEM atcmd79_help[] = "Wake Host time. If it is set to a non-zero value, it " + "specifies the time in ms that the device should allow after " + "waking from sleep before sending data out the UART or " + "transmitting an I/O sample. If serial characters are " + "received, the WH timer is stopped immediately. Range is " + "from 0 to 0xFFFF, default is 0."; +#endif + +const struct xbee_atcmd PROGMEM xbee_atcmd_list[] = { + { + /* "WR" */ + atcmd0_name, + atcmd0_desc, + XBEE_ATCMD_F_PARAM_NONE | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd0_help, +#endif + }, + { + /* "RE" */ + atcmd1_name, + atcmd1_desc, + XBEE_ATCMD_F_PARAM_NONE | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd1_help, +#endif + }, + { + /* "FR" */ + atcmd2_name, + atcmd2_desc, + XBEE_ATCMD_F_PARAM_NONE | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd2_help, +#endif + }, + { + /* "AC" */ + atcmd3_name, + atcmd3_desc, + XBEE_ATCMD_F_PARAM_NONE | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd3_help, +#endif + }, + { + /* "R1" */ + atcmd4_name, + atcmd4_desc, + XBEE_ATCMD_F_PARAM_NONE | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd4_help, +#endif + }, + { + /* "VL" */ + atcmd5_name, + atcmd5_desc, + XBEE_ATCMD_F_PARAM_NONE | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd5_help, +#endif + }, + { + /* "DH" */ + atcmd6_name, + atcmd6_desc, + XBEE_ATCMD_F_PARAM_U32 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd6_help, +#endif + }, + { + /* "DL" */ + atcmd7_name, + atcmd7_desc, + XBEE_ATCMD_F_PARAM_U32 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd7_help, +#endif + }, + { + /* "DD" */ + atcmd8_name, + atcmd8_desc, + XBEE_ATCMD_F_PARAM_U32 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd8_help, +#endif + }, + { + /* "SH" */ + atcmd9_name, + atcmd9_desc, + XBEE_ATCMD_F_PARAM_U32 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd9_help, +#endif + }, + { + /* "SL" */ + atcmd10_name, + atcmd10_desc, + XBEE_ATCMD_F_PARAM_U32 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd10_help, +#endif + }, + { + /* "SE" */ + atcmd11_name, + atcmd11_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd11_help, +#endif + }, + { + /* "DE" */ + atcmd12_name, + atcmd12_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd12_help, +#endif + }, + { + /* "CI" */ + atcmd13_name, + atcmd13_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd13_help, +#endif + }, + { + /* "NP" */ + atcmd14_name, + atcmd14_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd14_help, +#endif + }, + { + /* "CE" */ + atcmd15_name, + atcmd15_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd15_help, +#endif + }, + { + /* "AP" */ + atcmd16_name, + atcmd16_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd16_help, +#endif + }, + { + /* "AO" */ + atcmd17_name, + atcmd17_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd17_help, +#endif + }, + { + /* "BD" */ + atcmd18_name, + atcmd18_desc, + XBEE_ATCMD_F_PARAM_U32 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd18_help, +#endif + }, + { + /* "RO" */ + atcmd19_name, + atcmd19_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd19_help, +#endif + }, + { + /* "FT" */ + atcmd20_name, + atcmd20_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd20_help, +#endif + }, + { + /* "NB" */ + atcmd21_name, + atcmd21_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd21_help, +#endif + }, + { + /* "D7" */ + atcmd22_name, + atcmd22_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd22_help, +#endif + }, + { + /* "D6" */ + atcmd23_name, + atcmd23_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd23_help, +#endif + }, + { + /* "P0" */ + atcmd24_name, + atcmd24_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd24_help, +#endif + }, + { + /* "P1" */ + atcmd25_name, + atcmd25_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd25_help, +#endif + }, + { + /* "P2" */ + atcmd26_name, + atcmd26_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd26_help, +#endif + }, + { + /* "RP" */ + atcmd27_name, + atcmd27_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd27_help, +#endif + }, + { + /* "1S" */ + atcmd28_name, + atcmd28_desc, + XBEE_ATCMD_F_PARAM_NONE | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd28_help, +#endif + }, + { + /* "D0" */ + atcmd29_name, + atcmd29_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd29_help, +#endif + }, + { + /* "D1" */ + atcmd30_name, + atcmd30_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd30_help, +#endif + }, + { + /* "D2" */ + atcmd31_name, + atcmd31_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd31_help, +#endif + }, + { + /* "D3" */ + atcmd32_name, + atcmd32_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd32_help, +#endif + }, + { + /* "D4" */ + atcmd33_name, + atcmd33_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd33_help, +#endif + }, + { + /* "D5" */ + atcmd34_name, + atcmd34_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd34_help, +#endif + }, + { + /* "D8" */ + atcmd35_name, + atcmd35_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd35_help, +#endif + }, + { + /* "D9" */ + atcmd36_name, + atcmd36_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd36_help, +#endif + }, + { + /* "PR" */ + atcmd37_name, + atcmd37_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd37_help, +#endif + }, + { + /* "M0" */ + atcmd38_name, + atcmd38_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd38_help, +#endif + }, + { + /* "M1" */ + atcmd39_name, + atcmd39_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd39_help, +#endif + }, + { + /* "LT" */ + atcmd40_name, + atcmd40_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd40_help, +#endif + }, + { + /* "IS" */ + atcmd41_name, + atcmd41_desc, + XBEE_ATCMD_F_PARAM_NONE | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd41_help, +#endif + }, + { + /* "IC" */ + atcmd42_name, + atcmd42_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd42_help, +#endif + }, + { + /* "IR" */ + atcmd43_name, + atcmd43_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd43_help, +#endif + }, + { + /* "CB" */ + atcmd44_name, + atcmd44_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd44_help, +#endif + }, + { + /* "VR" */ + atcmd45_name, + atcmd45_desc, + XBEE_ATCMD_F_PARAM_U32 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd45_help, +#endif + }, + { + /* "HV" */ + atcmd46_name, + atcmd46_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd46_help, +#endif + }, + { + /* "CK" */ + atcmd47_name, + atcmd47_desc, + XBEE_ATCMD_F_PARAM_U32 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd47_help, +#endif + }, + { + /* "ER" */ + atcmd48_name, + atcmd48_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd48_help, +#endif + }, + { + /* "GD" */ + atcmd49_name, + atcmd49_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd49_help, +#endif + }, + { + /* "RP" */ + atcmd50_name, + atcmd50_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd50_help, +#endif + }, + { + /* "TR" */ + atcmd51_name, + atcmd51_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd51_help, +#endif + }, + { + /* "TP" */ + atcmd52_name, + atcmd52_desc, + XBEE_ATCMD_F_PARAM_S16 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd52_help, +#endif + }, + { + /* "DB" */ + atcmd53_name, + atcmd53_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd53_help, +#endif + }, + { + /* "DC" */ + atcmd54_name, + atcmd54_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd54_help, +#endif + }, + { + /* "RC" */ + atcmd55_name, + atcmd55_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd55_help, +#endif + }, + { + /* "R#" */ + atcmd56_name, + atcmd56_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd56_help, +#endif + }, + { + /* "TA" */ + atcmd57_name, + atcmd57_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd57_help, +#endif + }, + { + /* "%V" */ + atcmd58_name, + atcmd58_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd58_help, +#endif + }, + { + /* "CT" */ + atcmd59_name, + atcmd59_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd59_help, +#endif + }, + { + /* "CN" */ + atcmd60_name, + atcmd60_desc, + XBEE_ATCMD_F_PARAM_NONE | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd60_help, +#endif + }, + { + /* "GT" */ + atcmd61_name, + atcmd61_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd61_help, +#endif + }, + { + /* "CC" */ + atcmd62_name, + atcmd62_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd62_help, +#endif + }, + { + /* "ID" */ + atcmd63_name, + atcmd63_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd63_help, +#endif + }, + { + /* "NT" */ + atcmd64_name, + atcmd64_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd64_help, +#endif + }, + { + /* "NI" */ + atcmd65_name, + atcmd65_desc, + XBEE_ATCMD_F_PARAM_STRING_20B | XBEE_ATCMD_F_READ | + XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd65_help, +#endif + }, + { + /* "DN" */ + atcmd66_name, + atcmd66_desc, + XBEE_ATCMD_F_PARAM_STRING_20B | XBEE_ATCMD_F_READ | + XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd66_help, +#endif + }, + { + /* "ND" */ + atcmd67_name, + atcmd67_desc, + XBEE_ATCMD_F_PARAM_NONE | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd67_help, +#endif + }, + { + /* "NO" */ + atcmd68_name, + atcmd68_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd68_help, +#endif + }, + { + /* "EE" */ + atcmd69_name, + atcmd69_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd69_help, +#endif + }, + { + /* "KY" XXX */ + atcmd70_name, + atcmd70_desc, + XBEE_ATCMD_F_PARAM_HEXBUF_16B | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd70_help, +#endif + }, + { + /* "MT" */ + atcmd71_name, + atcmd71_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd71_help, +#endif + }, + { + /* "RR" */ + atcmd72_name, + atcmd72_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd72_help, +#endif + }, + { + /* "PL" */ + atcmd73_name, + atcmd73_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd73_help, +#endif + }, + { + /* "SM" */ + atcmd74_name, + atcmd74_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd74_help, +#endif + }, + { + /* "SO" */ + atcmd75_name, + atcmd75_desc, + XBEE_ATCMD_F_PARAM_U8 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd75_help, +#endif + }, + { + /* "ST" */ + atcmd76_name, + atcmd76_desc, + XBEE_ATCMD_F_PARAM_U32 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd76_help, +#endif + }, + { + /* "SP" */ + atcmd77_name, + atcmd77_desc, + XBEE_ATCMD_F_PARAM_U32 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd77_help, +#endif + }, + { + /* "SN" */ + atcmd78_name, + atcmd78_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd78_help, +#endif + }, + { + /* "WH" */ + atcmd79_name, + atcmd79_desc, + XBEE_ATCMD_F_PARAM_U16 | XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + atcmd79_help, +#endif + }, + { + NULL, + NULL, + 0, +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + NULL, +#endif + }, +}; + +const struct xbee_atcmd *xbee_atcmd_lookup_name(const char *atcmd_str) +{ + const struct xbee_atcmd *cmd; + struct xbee_atcmd copy; + + for (cmd = &xbee_atcmd_list[0], memcpy_P(©, cmd, sizeof(copy)); + copy.name != NULL; + cmd++, memcpy_P(©, cmd, sizeof(copy))) { + + if (!strcmp_P(atcmd_str, copy.name)) + break; + } + + if (copy.name == NULL) /* not found */ + return NULL; + + return cmd; +} + +const struct xbee_atcmd *xbee_atcmd_lookup_desc(const char *desc) +{ + const struct xbee_atcmd *cmd; + struct xbee_atcmd copy; + + for (cmd = &xbee_atcmd_list[0], memcpy_P(©, cmd, sizeof(copy)); + copy.name != NULL; + cmd++, memcpy_P(©, cmd, sizeof(copy))) { + if (!strcmp_P(desc, copy.desc)) + break; + } + if (copy.name == NULL) /* not found */ + return NULL; + + return cmd; +} diff --git a/modules/devices/radio/xbee/xbee_atcmd.h b/modules/devices/radio/xbee/xbee_atcmd.h new file mode 100644 index 0000000..0bde226 --- /dev/null +++ b/modules/devices/radio/xbee/xbee_atcmd.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _XBEE_ATCMD_H_ +#define _XBEE_ATCMD_H_ + +#define XBEE_ATCMD_F_READ 0x001 +#define XBEE_ATCMD_F_WRITE 0x002 +#define XBEE_ATCMD_F_PARAM_NONE 0x004 +#define XBEE_ATCMD_F_PARAM_U8 0x008 +#define XBEE_ATCMD_F_PARAM_U16 0x010 +#define XBEE_ATCMD_F_PARAM_S16 0x020 +#define XBEE_ATCMD_F_PARAM_U32 0x040 +#define XBEE_ATCMD_F_PARAM_STRING_20B 0x080 +#define XBEE_ATCMD_F_PARAM_HEXBUF_16B 0x100 + +/* list of xbee at commands */ +struct xbee_atcmd { + PGM_P name; + PGM_P desc; + unsigned int flags; +#ifdef CONFIG_MODULE_XBEE_ATCMD_HELP + PGM_P help; +#endif +}; + +extern const struct xbee_atcmd PROGMEM xbee_atcmd_list[]; + +const struct xbee_atcmd *xbee_atcmd_lookup_name(const char *atcmd_str); +const struct xbee_atcmd *xbee_atcmd_lookup_desc(const char *desc); + +#endif /* _xBEE_ATCMD_H_ */ diff --git a/modules/devices/radio/xbee/xbee_neighbor.c b/modules/devices/radio/xbee/xbee_neighbor.c new file mode 100644 index 0000000..46ea014 --- /dev/null +++ b/modules/devices/radio/xbee/xbee_neighbor.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2011, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "xbee_neighbor.h" +#include "xbee_atcmd.h" +#include "xbee_stats.h" +#include "xbee_rxtx.h" +#include "xbee.h" + +void xbee_neigh_init(struct xbee_dev *dev) +{ + LIST_INIT(&dev->neigh_list); +} + +struct xbee_neigh *xbee_neigh_lookup(struct xbee_dev *dev, const char *name) +{ + struct xbee_neigh *neigh; + + LIST_FOREACH(neigh, &dev->neigh_list, next) { + if (!strcmp(name, neigh->name)) + break; + } + + return neigh; +} + +struct xbee_neigh *xbee_neigh_rlookup(struct xbee_dev *dev, uint64_t addr) +{ + struct xbee_neigh *neigh; + + LIST_FOREACH(neigh, &dev->neigh_list, next) { + if (addr == neigh->addr) + break; + } + + return neigh; +} + +struct xbee_neigh *xbee_neigh_add(struct xbee_dev *dev, const char *name, + uint64_t addr) +{ + struct xbee_neigh *neigh; + + if (xbee_neigh_rlookup(dev, addr) != NULL) + return NULL; + + if (xbee_neigh_lookup(dev, name) != NULL) + return NULL; + + neigh = malloc(sizeof(*neigh)); + if (neigh == NULL) + return NULL; + + neigh->addr = addr; + snprintf_P(neigh->name, sizeof(neigh->name), PSTR("%s"), name); + LIST_INSERT_HEAD(&dev->neigh_list, neigh, next); + + return neigh; +} + +void xbee_neigh_del(struct xbee_dev *dev, struct xbee_neigh *neigh) +{ + dev = dev; /* silent compiler */ + LIST_REMOVE(neigh, next); + free(neigh); +} diff --git a/modules/devices/radio/xbee/xbee_neighbor.h b/modules/devices/radio/xbee/xbee_neighbor.h new file mode 100644 index 0000000..70d7585 --- /dev/null +++ b/modules/devices/radio/xbee/xbee_neighbor.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _XBEE_NEIGHBOR_H_ +#define _XBEE_NEIGHBOR_H_ + +#include + +struct xbee_neigh { + LIST_ENTRY(xbee_neigh) next; + char name[21]; + uint64_t addr; +}; + +struct xbee_dev; + +/* define struct xbee_neigh_list */ +LIST_HEAD(xbee_neigh_list, xbee_neigh); + +/* init neighbor list of an xbee device */ +void xbee_neigh_init(struct xbee_dev *dev); + +/* return a neighbor from its name */ +struct xbee_neigh *xbee_neigh_lookup(struct xbee_dev *dev, const char *name); + +/* return a neighbor from its address (in host order) */ +struct xbee_neigh *xbee_neigh_rlookup(struct xbee_dev *dev, uint64_t addr); + +/* add a neighbor */ +struct xbee_neigh *xbee_neigh_add(struct xbee_dev *dev, const char *name, + uint64_t addr); + +/* del a neighbor from list */ +void xbee_neigh_del(struct xbee_dev *dev, struct xbee_neigh *neigh); + +#endif /* _XBEE_NEIGHBOR_H_ */ diff --git a/modules/devices/radio/xbee/xbee_rxtx.c b/modules/devices/radio/xbee/xbee_rxtx.c new file mode 100644 index 0000000..88699a8 --- /dev/null +++ b/modules/devices/radio/xbee/xbee_rxtx.c @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2011, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "xbee_neighbor.h" +#include "xbee_stats.h" +#include "xbee_rxtx.h" +#include "xbee.h" + +/* Return -1 if the frame is invalid. The arguments buf and len correspond to + * the whole xbee frame, from delimiter to cksum. */ +static int xbee_parse_atresp(struct xbee_dev *dev, void *buf, unsigned len) +{ + struct xbee_atresp_hdr *atresp_hdr; + + dev->stats.rx_atresp++; + + if (len < sizeof(struct xbee_hdr) + sizeof(struct xbee_atresp_hdr)) { + dev->stats.rx_frame_too_small++; + return -1; + } + + atresp_hdr = buf + sizeof(struct xbee_hdr); + + /* bad status, but let the frame continue */ + if (atresp_hdr->status != 0) + dev->stats.rx_atresp_error++; + + return 0; +} + +/* Return -1 if the frame is invalid. The arguments buf and len correspond to + * the whole xbee frame, from delimiter to cksum. */ +static int xbee_parse_rmt_atresp(struct xbee_dev *dev, void *buf, unsigned len) +{ + struct xbee_rmt_atresp_hdr *rmt_atresp_hdr; + + dev->stats.rx_rmt_atresp++; + + if (len < sizeof(struct xbee_hdr) + sizeof(struct xbee_rmt_atresp_hdr)) { + dev->stats.rx_frame_too_small++; + return -1; + } + + rmt_atresp_hdr = buf + sizeof(struct xbee_hdr); + + /* bad status, but let the frame continue */ + if (rmt_atresp_hdr->status != 0) + dev->stats.rx_rmt_atresp_error++; + + return 0; +} + +/* Parse the reception of a "xmit status message". The arguments buf and len + * correspond to the whole xbee frame, from delimiter to cksum. Return -1 if the + * frame is invalid */ +static int xbee_parse_xmit_status(struct xbee_dev *dev, void *buf, unsigned len) +{ + struct xbee_xmit_status_hdr *xmit_status_hdr; + + dev->stats.rx_xmit_status++; + + if (len < sizeof(struct xbee_hdr) + sizeof(struct xbee_xmit_status_hdr)) { + dev->stats.rx_frame_too_small++; + return -1; + } + + xmit_status_hdr = buf + sizeof(struct xbee_hdr); + dev->stats.tx_xmit_retries += xmit_status_hdr->xmit_retry_cnt; + + /* bad status, but let the frame continue */ + if (xmit_status_hdr->delivery_status != 0) + dev->stats.rx_xmit_status_error++; + + return 0; +} + +/* parse the frame stored in the xbee_dev structure: return 0 if the frame is + * valid, else a negative value */ +static void xbee_parse_frame(struct xbee_dev *dev) +{ + void *buf = dev->frame; + uint8_t len = dev->frame_len; + uint8_t hdrlen; + struct xbee_hdr *hdr = buf; + int i; + uint8_t cksum = 0; + int channel = XBEE_DEFAULT_CHANNEL; + + 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 < (hdrlen + 1)) { + dev->stats.rx_frame_too_small++; + fprintf_P(stderr, PSTR("Frame too small\r\n")); + return; + } + + /* validate the cksum */ + for (i = 3; i < (len - 1); i++) + cksum += ((uint8_t *)buf)[i]; + cksum = 0xff - cksum; + if (cksum != ((uint8_t *)buf)[len-1]) { + fprintf_P(stderr, PSTR("Invalid cksum\r\n")); + dev->stats.rx_invalid_cksum++; + return; + } + + /* dispatch */ + switch (hdr->type) { + case XBEE_TYPE_MODEM_STATUS: + dev->stats.rx_modem_status++; + channel = XBEE_DEFAULT_CHANNEL; + break; + case XBEE_TYPE_ATRESP: + if (xbee_parse_atresp(dev, buf, len) < 0) + return; + channel = hdr->id; + break; + case XBEE_TYPE_RMT_ATRESP: + if (xbee_parse_rmt_atresp(dev, buf, len) < 0) + return; + channel = hdr->id; + break; + case XBEE_TYPE_XMIT_STATUS: + if (xbee_parse_xmit_status(dev, buf, len) < 0) + return; + channel = hdr->id; + break; + case XBEE_TYPE_RECV: + dev->stats.rx_data++; + channel = XBEE_DEFAULT_CHANNEL; + break; + case XBEE_TYPE_EXPL_RECV: + dev->stats.rx_expl_data++; + channel = XBEE_DEFAULT_CHANNEL; + break; + case XBEE_TYPE_NODE_ID: + dev->stats.rx_node_id++; + channel = hdr->id; //XXX + break; + /* invalid commands */ + case XBEE_TYPE_ATCMD: + case XBEE_TYPE_ATCMD_Q: + case XBEE_TYPE_XMIT: + case XBEE_TYPE_EXPL_XMIT: + case XBEE_TYPE_RMT_ATCMD: + default: + dev->stats.rx_invalid_type++; + break; + } + + /* fallback to default channel if not registered */ + if (channel < 0 || channel >= XBEE_MAX_CHANNEL || + dev->channel[channel].registered == 0) + channel = XBEE_DEFAULT_CHANNEL; + + /* execute the callback if any */ + if (dev->channel[channel].rx_cb == NULL) + return; + if (dev->channel[channel].rx_cb(dev, channel, hdr->type, + buf + hdrlen, + len - hdrlen - 1, + dev->channel[channel].arg) < 0) + dev->stats.rx_usr_error++; +} + +int xbee_tx_iovec(struct xbee_dev *dev, uint8_t channel_id, uint8_t type, + const struct xbee_msg *msg) +{ + struct xbee_hdr hdr; + unsigned i, j; + uint8_t cksum = 0; + unsigned len = 0; + + for (i = 0; i < msg->iovlen; i++) + len += msg->iov[i].len; + + /* prepare an iovec to avoid a copy: prepend a header to the + * buffer and append a checksum */ + hdr.delimiter = XBEE_DELIMITER; + hdr.len = htons(len + 2); + hdr.type = type; + hdr.id = channel_id; + + if (channel_id >= XBEE_MAX_CHANNEL || + dev->channel[channel_id].registered == 0) { + dev->stats.tx_invalid_channel ++; + return -1; + } + + /* calculate the cksum */ + cksum = hdr.type; + cksum += hdr.id; + for (i = 0; i < msg->iovlen; i++) { + for (j = 0; j < msg->iov[i].len; j++) + cksum += ((uint8_t *)msg->iov[i].buf)[j]; + } + cksum = 0xff - cksum; + dev->stats.tx_frame ++; + + /* some additional checks before sending */ + switch (hdr.type) { + + case XBEE_TYPE_ATCMD: + // XXX some checks ? + dev->stats.tx_atcmd ++; + break; + case XBEE_TYPE_ATCMD_Q: + dev->stats.tx_atcmd_q ++; + break; + case XBEE_TYPE_XMIT: + dev->stats.tx_data ++; + break; + case XBEE_TYPE_EXPL_XMIT: + dev->stats.tx_expl_data ++; + break; + case XBEE_TYPE_RMT_ATCMD: + dev->stats.tx_rmt_atcmd ++; + break; + + /* invalid commands */ + case XBEE_TYPE_XMIT_STATUS: + case XBEE_TYPE_MODEM_STATUS: + case XBEE_TYPE_ATRESP: + case XBEE_TYPE_RECV: + case XBEE_TYPE_EXPL_RECV: + case XBEE_TYPE_NODE_ID: + case XBEE_TYPE_RMT_ATRESP: + default: + dev->stats.tx_invalid_type ++; + fprintf_P(stderr, PSTR("unhandled xmit type=%x\r\n"), + hdr.type); + return -1; + } + + /* send the frame on the wire */ + fwrite(&hdr, 1, sizeof(hdr), dev->file); + for (i = 0; i < msg->iovlen; i++) + fwrite(msg->iov[i].buf, 1, msg->iov[i].len, dev->file); + fwrite(&cksum, 1, 1, dev->file); + + return 0; +} + +int xbee_tx(struct xbee_dev *dev, uint8_t channel_id, uint8_t type, + char *buf, unsigned len) +{ + struct xbee_msg msg; + msg.iovlen = 1; + msg.iov[0].buf = buf; + msg.iov[0].len = len; + return xbee_tx_iovec(dev, channel_id, type, &msg); +} + +void xbee_rx(struct xbee_dev *dev) +{ + uint8_t framelen; + struct xbee_hdr *hdr = (struct xbee_hdr *)dev->frame; + int c; + + while (1) { + + /* read from UART */ + c = fgetc(dev->file); + if (c == EOF) + break; + + /* frame too long XXX stats */ + if (dev->frame_len >= XBEE_MAX_FRAME_LEN) { + dev->frame_len = 0; + continue; + } + + if (dev->frame_len == 0 && c != XBEE_DELIMITER) + continue; + + dev->frame[dev->frame_len++] = c; + + /* not enough data to read len */ + if (dev->frame_len < sizeof(*hdr)) + continue; + + 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; + dev->stats.rx_frame++; + dev->stats.rx_frame_too_large++; + continue; + } + + /* not enough data */ + if (dev->frame_len < framelen) + continue; + + xbee_parse_frame(dev); + dev->frame_len = 0; + } +} diff --git a/modules/devices/radio/xbee/xbee_rxtx.h b/modules/devices/radio/xbee/xbee_rxtx.h new file mode 100644 index 0000000..67e175f --- /dev/null +++ b/modules/devices/radio/xbee/xbee_rxtx.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2011, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _XBEE_RXTX_H_ +#define _XBEE_RXTX_H_ + +/* protocol headers */ + +#define XBEE_DELIMITER 0x7E +#define XBEE_MAX_FRAME_LEN 0x50 + +struct xbee_hdr { + uint8_t delimiter; + uint16_t len; + uint8_t type; + uint8_t id; +} __attribute__((packed)); + +#define XBEE_TYPE_ATCMD 0x08 +struct xbee_atcmd_hdr { + uint16_t cmd; + uint8_t params[]; +} __attribute__((packed)); + +#define XBEE_TYPE_ATCMD_Q 0x09 +struct xbee_atcmd_q_hdr { + uint16_t cmd; + uint8_t params[]; +} __attribute__((packed)); + +#define XBEE_TYPE_XMIT 0x10 +struct xbee_xmit_hdr { + uint64_t dstaddr; + uint16_t reserved; + uint8_t bcast_radius; + uint8_t opts; + uint8_t data[]; +} __attribute__((packed)); + +#define XBEE_TYPE_EXPL_XMIT 0x11 +struct xbee_expl_xmit_hdr { + uint64_t dstaddr; + uint16_t reserved; + uint8_t src_endpoint; + uint8_t dst_endpoint; + uint16_t cluster_id; + uint16_t profile_id; + uint8_t bcast_radius; + uint8_t opts; + uint8_t data[]; +} __attribute__((packed)); + +#define XBEE_TYPE_RMT_ATCMD 0x17 +struct xbee_rmt_atcmd_hdr { + uint64_t dstaddr; + uint16_t reserved; + uint8_t opts; + uint16_t cmd; + uint8_t params[]; +} __attribute__((packed)); + +#define XBEE_TYPE_ATRESP 0x88 +struct xbee_atresp_hdr { + uint16_t cmd; + uint8_t status; + uint8_t data[]; +} __attribute__((packed)); + +#define XBEE_TYPE_MODEM_STATUS 0x8A +struct xbee_modem_status_hdr { + /* empty */ +} __attribute__((packed)); + +#define XBEE_TYPE_XMIT_STATUS 0x8B +struct xbee_xmit_status_hdr { + uint16_t reserved; + uint8_t xmit_retry_cnt; + uint8_t delivery_status; + uint8_t discovery_status; +} __attribute__((packed)); + +#define XBEE_TYPE_RECV 0x90 +struct xbee_recv_hdr { + uint64_t srcaddr; + uint16_t reserved; + uint8_t opts; + uint8_t data[]; +} __attribute__((packed)); + +#define XBEE_TYPE_EXPL_RECV 0x91 +struct xbee_expl_recv_hdr { + uint64_t srcaddr; + uint16_t reserved; + uint8_t src_endpoint; + uint8_t dst_endpoint; + uint16_t cluster_id; + uint16_t profile_id; + uint8_t opts; + uint8_t data[]; +} __attribute__((packed)); + +#define XBEE_TYPE_NODE_ID 0x95 +struct xbee_node_id_hdr { + uint64_t srcaddr; + uint16_t srcnetwork; + uint8_t opts; + uint16_t dstnetwork; + uint64_t dstaddr; + uint8_t ni_string[]; + /* uint16_t parentaddr; after variable field */ +} __attribute__((packed)); + +#define XBEE_TYPE_RMT_ATRESP 0x97 +struct xbee_rmt_atresp_hdr { + uint64_t srcaddr; + uint16_t reserved; + uint16_t cmd; + uint8_t status; + uint8_t data[]; +} __attribute__((packed)); + +struct xbee_dev; + +struct xbee_iovec { + void *buf; /* Buffer */ + unsigned len; /* Number of bytes in the buffer */ +}; + +#define XBEE_MSG_MAXIOV 4 +struct xbee_msg { + struct xbee_iovec iov[XBEE_MSG_MAXIOV]; /* scatter/gather array */ + unsigned iovlen; /* number of valid iov */ +}; + +/* send a frame */ +int xbee_tx(struct xbee_dev *dev, uint8_t id, uint8_t type, + char *buf, unsigned len); + +/* send a frame using an iovec */ +int xbee_tx_iovec(struct xbee_dev *dev, uint8_t id, uint8_t type, + const struct xbee_msg *msg); + +/* process the content of the rx buffer and decode incoming frames */ +void xbee_rx(struct xbee_dev *dev); + +#endif /* _XBEE_RXTX_H_ */ diff --git a/modules/devices/radio/xbee/xbee_stats.c b/modules/devices/radio/xbee/xbee_stats.c new file mode 100644 index 0000000..c47f185 --- /dev/null +++ b/modules/devices/radio/xbee/xbee_stats.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2011, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "xbee_neighbor.h" +#include "xbee_stats.h" +#include "xbee_rxtx.h" +#include "xbee.h" + +struct xbee_stats *xbee_get_stats(struct xbee_dev *dev) +{ +#ifdef CONFIG_MODULE_XBEE_STATS + return &dev->stats; +#else + (void)dev; + return NULL; +#endif +} + +void xbee_reset_stats(struct xbee_dev *dev) +{ + (void)dev; +#ifdef CONFIG_MODULE_XBEE_STATS + memset(&dev->stats, 0, sizeof(dev->stats)); +#endif +} + +void xbee_dump_stats(struct xbee_dev *dev) +{ +#ifdef CONFIG_MODULE_XBEE_STATS + printf_P(PSTR("statistics on xbee_dev %p:\r\n"), dev); + printf_P(PSTR(" rx_frame: %"PRIu32"\r\n"), dev->stats.rx_frame); + printf_P(PSTR(" rx_atresp: %"PRIu32"\r\n"), dev->stats.rx_atresp); + printf_P(PSTR(" rx_atresp_error: %"PRIu32"\r\n"), dev->stats.rx_atresp_error); + printf_P(PSTR(" rx_modem_status: %"PRIu32"\r\n"), dev->stats.rx_modem_status); + printf_P(PSTR(" rx_xmit_status: %"PRIu32"\r\n"), dev->stats.rx_xmit_status); + printf_P(PSTR(" rx_xmit_status_error: %"PRIu32"\r\n"), dev->stats.rx_xmit_status_error); + printf_P(PSTR(" rx_data: %"PRIu32"\r\n"), dev->stats.rx_data); + printf_P(PSTR(" rx_expl_data: %"PRIu32"\r\n"), dev->stats.rx_expl_data); + printf_P(PSTR(" rx_node_id: %"PRIu32"\r\n"), dev->stats.rx_node_id); + printf_P(PSTR(" rx_rmt_atresp: %"PRIu32"\r\n"), dev->stats.rx_rmt_atresp); + printf_P(PSTR(" rx_rmt_atresp_error: %"PRIu32"\r\n"), dev->stats.rx_rmt_atresp_error); + printf_P(PSTR(" rx_frame_too_small: %"PRIu32"\r\n"), dev->stats.rx_frame_too_small); + printf_P(PSTR(" rx_frame_too_large: %"PRIu32"\r\n"), dev->stats.rx_frame_too_large); + printf_P(PSTR(" rx_invalid_cksum: %"PRIu32"\r\n"), dev->stats.rx_invalid_cksum); + printf_P(PSTR(" rx_invalid_type: %"PRIu32"\r\n"), dev->stats.rx_invalid_type); + printf_P(PSTR(" rx_no_delim: %"PRIu32"\r\n"), dev->stats.rx_no_delim); + printf_P(PSTR(" rx_usr_error: %"PRIu32"\r\n"), dev->stats.rx_usr_error); + printf_P(PSTR(" tx_frame: %"PRIu32"\r\n"), dev->stats.tx_frame); + printf_P(PSTR(" tx_atcmd: %"PRIu32"\r\n"), dev->stats.tx_atcmd); + printf_P(PSTR(" tx_atcmd_q: %"PRIu32"\r\n"), dev->stats.tx_atcmd_q); + printf_P(PSTR(" tx_data: %"PRIu32"\r\n"), dev->stats.tx_data); + printf_P(PSTR(" tx_expl_data: %"PRIu32"\r\n"), dev->stats.tx_expl_data); + printf_P(PSTR(" tx_xmit_retries: %"PRIu32"\r\n"), dev->stats.tx_xmit_retries); + printf_P(PSTR(" tx_rmt_atcmd: %"PRIu32"\r\n"), dev->stats.tx_rmt_atcmd); + printf_P(PSTR(" tx_invalid_type: %"PRIu32"\r\n"), dev->stats.tx_invalid_type); + printf_P(PSTR(" tx_invalid_channel: %"PRIu32"\r\n"), dev->stats.tx_invalid_channel); +#else + (void)dev; + printf_P(PSTR("Statistics not enabled\r\n")); +#endif +} diff --git a/modules/devices/radio/xbee/xbee_stats.h b/modules/devices/radio/xbee/xbee_stats.h new file mode 100644 index 0000000..fc95aff --- /dev/null +++ b/modules/devices/radio/xbee/xbee_stats.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _XBEE_STATS_H_ +#define _XBEE_STATS_H_ + +/* per-device statistics */ +struct xbee_stats { + uint32_t rx_frame; + uint32_t rx_atresp; + uint32_t rx_atresp_error; + uint32_t rx_modem_status; + uint32_t rx_xmit_status; + uint32_t rx_xmit_status_error; + uint32_t rx_data; + uint32_t rx_expl_data; + uint32_t rx_node_id; + uint32_t rx_rmt_atresp; + uint32_t rx_rmt_atresp_error; + uint32_t rx_frame_too_small; + uint32_t rx_frame_too_large; + uint32_t rx_invalid_cksum; + uint32_t rx_invalid_type; + uint32_t rx_no_delim; + uint32_t rx_usr_error; + + uint32_t tx_frame; + uint32_t tx_atcmd; + uint32_t tx_atcmd_q; + uint32_t tx_data; + uint32_t tx_expl_data; + uint32_t tx_xmit_retries; + uint32_t tx_rmt_atcmd; + uint32_t tx_invalid_type; + uint32_t tx_invalid_channel; +}; + +struct xbee_dev; + +/* return pointer to device stats */ +struct xbee_stats *xbee_get_stats(struct xbee_dev *dev); + +/* reset statistics of device */ +void xbee_reset_stats(struct xbee_dev *dev); + +/* dump statistics on stdout */ +void xbee_dump_stats(struct xbee_dev *dev); + +#endif /* _XBEE_STATS_H_ */