diff --git a/drivers/include/xbee.h b/drivers/include/xbee.h index 7daf52f7e6..8d1d09f77c 100644 --- a/drivers/include/xbee.h +++ b/drivers/include/xbee.h @@ -70,6 +70,19 @@ */ #define XBEE_DEFAULT_CHANNEL (17U) +/** + * @name Address flags + * @{ + */ +/** + * @brief Use long addresses if not otherwise defined when set, use short + * addresses when unset. + */ +#define XBEE_ADDR_FLAGS_LONG (0x80) +/** + * @} + */ + /** * @brief States of the internal FSM for handling incoming UART frames * @@ -104,6 +117,7 @@ typedef struct { gpio_t sleep_pin; /**< GPIO pin connected to SLEEP */ ng_nettype_t proto; /**< protocol the interface speaks */ uint8_t options; /**< options field */ + uint8_t addr_flags; /**< address flags as defined above */ uint8_t addr_short[2]; /**< onw 802.15.4 short address */ eui64_t addr_long; /**< own 802.15.4 long address */ /* general variables for the UART RX state machine */ diff --git a/drivers/xbee/xbee.c b/drivers/xbee/xbee.c index c7a756c6e3..bd7f60339c 100644 --- a/drivers/xbee/xbee.c +++ b/drivers/xbee/xbee.c @@ -288,6 +288,26 @@ static int _set_addr(xbee_t *dev, uint8_t *val, size_t len) return -ECANCELED; } +static int _set_addr_len(xbee_t *dev, uint16_t *val, size_t len) +{ + if (len != sizeof(uint16_t)) { + return -EOVERFLOW; + } + + switch (*val) { + case 8: + dev->addr_flags |= XBEE_ADDR_FLAGS_LONG; + break; + case 2: + dev->addr_flags &= ~XBEE_ADDR_FLAGS_LONG; + break; + default: + return -EINVAL; + } + + return sizeof(uint16_t); +} + static int _get_channel(xbee_t *dev, uint8_t *val, size_t max) { uint8_t cmd[2]; @@ -403,6 +423,7 @@ int xbee_init(xbee_t *dev, uart_t uart, uint32_t baudrate, dev->reset_pin = reset_pin; dev->sleep_pin = sleep_pin; /* set default options */ + dev->addr_flags = 0; dev->proto = XBEE_DEFAULT_PROTOCOL; dev->options = 0; /* initialize buffers and locks*/ @@ -592,7 +613,12 @@ static int _get(ng_netdev_t *netdev, ng_netconf_opt_t opt, if (max_len < sizeof(uint16_t)) { return -EOVERFLOW; } - *((uint16_t *)value) = 2; + if (dev->addr_flags & XBEE_ADDR_FLAGS_LONG) { + *((uint16_t *)value) = 8; + } + else { + *((uint16_t *)value) = 2; + } return sizeof(uint16_t); case NETCONF_OPT_CHANNEL: return _get_channel(dev, (uint8_t *)value, max_len); @@ -622,6 +648,9 @@ static int _set(ng_netdev_t *netdev, ng_netconf_opt_t opt, switch (opt) { case NETCONF_OPT_ADDRESS: return _set_addr(dev, (uint8_t *)value, value_len); + case NETCONF_OPT_ADDR_LEN: + case NETCONF_OPT_SRC_LEN: + return _set_addr_len(dev, value, value_len); case NETCONF_OPT_CHANNEL: return _set_channel(dev, (uint8_t *)value, value_len); case NETCONF_OPT_NID: