yap yee king / XBeeLib2

Fork of XBeeLib by Digi International Inc.

Files at this revision

API Documentation at this revision

Comitter:
spastor
Date:
Mon Jun 01 18:59:43 2015 +0200
Parent:
3:8662ebe83570
Child:
5:da2ea7a76243
Commit message:
Automatic upload

Changed in this revision

DigiLogger.lib Show annotated file Show diff for this revision Revisions of this file
FrameBuffer/FrameBuffer.cpp Show annotated file Show diff for this revision Revisions of this file
FrameBuffer/FrameBuffer.h Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_AtCmdResp.cpp Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_AtCmdResp.h Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_IoDataSample802.cpp Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_IoDataSample802.h Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_IoDataSampleZB.cpp Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_IoDataSampleZB.h Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_ModemStatus.cpp Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_ModemStatus.h Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_RxPacket802.cpp Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_RxPacket802.h Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_RxPacketZB.cpp Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FH_RxPacketZB.h Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FrameHandler.cpp Show annotated file Show diff for this revision Revisions of this file
FrameHandlers/FrameHandler.h Show annotated file Show diff for this revision Revisions of this file
Frames/802_Frames.cpp Show annotated file Show diff for this revision Revisions of this file
Frames/802_Frames.h Show annotated file Show diff for this revision Revisions of this file
Frames/ApiFrame.cpp Show annotated file Show diff for this revision Revisions of this file
Frames/ApiFrame.h Show annotated file Show diff for this revision Revisions of this file
Frames/AtCmdFrame.cpp Show annotated file Show diff for this revision Revisions of this file
Frames/AtCmdFrame.h Show annotated file Show diff for this revision Revisions of this file
Frames/ZigbeeFrames.cpp Show annotated file Show diff for this revision Revisions of this file
Frames/ZigbeeFrames.h Show annotated file Show diff for this revision Revisions of this file
IO/IO.h Show annotated file Show diff for this revision Revisions of this file
IO/IOSample802.cpp Show annotated file Show diff for this revision Revisions of this file
IO/IOSample802.h Show annotated file Show diff for this revision Revisions of this file
IO/IOSampleZB.h Show annotated file Show diff for this revision Revisions of this file
RemoteXBee/RemoteXBee.h Show annotated file Show diff for this revision Revisions of this file
Utils/Debug.h Show annotated file Show diff for this revision Revisions of this file
Utils/Utils.cpp Show annotated file Show diff for this revision Revisions of this file
XBee/Addresses.h Show annotated file Show diff for this revision Revisions of this file
XBee/AtCommands.cpp Show annotated file Show diff for this revision Revisions of this file
XBee/RadioConfig.cpp Show annotated file Show diff for this revision Revisions of this file
XBee/XBee.cpp Show annotated file Show diff for this revision Revisions of this file
XBee/XBee.h Show annotated file Show diff for this revision Revisions of this file
XBee802/XBee802.cpp Show annotated file Show diff for this revision Revisions of this file
XBee802/XBee802.h Show annotated file Show diff for this revision Revisions of this file
XBeeLib.h Show annotated file Show diff for this revision Revisions of this file
XBeeZB/XBeeZB.cpp Show annotated file Show diff for this revision Revisions of this file
XBeeZB/XBeeZB.h Show annotated file Show diff for this revision Revisions of this file
--- a/DigiLogger.lib	Mon May 18 13:16:55 2015 +0200
+++ b/DigiLogger.lib	Mon Jun 01 18:59:43 2015 +0200
@@ -1,1 +1,1 @@
-http://developer.mbed.org/teams/Digi-International-Inc/code/DigiLogger/#b67d49554d8c
+http://developer.mbed.org/teams/Digi-International-Inc/code/DigiLogger/#58c5158b5120
--- a/FrameBuffer/FrameBuffer.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/FrameBuffer/FrameBuffer.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -9,8 +9,9 @@
  * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
  * =======================================================================
  */
- 
+
 #include "FrameBuffer.h"
+#include "Utils/Debug.h"
 
 #if !(defined AVOID_DISABLE_IRQS)
 #define disable_irq() __disable_irq()
@@ -20,47 +21,54 @@
 #define enable_irq()
 #endif
 
-FrameBuffer::FrameBuffer() : _head(0), _tail_app(0), _tail_syncr(0), _dropped_frames(0)
+FrameBuffer::FrameBuffer(uint8_t size, uint16_t max_payload_len) : _size(size), _head(0), _tail(0), _dropped_frames(0)
 {
-    for (int i = 0; i < FRAME_BUFFER_SIZE; i++) {
-        _frm_buf[i].frame = new ApiFrame(MAX_FRAME_PAYLOAD_LEN - 1);
+    _frm_buf = new buf_element_t[_size];
+
+    assert(_frm_buf != NULL);
+
+    for (int i = 0; i < _size; i++) {
+        _frm_buf[i].frame = new ApiFrame(max_payload_len - 1);
         _frm_buf[i].status = FrameStatusFree;
     }
 }
 
 FrameBuffer::~FrameBuffer()
 {
-    for (int i = 0; i < FRAME_BUFFER_SIZE; i++) {
+    for (int i = 0; i < _size; i++) {
         delete _frm_buf[i].frame;
     }
+
+    delete _frm_buf;
 }
-    
+
 ApiFrame *FrameBuffer::get_next_free_frame(void)
 {
     uint8_t i = _head;
     ApiFrame *ret = NULL;
-    
+
     do {
         if (_frm_buf[i].status == FrameStatusFree || _frm_buf[i].status == FrameStatusComplete) {
-            if (_frm_buf[i].status == FrameStatusComplete)
+            if (_frm_buf[i].status == FrameStatusComplete) {
                 _dropped_frames++;
+            }
             _frm_buf[i].status = FrameStatusAssigned;
             ret = _frm_buf[i].frame;
-            _head = ++i % FRAME_BUFFER_SIZE;
+            _head = ++i % _size;
             break;
         }
         i++;
-        i = i % FRAME_BUFFER_SIZE;
+        i = i % _size;
     } while (i != _head);
 
-    return ret;    
+    return ret;
 }
 
 bool FrameBuffer::complete_frame(ApiFrame *frame)
 {
     bool ret = false;
-    
-    for (int i = 0; i < FRAME_BUFFER_SIZE; i++) {
+
+    for (int i = 0; i < _size; i++) {
         if (_frm_buf[i].frame == frame) {
             _frm_buf[i].status = FrameStatusComplete;
             ret = true;
@@ -71,43 +79,33 @@
     return ret;
 }
 
-ApiFrame *FrameBuffer::get_next_complete_frame(uint8_t* tail)
+ApiFrame *FrameBuffer::get_next_complete_frame(void)
 {
-    uint8_t i = *tail;
+    uint8_t i = _tail;
     ApiFrame *ret = NULL;
-    
+
     do {
         disable_irq();
         if (_frm_buf[i].status == FrameStatusComplete) {
             _frm_buf[i].status = FrameStatusAssigned;
             enable_irq();
             ret = _frm_buf[i].frame;
-            *tail = ++i % FRAME_BUFFER_SIZE;
+            _tail = ++i % _size;
             break;
         }
         enable_irq();
         i++;
-        i = i % FRAME_BUFFER_SIZE;
-    } while (i != *tail);
-
-    return ret;    
-}
+        i = i % _size;
+    } while (i != _tail);
 
-ApiFrame *FrameBuffer::get_next_complete_frame_syncr(void)
-{
-    return get_next_complete_frame(&_tail_syncr);
-}
-
-ApiFrame *FrameBuffer::get_next_complete_frame_app(void)
-{
-    return get_next_complete_frame(&_tail_app);
+    return ret;
 }
 
 bool FrameBuffer::free_frame(ApiFrame *frame)
 {
     bool ret = false;
-    
-    for (int i = 0; i < FRAME_BUFFER_SIZE; i++) {
+
+    for (int i = 0; i < _size; i++) {
         if (_frm_buf[i].frame == frame) {
             _frm_buf[i].status = FrameStatusFree;
             ret = true;
--- a/FrameBuffer/FrameBuffer.h	Mon May 18 13:16:55 2015 +0200
+++ b/FrameBuffer/FrameBuffer.h	Mon Jun 01 18:59:43 2015 +0200
@@ -9,10 +9,10 @@
  * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
  * =======================================================================
  */
- 
+
 #if !defined(__FRAME_BUFFER_H_)
 #define __FRAME_BUFFER_H_
- 
+
 #include "config.h"
 #include "mbed.h"
 #include "Frames/ApiFrame.h"
@@ -28,47 +28,41 @@
 
 /**
  *  @class FrameBuffer
- *  @brief storage class for incoming frames 
- */ 
+ *  @brief storage class for incoming frames
+ */
 class FrameBuffer
 {
     public:
         /** Constructor */
-        FrameBuffer();
-        
+        FrameBuffer(uint8_t size, uint16_t max_payload_len);
+
         FrameBuffer(const FrameBuffer& other); /* Intentionally not implemented */
-        /** Destructor */ 
+        /** Destructor */
         ~FrameBuffer();
-        
-        /** get_next_free_frame returns the next free frame 
+
+        /** get_next_free_frame returns the next free frame
          *
          * @returns a pointer to the next free frame */
         ApiFrame *get_next_free_frame();
 
-        /** complete_frame sets the status of the frame to complete once the 
+        /** complete_frame sets the status of the frame to complete once the
          *                      data has been set in the buffer.
          *
          * @param pointer to the buffer we want to set as complete
          * @returns true on success, false otherwise
          */
         bool complete_frame(ApiFrame *frame);
-        
+
         /** free_frame makes the frame available to be reused in future
          *
          * @param frame to release */
         bool free_frame(ApiFrame *frame);
 
-        /** get_next_complete_frame_app returns the pointer to the next complete frame using _tail_app 
+        /** get_next_complete_frame returns the pointer to the next complete frame
          *
          * @returns the pointer to the selected buffer
          */
-        ApiFrame *get_next_complete_frame_app();
-
-        /** get_next_complete_frame_syncr returns the pointer to the next complete frame using _tail_syncr
-         *
-         * @returns the pointer to the selected buffer
-         */
-        ApiFrame *get_next_complete_frame_syncr();
+        ApiFrame *get_next_complete_frame();
 
         /** get_dropped_frames_count returns the number of dropped frames since latest call to this method
          *
@@ -76,7 +70,6 @@
          */
         uint32_t get_dropped_frames_count();
 
-
 protected:
 
         /** frame status */
@@ -87,26 +80,19 @@
         };
 
         /** buffer array */
-        buf_element_t   _frm_buf[FRAME_BUFFER_SIZE];
+        buf_element_t   * _frm_buf;
+
+        uint8_t          _size;
+        
 
         /** head frame index */
         uint8_t         _head;
 
         /** tail frame index for application */
-        uint8_t         _tail_app;
-
-        /** tail frame index for syncronous operations */
-        uint8_t         _tail_syncr;
+        uint8_t         _tail;
 
         /** dropped frames */
         uint32_t        _dropped_frames;
+};
 
-        /** get_next_complete_frame returns the pointer to the next complete frame
-         *
-         * @param tail tail index to use (either _tail_app or _tail_syncr)
-         * @returns the pointer to the selected buffer
-         */
-        ApiFrame *get_next_complete_frame(uint8_t* tail);
-};
- 
 #endif /* __FRAME_BUFFER_H_ */
--- a/FrameHandlers/FH_AtCmdResp.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_AtCmdResp.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -16,12 +16,12 @@
 using namespace XBeeLib;
 
 /** Class constructor */
-FH_AtCmdResp::FH_AtCmdResp() : 
+FH_AtCmdResp::FH_AtCmdResp() :
     FrameHandler(ApiFrame::AtCmdResp), at_cmd_resp_cb(NULL)
 {
 }
 
-FH_AtCmdResp::FH_AtCmdResp(ApiFrame::ApiFrameType type) : 
+FH_AtCmdResp::FH_AtCmdResp(ApiFrame::ApiFrameType type) :
     FrameHandler(type), at_cmd_resp_cb(NULL)
 {
 }
@@ -31,13 +31,11 @@
 {
 }
 
-/**  */
 void FH_AtCmdResp::register_at_cmd_resp_cb(at_cmd_resp_cb_t function)
 {
-    at_cmd_resp_cb = function;    
+    at_cmd_resp_cb = function;
 }
 
-/**  */
 void FH_AtCmdResp::unregister_at_cmd_resp_cb()
 {
     at_cmd_resp_cb = NULL;
@@ -45,17 +43,18 @@
 
 void FH_AtCmdResp::process_frame_data(const ApiFrame * const frame)
 {
-    /* The caller checks that the type matches, so no need to check it here again */        
-    
-    if (at_cmd_resp_cb == NULL)
+    /* The caller checks that the type matches, so no need to check it here again */
+
+    if (at_cmd_resp_cb == NULL) {
         return;
-    
+    }
+
     at_cmd_resp_cb(frame->get_data(), frame->get_data_len());
 }
 
 
 /** Class constructor */
-FH_NodeDiscoveryZB::FH_NodeDiscoveryZB() : 
+FH_NodeDiscoveryZB::FH_NodeDiscoveryZB() :
     FH_AtCmdResp(ApiFrame::AtCmdResp), node_discovery_cb(NULL)
 {
 }
@@ -65,13 +64,11 @@
 {
 }
 
-/**  */
 void FH_NodeDiscoveryZB::register_node_discovery_cb(node_discovery_zb_cb_t function)
 {
-    node_discovery_cb = function;    
+    node_discovery_cb = function;
 }
 
-/**  */
 void FH_NodeDiscoveryZB::unregister_node_discovery_cb()
 {
     node_discovery_cb = NULL;
@@ -80,17 +77,17 @@
 
 void FH_NodeDiscoveryZB::process_frame_data(const ApiFrame *const frame)
 {
-    /* The caller checks that the type matches, so no need to check it here again */        
-    
+    /* The caller checks that the type matches, so no need to check it here again */
+
     if (node_discovery_cb == NULL) {
         return;
     }
 
-    if (frame->get_data_at(ATCMD_RESP_CMD_LOW_OFFSET) != 'N' || 
+    if (frame->get_data_at(ATCMD_RESP_CMD_LOW_OFFSET) != 'N' ||
         frame->get_data_at(ATCMD_RESP_CMD_HIGH_OFFSET) != 'D') {
         return;
     }
-    
+
     if (frame->get_data_at(ATCMD_RESP_STATUS_OFFSET) != AtCmdFrame::AtCmdRespOk) {
         return;
     }
@@ -99,14 +96,6 @@
     const uint16_t addr16 = UINT16(data[ATCMD_RESP_NW_ADDR_H_OFFSET], data[ATCMD_RESP_NW_ADDR_L_OFFSET]);
     const uint64_t addr64 = addr64_from_uint8_t(&data[ATCMD_RESP_SH_ADDR_L_OFFSET]);
     const char * const node_id = (const char *)&data[ATCMD_RESP_NI_OFFSET];
-#if 0
-    const unsigned int node_id_len = strlen(node_id);
-    const unsigned int parent_addr16_offset = ATCMD_RESP_NI_OFFSET + node_id_len + sizeof "";
-    const uint16_t parent_addr16 = UINT16(data[parent_addr16_offset], data[parent_addr16_offset + 1]);
-    const NetworkRole network_role = (NetworkRole)(data[parent_addr16_offset + 2]);
-    const uint16_t profile_id = UINT16(data[parent_addr16_offset + 4], data[parent_addr16_offset + 5]);
-    const uint16_t manuf_id = UINT16(data[parent_addr16_offset + 6], data[parent_addr16_offset + 7]);
-#endif
     RemoteXBeeZB remote = RemoteXBeeZB(addr64, addr16);
 
     node_discovery_cb(remote, node_id);
@@ -115,7 +104,7 @@
 
 
 /** Class constructor */
-FH_NodeDiscovery802::FH_NodeDiscovery802() : 
+FH_NodeDiscovery802::FH_NodeDiscovery802() :
     FH_AtCmdResp(ApiFrame::AtCmdResp), node_discovery_cb(NULL)
 {
 }
@@ -125,13 +114,11 @@
 {
 }
 
-/**  */
 void FH_NodeDiscovery802::register_node_discovery_cb(node_discovery_802_cb_t function)
 {
-    node_discovery_cb = function;    
+    node_discovery_cb = function;
 }
 
-/**  */
 void FH_NodeDiscovery802::unregister_node_discovery_cb()
 {
     node_discovery_cb = NULL;
@@ -140,13 +127,13 @@
 
 void FH_NodeDiscovery802::process_frame_data(const ApiFrame *const frame)
 {
-    /* The caller checks that the type matches, so no need to check it here again */        
+    /* The caller checks that the type matches, so no need to check it here again */
 
     if (node_discovery_cb == NULL) {
         return;
     }
 
-    if (frame->get_data_at(ATCMD_RESP_CMD_LOW_OFFSET) != 'N' || 
+    if (frame->get_data_at(ATCMD_RESP_CMD_LOW_OFFSET) != 'N' ||
         frame->get_data_at(ATCMD_RESP_CMD_HIGH_OFFSET) != 'D') {
         return;
     }
@@ -155,7 +142,7 @@
         return;
     }
 
-    const uint16_t min_atnd_response_with_data = 2 + 8 + 1;
+    const uint16_t min_atnd_response_with_data = sizeof (uint16_t) + sizeof(uint64_t);
     if (frame->get_data_len() < min_atnd_response_with_data) {
         /* Do not process the ATND "OK" response */
         return;
--- a/FrameHandlers/FH_AtCmdResp.h	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_AtCmdResp.h	Mon Jun 01 18:59:43 2015 +0200
@@ -24,12 +24,12 @@
     private:
         /** Callback function, invoked (if registered) when an at command response packet is received */
         at_cmd_resp_cb_t at_cmd_resp_cb;
- 
+
     public:
-    
+
         /** Class constructor */
         FH_AtCmdResp();
-    
+
         /** Class constructor */
         FH_AtCmdResp(ApiFrame::ApiFrameType type);
 
@@ -38,11 +38,9 @@
         virtual ~FH_AtCmdResp();
 
         virtual void process_frame_data(const ApiFrame *const frame);
-        
-        /**  */
+
         virtual void register_at_cmd_resp_cb(at_cmd_resp_cb_t function);
 
-        /**  */
         virtual void unregister_at_cmd_resp_cb();
 };
 
@@ -57,16 +55,16 @@
 typedef void (*node_discovery_zb_cb_t)(const RemoteXBeeZB& remote, char const * const node_id);
 /**
  * @}
- */ 
+ */
 
 class FH_NodeDiscoveryZB : public FH_AtCmdResp
 {
     private:
         /** Callback function, invoked (if registered) when an at command response packet is received */
         node_discovery_zb_cb_t node_discovery_cb;
- 
+
     public:
-    
+
         /** Class constructor */
         FH_NodeDiscoveryZB();
 
@@ -74,11 +72,9 @@
         virtual ~FH_NodeDiscoveryZB();
 
         virtual void process_frame_data(const ApiFrame *const frame);
-        
-        /**  */
+
         virtual void register_node_discovery_cb(node_discovery_zb_cb_t function);
 
-        /**  */
         virtual void unregister_node_discovery_cb();
 };
 
@@ -93,16 +89,16 @@
 typedef void (*node_discovery_802_cb_t)(const RemoteXBee802& remote, char const * const node_id);
 /**
  * @}
- */ 
+ */
 
 class FH_NodeDiscovery802 : public FH_AtCmdResp
 {
     private:
         /** Callback function, invoked (if registered) when an at command response packet is received */
         node_discovery_802_cb_t node_discovery_cb;
- 
+
     public:
-    
+
         /** Class constructor */
         FH_NodeDiscovery802();
 
@@ -110,11 +106,9 @@
         virtual ~FH_NodeDiscovery802();
 
         virtual void process_frame_data(const ApiFrame *const frame);
-        
-        /**  */
+
         virtual void register_node_discovery_cb(node_discovery_802_cb_t function);
 
-        /**  */
         virtual void unregister_node_discovery_cb();
 };
 
--- a/FrameHandlers/FH_IoDataSample802.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_IoDataSample802.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -23,27 +23,25 @@
 /** Class destructor */
 FH_IoDataSampe64b802::~FH_IoDataSampe64b802()
 {
+
 }
 
-/**  */
 void FH_IoDataSampe64b802::register_io_data_cb(io_data_cb_802_t function)
 {
-    io_data_cb = function;    
+    io_data_cb = function;
 }
 
-/**  */
 void FH_IoDataSampe64b802::unregister_io_data_cb()
 {
-    io_data_cb = NULL;    
+    io_data_cb = NULL;
 }
 
 #define IO_SAMPLE_64_802_DATA_OFFSET        10
 
-/**  */
 void FH_IoDataSampe64b802::process_frame_data(const ApiFrame *const frame)
 {
     const uint8_t * const datap = frame->get_data();
-        
+
     /* The caller checks that the type matches, so no need to check it here again */
     if (io_data_cb == NULL) {
         return;
@@ -68,13 +66,11 @@
 {
 }
 
-/**  */
 void FH_IoDataSampe16b802::register_io_data_cb(io_data_cb_802_t function)
 {
     io_data_cb = function;
 }
 
-/**  */
 void FH_IoDataSampe16b802::unregister_io_data_cb()
 {
     io_data_cb = NULL;
@@ -84,7 +80,6 @@
 #define IO_SAMPLE_16_802_ADDR16_LSB_OFFSET  1
 #define IO_SAMPLE_16_802_DATA_OFFSET        4
 
-/**  */
 void FH_IoDataSampe16b802::process_frame_data(const ApiFrame *const frame)
 {
     const uint8_t * const datap = frame->get_data();;
--- a/FrameHandlers/FH_IoDataSample802.h	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_IoDataSample802.h	Mon Jun 01 18:59:43 2015 +0200
@@ -43,7 +43,6 @@
         /** Class destructor */
         virtual ~FH_IoDataSampe64b802();
 
-        /**  */
         virtual void process_frame_data(const ApiFrame *const frame);
 
         void register_io_data_cb(io_data_cb_802_t function);
@@ -64,11 +63,12 @@
         /** Class destructor */
         virtual ~FH_IoDataSampe16b802();
 
-        /**  */
         virtual void process_frame_data(const ApiFrame *const frame);
 
         void register_io_data_cb(io_data_cb_802_t function);
+
         void unregister_io_data_cb();
+
     private:
         /** Callback function, invoked if registered */
         io_data_cb_802_t io_data_cb;
--- a/FrameHandlers/FH_IoDataSampleZB.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_IoDataSampleZB.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -25,16 +25,14 @@
 {
 }
 
-/**  */
 void FH_IoDataSampeZB::register_io_data_cb(io_data_cb_zb_t function)
 {
-    io_data_cb = function;    
+    io_data_cb = function;
 }
 
-/**  */
 void FH_IoDataSampeZB::unregister_io_data_cb()
 {
-    io_data_cb = NULL;    
+    io_data_cb = NULL;
 }
 
 /* ZB RX packet offsets */
@@ -42,20 +40,20 @@
 #define ZB_IO_SAMPLE_ADDR16_LSB_OFFSET      9
 #define ZB_IO_SAMPLE_DATA_OFFSET            11
 
-/**  */
 void FH_IoDataSampeZB::process_frame_data(const ApiFrame *const frame)
 {
     const uint8_t * const datap = frame->get_data();;
-        
+
     /* The caller checks that the type matches, so no need to check it here again */
-    if (io_data_cb == NULL)
+    if (io_data_cb == NULL) {
         return;
+    }
 
     /* We got an IO packet, decode it... */
     const uint64_t sender64 = addr64_from_uint8_t(datap);
     const uint16_t sender16 = ADDR16(datap[ZB_IO_SAMPLE_ADDR16_MSB_OFFSET], datap[ZB_IO_SAMPLE_ADDR16_LSB_OFFSET]);
     const RemoteXBeeZB sender = RemoteXBeeZB(sender64, sender16);
     const IOSampleZB ioSample = IOSampleZB(&datap[ZB_IO_SAMPLE_DATA_OFFSET], frame->get_data_len() - ZB_IO_SAMPLE_DATA_OFFSET);
-    
+
     io_data_cb(sender, ioSample);
 }
--- a/FrameHandlers/FH_IoDataSampleZB.h	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_IoDataSampleZB.h	Mon Jun 01 18:59:43 2015 +0200
@@ -41,10 +41,11 @@
 
         /** Class destructor */
         virtual ~FH_IoDataSampeZB();
-        /**  */
+
         virtual void process_frame_data(const ApiFrame *const frame);
 
         void register_io_data_cb(io_data_cb_zb_t function);
+
         void unregister_io_data_cb();
 
     private:
--- a/FrameHandlers/FH_ModemStatus.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_ModemStatus.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -22,24 +22,23 @@
 {
 }
 
-/**  */
 void FH_ModemStatus::register_modem_status_cb(modem_status_cb_t function)
 {
-    modem_status_cb = function;    
+    modem_status_cb = function;
 }
 
-/**  */
 void FH_ModemStatus::unregister_modem_status_cb(void)
 {
-    modem_status_cb = NULL;    
+    modem_status_cb = NULL;
 }
 
 void FH_ModemStatus::process_frame_data(const ApiFrame *const frame)
 {
-    /* The caller checks that the type matches, so no need to check it here again */        
-    
-    if (modem_status_cb == NULL)
+    /* The caller checks that the type matches, so no need to check it here again */
+
+    if (modem_status_cb == NULL) {
         return;
+    }
 
     modem_status_cb((AtCmdFrame::ModemStatus)frame->get_data_at(0));
 }
--- a/FrameHandlers/FH_ModemStatus.h	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_ModemStatus.h	Mon Jun 01 18:59:43 2015 +0200
@@ -32,14 +32,12 @@
         virtual ~FH_ModemStatus();
 
          /** Method called by the stack to process the modem status frame data
-                
+
              \param frame pointer pointing to api frame that must be processed */
         virtual void process_frame_data(const ApiFrame *const frame);
-        
-        /**  */
+
         virtual void register_modem_status_cb(modem_status_cb_t function);
 
-        /**  */
         virtual void unregister_modem_status_cb(void);
 };
 
--- a/FrameHandlers/FH_RxPacket802.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_RxPacket802.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -15,7 +15,7 @@
 using namespace XBeeLib;
 
 /** Class constructor */
-FH_RxPacket64b802::FH_RxPacket64b802() : FrameHandler(ApiFrame::RxPacket64Bit), 
+FH_RxPacket64b802::FH_RxPacket64b802() : FrameHandler(ApiFrame::RxPacket64Bit),
     receive_cb(NULL)
 {
 }
@@ -25,16 +25,14 @@
 {
 }
 
-/**  */
 void FH_RxPacket64b802::register_receive_cb(receive_802_cb_t function)
 {
-    receive_cb = function;    
+    receive_cb = function;
 }
 
-/**  */
 void FH_RxPacket64b802::unregister_receive_cb(void)
 {
-    receive_cb = NULL;    
+    receive_cb = NULL;
 }
 
 /* 802.15.4 RX packet offsets */
@@ -43,20 +41,19 @@
 #define RX_802_DATA_OFFSET          10
 #define RX_802_OVERHEAD             (8+1+1)
 
-#define BROADCAST_PACKET            0x02    
+#define BROADCAST_PACKET            0x02
 
-/**  */
 void FH_RxPacket64b802::process_frame_data(const ApiFrame *const frame)
-{       
-    /* The caller checks that the type matches, so no need to check it here again */        
-    
-    if (receive_cb == NULL)
+{
+    /* The caller checks that the type matches, so no need to check it here again */
+
+    if (receive_cb == NULL) {
         return;
+    }
 
     /* We got a rx packet, decode it... */
     const uint8_t *datap = frame->get_data();
     const uint64_t sender64 = addr64_from_uint8_t(datap);
-//    uint8_t rssi = datap[RX_802_RSSI_OFFSET];
     const uint8_t rx_options = datap[RX_802_OPTIONS_OFFSET];
     const RemoteXBee802 sender = RemoteXBee802(sender64);
 
@@ -75,16 +72,14 @@
 {
 }
 
-/**  */
 void FH_RxPacket16b802::register_receive_cb(receive_802_cb_t function)
 {
-    receive_cb = function;    
+    receive_cb = function;
 }
 
-/**  */
 void FH_RxPacket16b802::unregister_receive_cb(void)
 {
-    receive_cb = NULL;    
+    receive_cb = NULL;
 }
 
 /* 802.15.4 RX packet offsets */
@@ -95,18 +90,17 @@
 #define RX_802_DATA_OFFSET2         4
 #define RX_802_OVERHEAD2            (2+1+1)
 
-/**  */
 void FH_RxPacket16b802::process_frame_data(const ApiFrame *const frame)
-{      
-    /* The caller checks that the type matches, so no need to check it here again */        
+{
+    /* The caller checks that the type matches, so no need to check it here again */
 
-    if (receive_cb == NULL)
+    if (receive_cb == NULL) {
         return;
+    }
 
     /* We got a rx packet, decode it... */
     const uint8_t *datap = frame->get_data();
     const uint16_t sender16 = ADDR16(datap[RX_802_ADDR16_MSB_OFFSET], datap[RX_802_ADDR16_LSB_OFFSET]);
-    //uint8_t rssi = datap[RX_802_RSSI_OFFSET2];
     const uint8_t rx_options = datap[RX_802_OPTIONS_OFFSET2];
     const RemoteXBee802 sender = RemoteXBee802(sender16);
 
--- a/FrameHandlers/FH_RxPacket802.h	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_RxPacket802.h	Mon Jun 01 18:59:43 2015 +0200
@@ -31,14 +31,14 @@
 typedef void (*receive_802_cb_t)(const RemoteXBee802& remote, bool broadcast, const uint8_t *const data, uint16_t len);
 /**
  * @}
- */ 
+ */
 
 class FH_RxPacket64b802 : public FrameHandler
 {
     private:
         /** Callback function, invoked if registered */
         receive_802_cb_t receive_cb;
-       
+
     public:
         /** Class constructor */
         FH_RxPacket64b802();
@@ -46,13 +46,10 @@
         /** Class destructor */
         virtual ~FH_RxPacket64b802();
 
-        /**  */
         virtual void process_frame_data(const ApiFrame* const frame);
 
-        /**  */
         virtual void register_receive_cb(receive_802_cb_t function);
 
-        /**  */
         virtual void unregister_receive_cb();
 };
 
@@ -69,13 +66,10 @@
         /** Class destructor */
         virtual ~FH_RxPacket16b802();
 
-        /**  */
         virtual void process_frame_data(const ApiFrame *const frame);
 
-        /**  */
         virtual void register_receive_cb(receive_802_cb_t function);
 
-        /**  */
         virtual void unregister_receive_cb();
 };
 
--- a/FrameHandlers/FH_RxPacketZB.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_RxPacketZB.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -24,16 +24,14 @@
 {
 }
 
-/**  */
 void FH_RxPacketZB::register_receive_cb(receive_zb_cb_t function)
 {
-    receive_cb = function;    
+    receive_cb = function;
 }
 
-/**  */
 void FH_RxPacketZB::unregister_receive_cb(void)
 {
-    receive_cb = NULL;    
+    receive_cb = NULL;
 }
 
 /* ZB RX packet offsets */
@@ -45,13 +43,13 @@
 
 #define BROADCAST_PACKET            0x02
 
-/**  */
 void FH_RxPacketZB::process_frame_data(const ApiFrame *const frame)
 {
-    /* The caller checks that the type matches, so no need to check it here again */        
+    /* The caller checks that the type matches, so no need to check it here again */
 
-    if (receive_cb == NULL)
+    if (receive_cb == NULL) {
         return;
+    }
 
     /* We got a rx packet, decode it... */
     const uint8_t *datap = frame->get_data();
--- a/FrameHandlers/FH_RxPacketZB.h	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FH_RxPacketZB.h	Mon Jun 01 18:59:43 2015 +0200
@@ -31,14 +31,14 @@
 typedef void (*receive_zb_cb_t)(const RemoteXBeeZB& remote, bool broadcast, const uint8_t *const data, uint16_t len);
 /**
  * @}
- */ 
+ */
 
 class FH_RxPacketZB : public FrameHandler
 {
     private:
         /** Callback function, invoked if registered */
         receive_zb_cb_t receive_cb;
-       
+
     public:
         /** Class constructor */
         FH_RxPacketZB();
@@ -47,14 +47,12 @@
         virtual ~FH_RxPacketZB();
 
         /** Method called by the stack to process the modem status frame data
-                
+
             \param frame pointer pointing to api frame that must be processed */
         virtual void process_frame_data(const ApiFrame* const frame);
 
-        /**  */
         void register_receive_cb(receive_zb_cb_t function);
 
-        /**  */
         void unregister_receive_cb();
 };
 
--- a/FrameHandlers/FrameHandler.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FrameHandler.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -19,8 +19,8 @@
 FrameHandler::~FrameHandler()
 {
 }
-    
+
 ApiFrame::ApiFrameType FrameHandler::get_type() const
 {
-    return _type;    
+    return _type;
 }
--- a/FrameHandlers/FrameHandler.h	Mon May 18 13:16:55 2015 +0200
+++ b/FrameHandlers/FrameHandler.h	Mon Jun 01 18:59:43 2015 +0200
@@ -19,7 +19,7 @@
 class FrameHandler
 {
     friend class ApiFrame;
-        
+
     public:
         /** Class constructor
          *
@@ -30,7 +30,7 @@
         FrameHandler(const FrameHandler& other); /* Intentionally not implemented */
         /** Class destructor */
         virtual ~FrameHandler();
-        
+
         /** get_type returns the type of frames handled by this handler
          *
          * @returns the frame type handled by the handler
@@ -46,7 +46,7 @@
 
     protected:
         /** frame type handled by this handler */
-        ApiFrame::ApiFrameType   _type;   
+        ApiFrame::ApiFrameType   _type;
 };
 
 #endif /* defined(__FRAME_HANDLER_H_) */
--- a/Frames/802_Frames.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/Frames/802_Frames.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -24,7 +24,7 @@
                 const uint8_t *const data, uint16_t len)
 {
     uint8_t frame_data[TX_REQUEST_OVERHEAD + len];
-    
+
     _frame_id = get_next_frame_id();
 
     /* copy the frame id, the 64bit remote address, the tx options byte
@@ -33,9 +33,10 @@
     frame_data[0] = _frame_id;
     rmemcpy(&frame_data[1], (const uint8_t *)&addr, sizeof addr);
     frame_data[9] = tx_options;
-        
-    if (len)
+
+    if (len) {
         memcpy(&frame_data[10], data, len);
+    }
 
     set_api_frame(TxReq64Bit, frame_data, TX_REQUEST_OVERHEAD + len);
 }
@@ -45,7 +46,7 @@
                 const uint8_t *const data, uint16_t len)
 {
     uint8_t frame_data[TX_REQUEST_OVERHEAD2 + len];
-    
+
     _frame_id = get_next_frame_id();
 
     /* copy the frame id, the 16bit remote address, the tx options byte
@@ -55,9 +56,10 @@
     frame_data[1] = (uint8_t)(addr16 >> 8);
     frame_data[2] = (uint8_t)addr16;
     frame_data[3] = tx_options;
-        
-    if (len)
+
+    if (len) {
         memcpy(&frame_data[4], data, len);
+    }
 
     set_api_frame(TxReq16Bit, frame_data, TX_REQUEST_OVERHEAD2 + len);
 }
--- a/Frames/802_Frames.h	Mon May 18 13:16:55 2015 +0200
+++ b/Frames/802_Frames.h	Mon Jun 01 18:59:43 2015 +0200
@@ -15,7 +15,7 @@
 
 #include "ApiFrame.h"
 
-class TxFrame802 : public ApiFrame 
+class TxFrame802 : public ApiFrame
 {
     public:
         /** Class constructor */
--- a/Frames/ApiFrame.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/Frames/ApiFrame.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -39,9 +39,10 @@
 uint8_t ApiFrame::get_next_frame_id(void)
 {
     last_frame_id++;
-    if (last_frame_id == 0)
+    if (last_frame_id == 0) {
         last_frame_id++;
-    
+    }
+
     return last_frame_id;
 }
 
@@ -55,8 +56,9 @@
 {
     this->_type = type;
     this->_data_frame_len = len;
-    if (this->_data)
+    if (this->_data) {
         delete _data;
+    }
     this->_data = new uint8_t[len];
     this->_alloc_data = true;
     assert(this->_data != NULL);
@@ -74,7 +76,7 @@
 {
 #if defined(ENABLE_LOGGING)
     digi_log(LogLevelFrameData, "API frame: type %02x, len %d\r\n", this->_type, this->_data_frame_len);
-    for (int i = 0; i < this->_data_frame_len; i++)    
+    for (int i = 0; i < this->_data_frame_len; i++)
         digi_log(LogLevelFrameData, "%02x ", this->_data[i]);
     digi_log(LogLevelFrameData, "\r\n");
 #endif
@@ -82,11 +84,12 @@
 
 void ApiFrame::dump_if(ApiFrameType type)
 {
-    if (_type != type)
+    if (_type != type) {
         return;
-    dump();        
+    }
+    dump();
 }
-       
+
 ApiFrame::ApiFrameType ApiFrame::get_frame_type() const
 {
     return _type;
@@ -100,27 +103,27 @@
 uint16_t ApiFrame::get_data_len() const
 {
     return _data_frame_len;
-} 
+}
 
-void ApiFrame::set_data_len(uint16_t len) 
+void ApiFrame::set_data_len(uint16_t len)
 {
     _data_frame_len = len;
-} 
+}
 
 const uint8_t *ApiFrame::get_data() const
 {
     return _data;
-} 
+}
 
 uint8_t ApiFrame::get_data_at(uint16_t index) const
 {
     return *(_data + index);
-} 
+}
 
-void ApiFrame::set_data(uint8_t d, uint16_t index) 
+void ApiFrame::set_data(uint8_t d, uint16_t index)
 {
     *(_data + index) = d;
-} 
+}
 
 /* Returns the frame_id of this frame */
 uint8_t ApiFrame::get_frame_id() const
--- a/Frames/ApiFrame.h	Mon May 18 13:16:55 2015 +0200
+++ b/Frames/ApiFrame.h	Mon Jun 01 18:59:43 2015 +0200
@@ -16,15 +16,15 @@
 #include "XBee/Addresses.h"
 
 /** Class for XBee API frames */
-class ApiFrame 
+class ApiFrame
 {
     /** Static variable that contains the last frame ID value assigned */
     static uint8_t      last_frame_id;
-    
+
         public:
         /** List of API frames. Note that not all frames are supported by all radios */
         enum ApiFrameType {
-       
+
             TxReq64Bit      = 0x00,     /**< TxReq64Bit: Only for 802.15.4 modules */
             TxReq16Bit      = 0x01,     /**< TxReq16Bit: Only for 802.15.4 modules */
             AtCmd           = 0x08,     /**< AtCmd */
@@ -52,38 +52,38 @@
             Many2OneRRInd   = 0xA3,     /**< Many2OneRRInd */
             Invalid         = ~0,       /**< Invalid */
         };
-   
+
         /** Default constructor */
         ApiFrame();
 
-        /** Constructor 
+        /** Constructor
          *
          * @param len length of the API frame (will allocate len bytes).
          */
         ApiFrame(uint16_t len);
-        
-        /** Constructor 
+
+        /** Constructor
          *
          * @param type frame type of this api frame.
          * @param data pointer to frame data payload.
          * @param len length of the payload.
          */
         ApiFrame(ApiFrameType type, const uint8_t *data, uint16_t len);
-        
+
         /** Destructor */
         ~ApiFrame();
 
         ApiFrame(const ApiFrame& other); /* Intentionally not implemented */
 
-        /** get_frame_type gets the type of the frame 
+        /** get_frame_type gets the type of the frame
          *
          * @returns the type of this frame.
          */
         ApiFrameType get_frame_type() const;
-        
+
         /** dump dumps the information of this frame */
         void dump() const;
-        
+
         /** dump_if dumps the information of the frame if the frame type matches
          *          with the parameter.
          *
@@ -97,7 +97,7 @@
          * @param type the type we want to set on the frame.
          */
         void set_frame_type(ApiFrameType type);
-        
+
         /** get_data_len gets the length of the frame data payload.
          *
          * @returns the length of the data payload.
@@ -109,19 +109,19 @@
          * @param len the length of the data payload will be set on this frame.
          */
         void set_data_len(uint16_t len);
-        
+
         /** get_data returns a pointer to the frame data payload.
          *
          * @returns a pointer to the frame data payload.
          */
         const uint8_t *get_data() const;
-        
+
         /** get_data_at returns the byte at index offset.
          *
          * @param index offset of the byte we want to get.
          * @returns the byte at index offset.
          */
-        uint8_t get_data_at(uint16_t index) const; 
+        uint8_t get_data_at(uint16_t index) const;
 
         /** set_data sets data byte at the specified index or offset.
          *
@@ -140,30 +140,30 @@
         {
             return last_frame_id;
         }
-    
+
     protected:
         /** Type of this frame */
         ApiFrameType        _type;
 
-        /** length of the payload, excluding the frame type */    
+        /** length of the payload, excluding the frame type */
         uint16_t            _data_frame_len;
 
-        /** pointer to the frame data */    
+        /** pointer to the frame data */
         uint8_t             *_data;
 
-        /** True if the constructor allocates the data. Needed to delete it on the destructor */    
+        /** True if the constructor allocates the data. Needed to delete it on the destructor */
         bool                _alloc_data;
-    
+
         /** Frame ID of this frame */
         uint8_t             _frame_id;
-    
+
         /** get_next_frame_id - returns the next frame ID secuentially, skipping the value 0
          *
          *  @returns the next frame ID that should be assigned to a frame
          */
         uint8_t get_next_frame_id();
 
-        /** set_api_frame sets several members  
+        /** set_api_frame sets several members
          *
          * @param type frame type of this api frame.
          * @param data pointer to frame data payload.
--- a/Frames/AtCmdFrame.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/Frames/AtCmdFrame.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -20,7 +20,7 @@
 void AtCmdFrame::build_at_cmd_frame(const char *cmd, const uint8_t *cmd_params, uint8_t payload_len, bool reverse)
 {
     uint8_t frame_data[AT_CMD_LEN + AT_CMD_ID_LEN + payload_len];
-    
+
     frame_data[0] = _frame_id;
     frame_data[1] = cmd[0];
     frame_data[2] = cmd[1];
@@ -65,7 +65,7 @@
 {
     assert(cmd != NULL);
     assert(strlen(cmd) == AT_CMD_LEN);
-    
+
     build_at_cmd_remote_frame(remote, ADDR16_UNKNOWN, cmd, (uint8_t *)&cmd_param, 4);
 }
 
@@ -81,7 +81,7 @@
 {
     assert(cmd != NULL);
     assert(strlen(cmd) == AT_CMD_LEN);
-    
+
     build_at_cmd_remote_frame(ADDR64_UNASSIGNED, remote, cmd, (uint8_t *)&cmd_param, 4);
 }
 
@@ -97,7 +97,7 @@
 {
     assert(cmd != NULL);
     assert(strlen(cmd) == AT_CMD_LEN);
-    
+
     build_at_cmd_remote_frame(remote64, remote16, cmd, (uint8_t *)&cmd_param, 4);
 }
 
@@ -123,7 +123,7 @@
                 const char *const cmd, const uint8_t *const cmd_params, uint8_t params_len, bool reverse)
 {
     uint8_t frame_data[REM_AT_CMD_OVERHEAD + params_len];
-    
+
     /* copy the frame id, the 64bit remote address, the 16bit network address,
      *  the options byte, the command and the command params */
 
@@ -134,7 +134,7 @@
     frame_data[11] = 0x02; /* TODO Options */
     frame_data[12] = cmd[0];
     frame_data[13] = cmd[1];
-        
+
     if (params_len) {
         if (reverse) {
             rmemcpy(&frame_data[14], cmd_params, params_len);
--- a/Frames/AtCmdFrame.h	Mon May 18 13:16:55 2015 +0200
+++ b/Frames/AtCmdFrame.h	Mon Jun 01 18:59:43 2015 +0200
@@ -39,12 +39,12 @@
 #define MAX_NI_PARAM_LEN                20
 
 /** Class for the AT command api frames. Derived from ApiFrame */
-class AtCmdFrame : public ApiFrame 
+class AtCmdFrame : public ApiFrame
 {
     public:
 
         /**
-         * AtCmdResp 
+         * AtCmdResp
          */
         enum AtCmdResp {
             AtCmdRespOk             = 0,     /**< Ok */
@@ -58,7 +58,7 @@
         };
 
         /**
-         * ModemStatus 
+         * ModemStatus
          */
         enum ModemStatus {
             HwReset         = 0,     /**< Hardware reset */
@@ -82,82 +82,82 @@
          * @param param_len length of the command param
          */
         AtCmdFrame(const char * const cmd, const uint32_t cmd_param);
-        
-        /** Class constructor 
+
+        /** Class constructor
          *
-         * @param cmd at command of the frame 
+         * @param cmd at command of the frame
          * @param cmd_param pointer to command parameter
          * @param param_len length of the command param
          */
         AtCmdFrame(const char * const cmd, const uint8_t * cmd_param = NULL, uint16_t param_len = 0);
 
-        /** Class constructor 
+        /** Class constructor
          *
          * @param remote 64 bit address of the remote device where we want to run the command
-         * @param cmd at command of the frame 
+         * @param cmd at command of the frame
          * @param cmd_param command parameter
          */
         AtCmdFrame(uint64_t remote, const char * const cmd, uint32_t cmd_param);
-        
-        /** Class constructor 
+
+        /** Class constructor
          *
          * @param remote 64 bit address of the remote device where we want to run the command
-         * @param cmd at command of the frame 
+         * @param cmd at command of the frame
          * @param cmd_param pointer to command parameter
          * @param param_len length of the command param
          */
         AtCmdFrame(uint64_t remote, const char * const cmd, const uint8_t * cmd_param = NULL, uint16_t param_len = 0);
 
-        /** Class constructor 
+        /** Class constructor
          *
          * @param remote 16 bit address of the remote device where we want to run the command
-         * @param cmd at command of the frame 
+         * @param cmd at command of the frame
          * @param cmd_param command parameter
          */
         AtCmdFrame(uint16_t remote, const char * const cmd, uint32_t cmd_param);
-        
-        /** Class constructor 
+
+        /** Class constructor
          *
          * @param remote 16 bit address of the remote device where we want to run the command
-         * @param cmd at command of the frame 
+         * @param cmd at command of the frame
          * @param cmd_param pointer to command parameter
          * @param param_len length of the command param
          */
         AtCmdFrame(uint16_t remote, const char * const cmd, const uint8_t * cmd_param = NULL, uint16_t param_len = 0);
 
-        /** Class constructor 
+        /** Class constructor
          *
          * @param remote 64 bit address of the remote device where we want to run the command
          * @param remote 16 bit address of the remote device where we want to run the command
-         * @param cmd at command of the frame 
+         * @param cmd at command of the frame
          * @param cmd_param command parameter
          */
         AtCmdFrame(uint64_t remote64, uint16_t remote16, const char * const cmd, uint32_t cmd_param);
-        
-        /** Class constructor 
+
+        /** Class constructor
          *
          * @param remote 64 bit address of the remote device where we want to run the command
          * @param remote 16 bit address of the remote device where we want to run the command
-         * @param cmd at command of the frame 
+         * @param cmd at command of the frame
          * @param cmd_param pointer to command parameter
          * @param param_len length of the command param
          */
         AtCmdFrame(uint64_t remote64, uint16_t remote16, const char * const cmd, const uint8_t * cmd_param = NULL, uint16_t param_len = 0);
 
     protected:
-        /** build_at_cmd_frame method used by the constructors to create the at command frame 
+        /** build_at_cmd_frame method used by the constructors to create the at command frame
          *
-         * @param cmd at command of the frame 
+         * @param cmd at command of the frame
          * @param cmd_params pointer to command parameter
          * @param param_len length of the command param
          */
         void build_at_cmd_frame(const char *cmd, const uint8_t *cmd_params, uint8_t payload_len, bool reverse = true);
 
-        /** build_at_cmd_remote_frame method used by the constructors to create the at command frame 
+        /** build_at_cmd_remote_frame method used by the constructors to create the at command frame
          *
          * @param remote64 64 bit address of the remote device where we want to run the command
          * @param remote16 16 bit address of the remote device where we want to run the command
-         * @param cmd at command of the frame 
+         * @param cmd at command of the frame
          * @param cmd_params pointer to command parameter
          * @param param_len length of the command param
          */
--- a/Frames/ZigbeeFrames.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/Frames/ZigbeeFrames.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -34,7 +34,7 @@
                 const uint8_t *const data, uint16_t len)
 {
     uint8_t frame_data[TX_REQUEST_OVERHEAD + len];
-    
+
     _frame_id = get_next_frame_id();
 
     /* copy the frame id, the 64bit remote address, the 16bit network address,
@@ -46,20 +46,21 @@
     frame_data[10] = (uint8_t)addr16;
     frame_data[11] = broadcast_rad;
     frame_data[12] = tx_opt;
-        
-    if (len)
+
+    if (len) {
         memcpy(&frame_data[13], data, len);
+    }
 
     set_api_frame(TxReqZB, frame_data, TX_REQUEST_OVERHEAD + len);
 }
 
 /** Class constructor */
 TxFrameZB::TxFrameZB(uint64_t addr, uint16_t addr16, uint8_t source_ep, uint8_t dest_ep,
-                  uint16_t cluster_id, uint16_t profile_id, uint8_t broadcast_rad, 
+                  uint16_t cluster_id, uint16_t profile_id, uint8_t broadcast_rad,
                   uint8_t tx_opt, const uint8_t *const data, uint16_t len)
 {
     uint8_t frame_data[EXP_ADDR_OVERHEAD + len];
-    
+
     _frame_id = get_next_frame_id();
 
     /* copy the frame id, the 64bit remote address, the 16bit network address,
@@ -78,9 +79,10 @@
     frame_data[16] = (uint8_t)profile_id;
     frame_data[17] = broadcast_rad;
     frame_data[18] = tx_opt;
-        
-    if (len)
+
+    if (len) {
         memcpy(&frame_data[19], data, len);
+    }
 
     set_api_frame(ExpAddrCmd, frame_data, EXP_ADDR_OVERHEAD + len);
 }
--- a/Frames/ZigbeeFrames.h	Mon May 18 13:16:55 2015 +0200
+++ b/Frames/ZigbeeFrames.h	Mon Jun 01 18:59:43 2015 +0200
@@ -15,7 +15,7 @@
 
 #include "ApiFrame.h"
 
-class TxFrameZB : public ApiFrame 
+class TxFrameZB : public ApiFrame
 {
     public:
         /** Class constructor */
@@ -24,7 +24,7 @@
 
         /** Class constructor */
         TxFrameZB(uint64_t addr, uint16_t addr16, uint8_t source_ep, uint8_t dest_ep,
-                  uint16_t cluster_id, uint16_t profile_id, uint8_t broadcast_rad, 
+                  uint16_t cluster_id, uint16_t profile_id, uint8_t broadcast_rad,
                   uint8_t tx_opt, const uint8_t *const data, uint16_t len);
 };
 
--- a/IO/IO.h	Mon May 18 13:16:55 2015 +0200
+++ b/IO/IO.h	Mon Jun 01 18:59:43 2015 +0200
@@ -22,7 +22,7 @@
  * @{
  */
 /**
- * IoMode 
+ * IoMode
  */
 enum IoMode {
     Disabled         = 0,  /**< Disabled */
@@ -36,13 +36,13 @@
 /**
  * @}
  */
- 
+
 /**
  * @defgroup DioVal
  * @{
  */
 /**
- * DioVal 
+ * DioVal
  */
 enum DioVal {
     Low     = 0,      /**< Low Value */
@@ -54,5 +54,5 @@
 
 }   /* namespace XBeeLib */
 
-        
+
 #endif /* __IO_H_ */
--- a/IO/IOSample802.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/IO/IOSample802.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -96,8 +96,7 @@
 {
     if (dio_channels_present()) {
         return UINT16(_sampled_data[0], _sampled_data[1]);
-    }
-    else {
+    } else {
         return 0;
     }
 }
--- a/IO/IOSample802.h	Mon May 18 13:16:55 2015 +0200
+++ b/IO/IOSample802.h	Mon Jun 01 18:59:43 2015 +0200
@@ -54,7 +54,7 @@
          */
         inline bool is_valid()
         {
-            return _channel_mask == 0;
+            return _channel_mask != 0;
         }
 
     protected:
--- a/IO/IOSampleZB.h	Mon May 18 13:16:55 2015 +0200
+++ b/IO/IOSampleZB.h	Mon Jun 01 18:59:43 2015 +0200
@@ -54,7 +54,7 @@
          */
         inline bool is_valid()
         {
-            return _digital_mask == 0 && _analog_mask == 0;
+            return _digital_mask != 0 || _analog_mask != 0;
         }
 
     protected:
--- a/RemoteXBee/RemoteXBee.h	Mon May 18 13:16:55 2015 +0200
+++ b/RemoteXBee/RemoteXBee.h	Mon Jun 01 18:59:43 2015 +0200
@@ -16,7 +16,7 @@
 #include "XBee/Addresses.h"
 
 namespace XBeeLib {
-  
+
 /** Class for Remote XBee modules. Not to be used directly. */
 class RemoteXBee
 {
@@ -80,7 +80,7 @@
         /** Remote Device 64 bit address */
         uint64_t      _dev_addr64;
 
-        /** Remote Device 16 bit address */        
+        /** Remote Device 16 bit address */
         uint16_t    _dev_addr16;
 };
 
@@ -98,7 +98,7 @@
          * @param remote64 the 64-bit address (ATSH and ATSL parameters) of the remote XBee module
          */
         RemoteXBee802(uint64_t remote64);
- 
+
         /** Class constructor for a 802.15.4 remote device (connected wirelessly) using 16bit addressing
          * @param remote16 the 16-bit address (ATMY parameter) of the remote XBee module
          */
@@ -144,7 +144,7 @@
          * @param remote16 the 16-bit address (ATMY parameter) of the remote XBee module
          */
         RemoteXBeeZB(uint64_t remote64, uint16_t remote16);
- 
+
         /** Class destructor */
         ~RemoteXBeeZB();
 
--- a/Utils/Debug.h	Mon May 18 13:16:55 2015 +0200
+++ b/Utils/Debug.h	Mon Jun 01 18:59:43 2015 +0200
@@ -9,7 +9,7 @@
  * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
  * =======================================================================
  */
- 
+
 #if !defined(__DEBUG_H_)
 #define __DEBUG_H_
 
--- a/Utils/Utils.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/Utils/Utils.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -9,7 +9,7 @@
  * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
  * =======================================================================
  */
- 
+
 #include "Utils.h"
 #include <string.h>
 
--- a/XBee/Addresses.h	Mon May 18 13:16:55 2015 +0200
+++ b/XBee/Addresses.h	Mon Jun 01 18:59:43 2015 +0200
@@ -9,7 +9,7 @@
  * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
  * =======================================================================
  */
- 
+
 #ifndef __ADDRESSES_H_
 #define __ADDRESSES_H_
 
--- a/XBee/AtCommands.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/XBee/AtCommands.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -9,7 +9,7 @@
  * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
  * =======================================================================
  */
- 
+
 #include "XBeeLib.h"
 
 #define GET_CMD_RESP(fr, radio_location)    (radio_location == RadioRemote ? fr->get_data_at(REM_AT_CMD_RESP_STATUS_OFFSET) \
@@ -17,11 +17,11 @@
 
 #define GET_DATA_LEN(fr, radio_location)    (radio_location == RadioRemote ? (fr->get_data_len() - REM_AT_CMD_RESP_OVERHEAD) \
                                                                    : (fr->get_data_len() - ATCMD_RESP_OVERHEAD))
-                                       
+
 #define GET_DATA_OFF(radio_location)        (radio_location == RadioRemote ? REM_AT_CMD_RESP_CMD_DATA_OFFSET \
                                                                    : ATCMD_RESP_DATA_OFFSET)
 
-using namespace XBeeLib;                              
+using namespace XBeeLib;
 
 /** Method that sends an AT command to the module and waits for the command response.
  *  @returns the AT command response */
@@ -30,7 +30,7 @@
 {
     AtCmdFrame::AtCmdResp resp = AtCmdFrame::AtCmdRespTimeout;
     ApiFrame *resp_frame;
-    ApiFrame::ApiFrameType expected_type = 
+    ApiFrame::ApiFrameType expected_type =
             (frame->get_frame_type() == ApiFrame::AtCmd) ?
             ApiFrame::AtCmdResp : ApiFrame::RemoteCmdResp;
 
@@ -38,9 +38,10 @@
 
     /* Wait for the AT command response packet */
     resp_frame = get_this_api_frame(frame->get_frame_id(), expected_type);
-    if (resp_frame == NULL)
+    if (resp_frame == NULL) {
         return resp;
- 
+    }
+
     resp = (AtCmdFrame::AtCmdResp)GET_CMD_RESP(resp_frame, radio_location);
     if (resp == AtCmdFrame::AtCmdRespOk) {
         if (buf != NULL && len != NULL) {
@@ -62,7 +63,7 @@
     }
 
     /* Once processed, remove the frame from the buffer */
-    _framebuf.free_frame(resp_frame);
+    _framebuf_syncr.free_frame(resp_frame);
     return resp;
 }
 
@@ -78,8 +79,9 @@
     uint16_t len = sizeof *data;
     AtCmdFrame::AtCmdResp atCmdResponse = send_at_cmd(frame, data, &len);
 
-    if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len != sizeof *data)
+    if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len != sizeof *data) {
         atCmdResponse = AtCmdFrame::AtCmdRespLenMismatch;
+    }
 
     return atCmdResponse;
 }
@@ -89,8 +91,9 @@
     uint16_t len = sizeof *data;
     AtCmdFrame::AtCmdResp atCmdResponse = send_at_cmd(frame, (uint8_t *)data, &len);
 
-    if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len != sizeof *data)
+    if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len != sizeof *data) {
         atCmdResponse = AtCmdFrame::AtCmdRespLenMismatch;
+    }
 
     return atCmdResponse;
 }
@@ -100,8 +103,9 @@
     uint16_t len = sizeof *data;
     AtCmdFrame::AtCmdResp atCmdResponse = send_at_cmd(frame, (uint8_t *)data, &len);
 
-    if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len != sizeof *data)
+    if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len != sizeof *data) {
         atCmdResponse = AtCmdFrame::AtCmdRespLenMismatch;
+    }
 
     return atCmdResponse;
 }
@@ -114,8 +118,9 @@
     *data = 0; /* Set to zero, send_at_cmd() only writes the necessary bytes, so if only 1 is written all the remaining 3 should be 0. */
     AtCmdFrame::AtCmdResp atCmdResponse = send_at_cmd(&cmd_frame, (uint8_t *)data, &len);
 
-    if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len > sizeof *data)
+    if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len > sizeof *data) {
         atCmdResponse = AtCmdFrame::AtCmdRespLenMismatch;
+    }
 
     return atCmdResponse;
 }
--- a/XBee/RadioConfig.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/XBee/RadioConfig.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -26,17 +26,6 @@
     return Success;
 }
 
-RadioStatus XBee::sleep_now(void)
-{
-    AtCmdFrame::AtCmdResp cmdresp;
-
-    cmdresp = set_param("SI");
-    if (cmdresp != AtCmdFrame::AtCmdRespOk) {
-        return Failure;
-    }
-    return Success;
-}
-
 RadioStatus XBee::set_power_level(uint8_t  level)
 {
     AtCmdFrame::AtCmdResp cmdresp;
@@ -138,6 +127,25 @@
     return Success;
 }
 
+RadioStatus XBee::enable_network_encryption(bool enable)
+{
+    AtCmdFrame::AtCmdResp cmdresp;
+
+    cmdresp = set_param("EE", enable);
+    return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
+}
+
+RadioStatus XBee::set_network_encryption_key(const uint8_t * const key, const uint16_t length)
+{
+    if (key == NULL || length == 0 || length > 16) {
+        return Failure;
+    }
+    AtCmdFrame::AtCmdResp cmdresp;
+
+    cmdresp = set_param("KY", key, length);
+    return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
+}
+
 uint16_t XBee::get_hw_version() const
 {
     return _hw_version;
@@ -158,24 +166,43 @@
     return _tx_options;
 }
 
-void XBee::set_broadcast_radius(uint8_t bc_radius)
-{
-    _bc_radius = bc_radius;
-}
-
-uint8_t XBee::get_bc_radius() const
-{
-    return _bc_radius;
-}
-
 RadioStatus XBee::start_node_discovery()
 {
+    AtCmdFrame::AtCmdResp cmdresp;
+    uint32_t nd_timeout_cfg;
+
+    cmdresp = get_param("NT", &nd_timeout_cfg);
+    if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+        return Failure;
+    }
+
+    const unsigned int guard_time_ms = 1000;
+    const uint32_t nd_timeout_cfg_ms = nd_timeout_cfg * 100;
+    _nd_timeout = nd_timeout_cfg_ms + guard_time_ms;
+
+    _nd_timer.start();
+
     AtCmdFrame cmd_frame = AtCmdFrame("ND");
     send_api_frame(&cmd_frame);
 
     return Success;
 }
 
+bool XBee::is_node_discovery_in_progress()
+{
+    const int nd_timer = _nd_timer.read_ms();
+
+    if (nd_timer == 0)
+        return false;
+
+    if (nd_timer > _nd_timeout) {
+        _nd_timer.stop();
+        _nd_timer.reset();
+    }
+
+    return true;
+}
+
 void XBee::_get_remote_node_by_id(const char * const node_id, uint64_t * const addr64, uint16_t * const addr16)
 {
     *addr64 = ADDR64_UNASSIGNED;
@@ -198,40 +225,48 @@
         _timeout_ms = (uint16_t)nd_timeout_100msec * 100 + 1000;
     }
 
-    const AtCmdFrame::AtCmdResp cmdresp = set_param("ND", (const uint8_t *)node_id, strlen(node_id));
-    if (cmdresp != AtCmdFrame::AtCmdRespOk) {
-        _timeout_ms = old_timeout;
+    const int nd_timeout = _timeout_ms;
+    Timer nd_timer = Timer();
+
+    nd_timer.start();
+
+    AtCmdFrame atnd_frame = AtCmdFrame("ND", (const uint8_t *)node_id, strlen(node_id));
+    const uint8_t frame_id = atnd_frame.get_frame_id();
+    _node_by_ni_frame_id = frame_id;
+    send_api_frame(&atnd_frame);
+
+    ApiFrame * const resp_frame = get_this_api_frame(frame_id, ApiFrame::AtCmdResp);
+    _timeout_ms = old_timeout;
+
+    _node_by_ni_frame_id = 0;
+
+    if (resp_frame == NULL) {
+        digi_log(LogLevelWarning, "_get_remote_node_by_id: timeout when waiting for ATND response");
         return;
     }
 
-    const int nd_start_time = _timer.read_ms();
-    const int nd_end_time = nd_start_time + _timeout_ms;
-
-    AtCmdFrame atnd_frame = AtCmdFrame("ND", (const uint8_t *)node_id, strlen(node_id));
-    send_api_frame(&atnd_frame);
-
-    ApiFrame * const resp_frame = get_this_api_frame(atnd_frame.get_frame_id(), ApiFrame::AtCmdResp);
-    _timeout_ms = old_timeout;
-
-    while (_timer.read_ms() < nd_end_time) {
-        wait_ms(10);
-    }
-
-    if (resp_frame == NULL) {
-        digi_log(LogLevelWarning, "XBeeZB::get_remote_node_by_id timeout when waiting for ATND response");
+    if (resp_frame->get_data_len() < sizeof (uint16_t) + sizeof (uint64_t)) {
+        /* In 802.15.4 this might be the OK or Timeout message with no information */
+        digi_log(LogLevelInfo, "_get_remote_node_by_id: node not found\r\n", __FUNCTION__, node_id);
+        _framebuf_syncr.free_frame(resp_frame);
         return;
     }
 
     const AtCmdFrame::AtCmdResp resp = (AtCmdFrame::AtCmdResp)resp_frame->get_data_at(ATCMD_RESP_STATUS_OFFSET);
     if (resp != AtCmdFrame::AtCmdRespOk) {
-        digi_log(LogLevelWarning, "send_at_cmd bad response: 0x%x\r\n", resp);
-        _framebuf.free_frame(resp_frame);
+        digi_log(LogLevelWarning, "_get_remote_node_by_id: send_at_cmd bad response: 0x%x\r\n", resp);
+        _framebuf_syncr.free_frame(resp_frame);
         return;
     }
 
     rmemcpy((uint8_t *)addr16, resp_frame->get_data() + ATCMD_RESP_DATA_OFFSET, sizeof *addr16);
     rmemcpy((uint8_t *)addr64, resp_frame->get_data() + ATCMD_RESP_DATA_OFFSET + sizeof *addr16, sizeof *addr64);
-    _framebuf.free_frame(resp_frame);
+    _framebuf_syncr.free_frame(resp_frame);
+
+    while (nd_timer.read_ms() < nd_timeout) {
+        wait_ms(10);
+    }
+
     return;
 }
 
--- a/XBee/XBee.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/XBee/XBee.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -25,8 +25,20 @@
 
 using namespace XBeeLib;
 
-Timer XBee::_timer;
-FrameBuffer XBee::_framebuf;
+#if defined(FRAME_BUFFER_SIZE_SYNCR)
+#if FRAME_BUFFER_SIZE_SYNCR < 2
+#error "FRAME_BUFFER_SIZE_SYNCR must be at least 2"
+#endif
+#else
+#define FRAME_BUFFER_SIZE_SYNCR     1
+#endif
+
+#define MAX_FRAME_PAYLOAD_LEN_SYNCR (1  /* type */         + 1  /* id */       + 2 /* at cmd*/    + 1 /* status */    + 2 /* MY sender */ + \
+                                     8  /* 64b sender */   + 20 /* max id */   + 1 /* null ter */ + 2 /* MY parent */ + 1  /* dev type */ + \
+                                     1  /* source event */ + 2  /* prof. id */ + 2 /* man. id */)
+
+FrameBuffer XBee::_framebuf_app(FRAME_BUFFER_SIZE, MAX_FRAME_PAYLOAD_LEN);
+FrameBuffer XBee::_framebuf_syncr(FRAME_BUFFER_SIZE_SYNCR, MAX_FRAME_PAYLOAD_LEN_SYNCR);
 
 #if defined(DEVICE_SERIAL_FC)
 bool XBee::check_radio_flow_control()
@@ -39,8 +51,7 @@
         if (cmdresp != AtCmdFrame::AtCmdRespOk) {
             digi_log(LogLevelError, "Could not read CTS configuration. Error %d\r\n", cmdresp);
             return false;
-        }
-        else if (value != 1) {
+        } else if (value != 1) {
             digi_log(LogLevelError, "Bad CTS configuration. Radio 'D7' param is %d and should be 1\r\n", value);
             return false;
         }
@@ -51,8 +62,7 @@
         if (cmdresp != AtCmdFrame::AtCmdRespOk) {
             digi_log(LogLevelError, "Could not read RTS configuration. Error %d\r\n", cmdresp);
             return false;
-        }
-        else if (value != 1) {
+        } else if (value != 1) {
             digi_log(LogLevelError, "Bad RTS configuration. Radio 'D6' param is %d and should be 1\r\n", value);
             return false;
         }
@@ -64,17 +74,13 @@
 
 /* Class constructor */
 XBee::XBee(PinName tx, PinName rx, PinName reset, PinName rts, PinName cts, int baud) :
-    _mode(ModeUnknown), _type(Unknown), _hw_version(0), _fw_version(0), _timeout_ms(SYNC_OPS_TIMEOUT_MS), _dev_addr64(ADDR64_UNASSIGNED), _dev_addr16(ADDR16_UNKNOWN),
-    _reset(NULL), _tx_options(0), _bc_radius(0), _hw_reset_cnt(0), _wd_reset_cnt(0), _reset_timeout(0), _modem_status_handler(NULL), _modem_status(AtCmdFrame::HwReset), _initializing(true), _pm_mode(SleepDisabled)
+    _mode(ModeUnknown), _hw_version(0), _fw_version(0), _timeout_ms(SYNC_OPS_TIMEOUT_MS), _dev_addr64(ADDR64_UNASSIGNED),
+    _reset(NULL), _tx_options(0), _hw_reset_cnt(0), _wd_reset_cnt(0), _modem_status_handler(NULL), _modem_status(AtCmdFrame::HwReset), _initializing(true), _node_by_ni_frame_id(0)
 {
 
     if (reset != NC) {
         _reset = new DigitalOut(reset, 1);
     }
-#if defined(ENABLE_PM_SUPPORT)
-    _on_sleep = NULL;
-    _sleep_req = NULL;
-#endif /* defined(ENABLE_PM_SUPPORT) */
 
     _uart = new RawSerial(tx, rx);
     _uart->baud(baud);
@@ -83,13 +89,11 @@
 #if defined(DEVICE_SERIAL_FC)
     if (rts != NC && cts != NC) {
         _serial_flow_type = SerialBase::RTSCTS;
-        _uart->set_flow_control(_serial_flow_type, rts, cts);        
-    }
-    else if (rts != NC && cts == NC) {
+        _uart->set_flow_control(_serial_flow_type, rts, cts);
+    } else if (rts != NC && cts == NC) {
         _serial_flow_type = SerialBase::RTS;
         _uart->set_flow_control(_serial_flow_type, rts);
-    }
-    else if (rts == NC && cts != NC) {
+    } else if (rts == NC && cts != NC) {
         _serial_flow_type = SerialBase::CTS;
         _uart->set_flow_control(_serial_flow_type, cts);
     }
@@ -122,54 +126,58 @@
     AtCmdFrame::AtCmdResp cmd_resp;
     uint32_t var32;
 
-    /* Start the timer, used for the timeouts */
-    _timer.reset();
-    _timer.start();
-
     _initializing = true;
 
-    device_reset();
+    const unsigned int max_reset_retries = 3;
+    RadioStatus reset_status;
+    for (unsigned int i = 0; i < max_reset_retries; i++) {
+        reset_status = device_reset();
+        if (reset_status == Success) {
+            break;
+        }
+    }
+    if (reset_status != Success) {
+        return reset_status;
+    }
 
     /* Check if radio is in API1 or API2 _mode */
     cmd_resp = get_param("AP", &var32);
-    if (cmd_resp != AtCmdFrame::AtCmdRespOk)
+    if (cmd_resp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
-
+    }
     _mode = (RadioMode)var32;
 
     /* Read the device unique 64b address */
     uint32_t serialn_high, serialn_low;
     cmd_resp = get_param("SH", &serialn_high);
-    if (cmd_resp != AtCmdFrame::AtCmdRespOk)
+    if (cmd_resp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
+    }
+
     cmd_resp = get_param("SL", &serialn_low);
-    if (cmd_resp != AtCmdFrame::AtCmdRespOk)
+    if (cmd_resp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
+    }
 
     _dev_addr64 = ((uint64_t)serialn_high << 32) | serialn_low;
 
     /* Read some important parameters */
     cmd_resp = get_param("HV", &var32);
-    if (cmd_resp != AtCmdFrame::AtCmdRespOk)
+    if (cmd_resp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
+    }
     _hw_version = var32;
 
     cmd_resp = get_param("VR", &var32);
-    if (cmd_resp != AtCmdFrame::AtCmdRespOk)
+    if (cmd_resp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
+    }
     _fw_version = var32;
 
-    cmd_resp = get_param("MY", &var32);
-    if (cmd_resp != AtCmdFrame::AtCmdRespOk)
-        return Failure;
-    _dev_addr16 = var32;
-    _type = (RadioType)(_hw_version >> 8);
-
     digi_log(LogLevelInfo, "mode:   %02x\r\n", (uint8_t)_mode);
     digi_log(LogLevelInfo, "HV:     %04x\r\n", _hw_version);
     digi_log(LogLevelInfo, "VR:     %04x\r\n", _fw_version);
     digi_log(LogLevelInfo, "ADDR64: %08x:%08x\r\n", UINT64_HI32(_dev_addr64), UINT64_LO32(_dev_addr64));
-    digi_log(LogLevelInfo, "ADDR16: %04x\r\n", _dev_addr16);
 
 #if defined(DEVICE_SERIAL_FC)
     bool valid_radio_fc = check_radio_flow_control();
@@ -180,7 +188,7 @@
     if (_modem_status_handler != NULL) {
         const ApiFrame frame = ApiFrame(ApiFrame::AtModemStatus, (uint8_t *)&_modem_status, sizeof(_modem_status));
         _modem_status_handler->process_frame_data(&frame);
-    }   
+    }
 
     return Success;
 }
@@ -190,11 +198,6 @@
     return _dev_addr64;
 }
 
-uint16_t XBee::get_addr16() const
-{
-    return _dev_addr16;
-}
-
 RadioStatus XBee::hardware_reset()
 {
     if (_reset != NULL) {
@@ -211,20 +214,23 @@
 
 RadioStatus XBee::device_reset()
 {
-    if (hardware_reset() == Success)
+    if (hardware_reset() == Success) {
         return Success;
+    }
 
     return software_reset();
 }
 
 RadioStatus XBee::wait_for_module_to_reset(volatile uint16_t *rst_cnt_p, uint16_t init_rst_cnt)
 {
-    const int rst_timeout = _timer.read_ms() + _reset_timeout;
-    while (*rst_cnt_p == init_rst_cnt && _timer.read_ms() < rst_timeout) {
+    Timer timer = Timer();
+    timer.start();
+
+    while (*rst_cnt_p == init_rst_cnt && timer.read_ms() < RESET_TIMEOUT_MS) {
         wait_ms(100);
     }
 
-    if (_reset_timeout && *rst_cnt_p == init_rst_cnt) {
+    if (*rst_cnt_p == init_rst_cnt) {
         digi_log(LogLevelWarning, "Reset Timeout\r\n");
         return Failure;
     }
@@ -240,10 +246,11 @@
     static uint8_t chksum;
     static ApiFrame *frame = NULL;
     static bool last_byte_escaped = false;
-    
+    static FrameBuffer * framebuf = NULL;
+
     while (_uart->readable()) {
         uint8_t data = _uart->getc();
-        
+
         if (IS_API2() && rxstate != WAITING_FOR_START_FRAME) {
             if (last_byte_escaped) {
                 data = data ^ DR_ESCAPE_XOR_BYTE;
@@ -253,13 +260,14 @@
                 continue;
             }
         }
-        
+
         switch (rxstate) {
             case WAITING_FOR_START_FRAME:
-                if (data == DR_START_OF_FRAME)
+                if (data == DR_START_OF_FRAME) {
                     rxstate = WAITING_FOR_LENGTH_MSB;
+                }
                 break;
-                
+
             case WAITING_FOR_LENGTH_MSB:
                 framelen = data << 8;
                 rxstate = WAITING_FOR_LENGTH_LSB;
@@ -267,7 +275,7 @@
 
             case WAITING_FOR_LENGTH_LSB:
                 framelen |= data;
-                rxstate = WAITING_FOR_PAYLOAD; /* FIXME, if frame is NULL the status should be WAITING */
+                rxstate = WAITING_FOR_PAYLOAD;
                 bytes_read = 0;
                 chksum = 0;
                 /* Sanity check that the frame is smaller than... */
@@ -276,27 +284,157 @@
                     digi_log(LogLevelWarning, "Frame dropped, frame too long. Increase MAX_FRAME_PAYLOAD_LEN define\r\n");
                     rxstate = WAITING_FOR_START_FRAME;
                 }
-
-                frame = _framebuf.get_next_free_frame();
-                if (frame == NULL) {
-                    /* It's not possible to achive this condition as we discard older frames and only one frame can be used by syncr. commands */
-                    assert(frame != NULL);
-                    rxstate = WAITING_FOR_START_FRAME;
-                } else {
-                    frame->set_data_len(framelen - 1);
-                }
                 break;
 
             case WAITING_FOR_PAYLOAD:
-                if (!bytes_read)
-                    frame->set_frame_type((ApiFrame::ApiFrameType)data);
-                else {
+                #define CACHED_SIZE 3
+                static uint8_t frame_cached[CACHED_SIZE];
+
+                if (framelen <= CACHED_SIZE) {
+                    if (!bytes_read) {
+                        const ApiFrame::ApiFrameType frame_type = (ApiFrame::ApiFrameType)data;
+                        switch (frame_type)
+                        {
+                            case ApiFrame::AtCmdResp:       /**< AtCmdResp */
+                            case ApiFrame::RemoteCmdResp:   /**< RemoteCmdResp */
+                            case ApiFrame::TxStatusZB:      /**< TxStatusZB: Only for ZigBee modules */
+                            case ApiFrame::TxStatus:        /**< TxStatus */
+                                framebuf = &_framebuf_syncr;
+                                break;
+
+                            case ApiFrame::RxPacket64Bit:   /**< RxPacket64Bit: Only for 802.15.4 modules */
+                            case ApiFrame::RxPacket16Bit:   /**< RxPacket16Bit: Only for 802.15.4 modules */
+                            case ApiFrame::Io64Bit:         /**< Io64Bit: Only for 802.15.4 modules */
+                            case ApiFrame::Io16Bit:         /**< Io16Bit */
+                            case ApiFrame::AtModemStatus:   /**< AtModemStatus */
+                            case ApiFrame::RxPacketAO0:     /**< RxPacketAO0: Only for ZigBee modules */
+                            case ApiFrame::IoSampleRxZB:    /**< IoSampleRxZB: Only for ZigBee modules */
+                                framebuf = &_framebuf_app;
+                                break;
+
+                            case ApiFrame::RxPacketAO1:     /**< RxPacketAO1: Only for ZigBee modules */
+                            case ApiFrame::SensorRxIndAO0:  /**< SensorRxIndAO0: Only for ZigBee modules */
+                            case ApiFrame::NodeIdentIndAO0: /**< NodeIdentIndAO0: Only for ZigBee modules */
+                            case ApiFrame::OtaFwUpStatus:   /**< OtaFwUpStatus */
+                            case ApiFrame::RouteRecInd:     /**< RouteRecInd */
+                            case ApiFrame::Many2OneRRInd:   /**< Many2OneRRInd */
+                            case ApiFrame::TxReq64Bit:      /**< TxReq64Bit: Only for 802.15.4 modules */
+                            case ApiFrame::TxReq16Bit:      /**< TxReq16Bit: Only for 802.15.4 modules */
+                            case ApiFrame::AtCmd:           /**< AtCmd */
+                            case ApiFrame::AtCmdQueuePV:    /**< AtCmdQueuePV */
+                            case ApiFrame::TxReqZB:         /**< TxReqZB: Only for ZigBee modules */
+                            case ApiFrame::ExpAddrCmd:      /**< ExpAddrCmd: Only for ZigBee modules */
+                            case ApiFrame::RemoteCmdReq:    /**< RemoteCmdReq */
+                            case ApiFrame::CreateSrcRoute:  /**< CreateSrcRoute */
+                            case ApiFrame::Invalid:         /**< Invalid */
+                                framebuf = NULL;
+                                break;
+                        }
+
+                        if (framebuf == NULL) {
+                            digi_log(LogLevelWarning, "Discarding not supported frame type %02x\r\n", frame_type);
+                            rxstate = WAITING_FOR_START_FRAME;
+                        } else {
+                            frame = framebuf->get_next_free_frame();
+                            if (frame == NULL) {
+                                /* It's not possible to achive this condition as we discard older frames and only one frame can be used by syncr. commands */
+                                assert(frame != NULL);
+                                rxstate = WAITING_FOR_START_FRAME;
+                            } else {
+                                frame->set_data_len(framelen - 1);
+                            }
+
+                            frame->set_frame_type(frame_type);
+                        }
+                    } else {
+                        frame->set_data(data, bytes_read - 1);
+                    }
+                    chksum += data;
+                    bytes_read++;
+                    if (bytes_read == framelen) {
+                        rxstate = WAITING_FOR_CHECKSUM;
+                    }
+                    break;
+                }
+
+
+                if (bytes_read < CACHED_SIZE) {
+                    frame_cached[bytes_read] = data;
+                }
+                else if (bytes_read == CACHED_SIZE) {
+                    const ApiFrame::ApiFrameType frame_type = (ApiFrame::ApiFrameType)frame_cached[0];
+                    switch (frame_type)
+                    {
+                        case ApiFrame::RemoteCmdResp:   /**< RemoteCmdResp */
+                        case ApiFrame::TxStatusZB:      /**< TxStatusZB: Only for ZigBee modules */
+                        case ApiFrame::TxStatus:        /**< TxStatus */
+                            framebuf = &_framebuf_syncr;
+                            break;
+
+                        case ApiFrame::AtCmdResp:       /**< AtCmdResp */
+                            if ((frame_cached[1] != _node_by_ni_frame_id ) && (frame_cached[2] == 'N') && (data == 'D'))
+                            {
+                                framebuf = &_framebuf_app;
+                            } else {
+                                framebuf = &_framebuf_syncr;
+                            }
+                            break;
+
+                        case ApiFrame::RxPacket64Bit:   /**< RxPacket64Bit: Only for 802.15.4 modules */
+                        case ApiFrame::RxPacket16Bit:   /**< RxPacket16Bit: Only for 802.15.4 modules */
+                        case ApiFrame::Io64Bit:         /**< Io64Bit: Only for 802.15.4 modules */
+                        case ApiFrame::Io16Bit:         /**< Io16Bit */
+                        case ApiFrame::AtModemStatus:   /**< AtModemStatus */
+                        case ApiFrame::RxPacketAO0:     /**< RxPacketAO0: Only for ZigBee modules */
+                        case ApiFrame::IoSampleRxZB:    /**< IoSampleRxZB: Only for ZigBee modules */
+                            framebuf = &_framebuf_app;
+                            break;
+
+                        case ApiFrame::RxPacketAO1:     /**< RxPacketAO1: Only for ZigBee modules */
+                        case ApiFrame::SensorRxIndAO0:  /**< SensorRxIndAO0: Only for ZigBee modules */
+                        case ApiFrame::NodeIdentIndAO0: /**< NodeIdentIndAO0: Only for ZigBee modules */
+                        case ApiFrame::OtaFwUpStatus:   /**< OtaFwUpStatus */
+                        case ApiFrame::RouteRecInd:     /**< RouteRecInd */
+                        case ApiFrame::Many2OneRRInd:   /**< Many2OneRRInd */
+                        case ApiFrame::TxReq64Bit:      /**< TxReq64Bit: Only for 802.15.4 modules */
+                        case ApiFrame::TxReq16Bit:      /**< TxReq16Bit: Only for 802.15.4 modules */
+                        case ApiFrame::AtCmd:           /**< AtCmd */
+                        case ApiFrame::AtCmdQueuePV:    /**< AtCmdQueuePV */
+                        case ApiFrame::TxReqZB:         /**< TxReqZB: Only for ZigBee modules */
+                        case ApiFrame::ExpAddrCmd:      /**< ExpAddrCmd: Only for ZigBee modules */
+                        case ApiFrame::RemoteCmdReq:    /**< RemoteCmdReq */
+                        case ApiFrame::CreateSrcRoute:  /**< CreateSrcRoute */
+                        case ApiFrame::Invalid:         /**< Invalid */
+                            framebuf = NULL;
+                            break;
+                    }
+
+                    if (framebuf == NULL) {
+                        digi_log(LogLevelWarning, "Discarding not supported frame type %02x\r\n", frame_type);
+                        rxstate = WAITING_FOR_START_FRAME;
+                    } else {
+                        frame = framebuf->get_next_free_frame();
+                        if (frame == NULL) {
+                            /* It's not possible to achive this condition as we discard older frames and only one frame can be used by syncr. commands */
+                            assert(frame != NULL);
+                            rxstate = WAITING_FOR_START_FRAME;
+                        } else {
+                            frame->set_data_len(framelen - 1);
+                        }
+
+                        frame->set_frame_type(frame_type);
+                        frame->set_data(frame_cached[1], 0);
+                        frame->set_data(frame_cached[2], 1);
+                        frame->set_data(data, 2);
+                    }
+                } else {
                     frame->set_data(data, bytes_read - 1);
                 }
                 chksum += data;
                 bytes_read++;
-                if (bytes_read == framelen)
+                if (bytes_read == framelen) {
                     rxstate = WAITING_FOR_CHECKSUM;
+                }
                 break;
 
             case WAITING_FOR_CHECKSUM:
@@ -304,37 +442,37 @@
                 if (chksum == 0xFF) {
                     /* We got a valid frame!! */
                     frame->dump();
-                                        
+
                     /* If its a _modem status frame, process it to update the status info of the library.
                      * The frame is also queued to allow processing it other handlers registered.
                      * Note that radio_status_update() has to be fast to minimize the impact of processing
                      * the funcion here */
                     if (frame->get_frame_type() == ApiFrame::AtModemStatus) {
                         radio_status_update((AtCmdFrame::ModemStatus)frame->get_data_at(0));
-                        if (_initializing)
-                            _framebuf.free_frame(frame);
-                        else
-                            _framebuf.complete_frame(frame);
-                    }
-                    else {
-                        _framebuf.complete_frame(frame);
+                        if (_initializing) {
+                            framebuf->free_frame(frame);
+                        } else {
+                            framebuf->complete_frame(frame);
+                        }
+                    } else {
+                        framebuf->complete_frame(frame);
                         /* Note, the frame will be released elsewhere, once it has been processed */
                     }
                 } else {
-                    _framebuf.free_frame(frame);
+                    framebuf->free_frame(frame);
                     digi_log(LogLevelWarning, "Checksum error, got %02x, %02x\r\n", data, chksum);
                 }
                 /* Intentional fall-through */
             default:
                 rxstate = WAITING_FOR_START_FRAME;
                 break;
-        }                
+        }
     }
     /* TODO, signal the thread processing incoming frames */
 }
 
 /* This is a pure virtual function, but exists here because its called from this class to
- * to update the status of the object, and can be called before the construction of the 
+ * to update the status of the object, and can be called before the construction of the
  * object has been completed and the virtual functions filled */
 void XBee::radio_status_update(AtCmdFrame::ModemStatus modem_status)
 {
@@ -343,7 +481,7 @@
 
 void XBee::set_timeout(uint16_t timeout_ms)
 {
-    this->_timeout_ms = timeout_ms;        
+    this->_timeout_ms = timeout_ms;
 }
 
 uint16_t XBee::get_timeout(void) const
@@ -351,21 +489,14 @@
     return _timeout_ms;
 }
 
-RadioType XBee::get_radio_type() const
-{
-    return _type;
-}
-
-
-
-/* */
-ApiFrame * XBee::get_this_api_frame(uint8_t id, ApiFrame::ApiFrameType type, 
+ApiFrame * XBee::get_this_api_frame(uint8_t id, ApiFrame::ApiFrameType type,
                                           ApiFrame::ApiFrameType type2)
 {
-    int const timeout = _timer.read_ms() + _timeout_ms;
+    Timer timer = Timer();
+    timer.start();
 
-    while (_timer.read_ms() < timeout) {
-        ApiFrame * frame = _framebuf.get_next_complete_frame_syncr();
+    while (timer.read_ms() < _timeout_ms) {
+        ApiFrame * frame = _framebuf_syncr.get_next_complete_frame();
         if (frame == NULL) {
             wait_ms(10);
             continue;
@@ -373,21 +504,21 @@
 
         if ((frame->get_frame_type() != type) &&
             (frame->get_frame_type() != type2)) {
-            _framebuf.complete_frame(frame);
-            wait_ms(1);
-            continue;
-        }
-            
-        if (frame->get_data_at(ATCMD_RESP_FRAME_ID_OFFSET) != id) {
-            _framebuf.complete_frame(frame);
+            _framebuf_syncr.complete_frame(frame);
             wait_ms(1);
             continue;
         }
 
-        /* frame found */    
+        if (frame->get_data_at(ATCMD_RESP_FRAME_ID_OFFSET) != id) {
+            _framebuf_syncr.complete_frame(frame);
+            wait_ms(1);
+            continue;
+        }
+
+        /* frame found */
         return frame;
     }
-    
+
     digi_log(LogLevelWarning, "Frame type: %02x, id: %02x, timeout\r\n", (uint8_t)type, id);
 
     return NULL;
@@ -409,7 +540,7 @@
         }
     } else {
         _uart->putc(data);
-    }    
+    }
 }
 
 void XBee::send_api_frame(ApiFrame *frame)
@@ -417,15 +548,15 @@
     uint8_t chksum;
     const uint8_t *data;
     uint16_t bytes_sent = 0, frame_len;
-    
+
     frame->dump();
-        
+
     frame_len = 1 + frame->get_data_len(); /* frame type + frame payload */
     data = frame->get_data();
-    
+
     /* Send the start of frame delimiter */
     _uart->putc(DR_START_OF_FRAME);
-    
+
     /* Now the length */
     send_byte_escaping_if((uint8_t)(frame_len >> 8));
     send_byte_escaping_if((uint8_t)frame_len);
@@ -440,47 +571,49 @@
         chksum += *data;
         send_byte_escaping_if(*data++);
     }
-            
+
     /* And finally send the checksum */
     send_byte_escaping_if(~chksum);
 }
-  
-/** */        
+
 RadioStatus XBee::register_frame_handler(FrameHandler *const handler)
 {
     if (handler != NULL) {
         for (int i = 0; i < MAX_FRAME_HANDLERS; i++) {
-            if (_fhandlers[i] != NULL)
+            if (_fhandlers[i] != NULL) {
                 continue;
+            }
             _fhandlers[i] = handler;
             return Success;
         }
     }
 
     digi_log(LogLevelError, "No more Frame Handlers available. Increase MAX_FRAME_HANDLERS define\r\n");
-    
+
     return Failure;
-}     
+}
 
-/** */
 RadioStatus XBee::unregister_frame_handler(FrameHandler *const handler)
 {
     int i;
 
     if (handler != NULL) {
         for (i = 0; i < MAX_FRAME_HANDLERS; i++) {
-            if (_fhandlers[i] == handler)
+            if (_fhandlers[i] == handler) {
                 break;
+            }
         }
-        
-        if (i == MAX_FRAME_HANDLERS)
+
+        if (i == MAX_FRAME_HANDLERS) {
             return Failure;
-        
+        }
+
         do {
-            if (i == MAX_FRAME_HANDLERS - 1)
+            if (i == MAX_FRAME_HANDLERS - 1) {
                 _fhandlers[i] = NULL;
-            else
+            } else {
                 _fhandlers[i] = _fhandlers[i + 1];
+            }
         } while (++i < MAX_FRAME_HANDLERS);
     }
 
@@ -640,20 +773,21 @@
 
     send_api_frame(frame);
 
-    /* Wait for the transmit status response packet */   
-    resp_frame = get_this_api_frame(frame->get_frame_id(), 
+    /* Wait for the transmit status response packet */
+    resp_frame = get_this_api_frame(frame->get_frame_id(),
                     ApiFrame::TxStatusZB, ApiFrame::TxStatus);
-    if (resp_frame == NULL)
+    if (resp_frame == NULL) {
         return resp;
-    
+    }
+
     uint8_t index = resp_frame->get_frame_type() == ApiFrame::TxStatusZB ?
             TX_STATUS_OFFSET_ZB : TX_STATUS_OFFSET_802;
-    
+
     resp = (TxStatus)resp_frame->get_data_at(index);
- 
+
     /* Once processed, remove the frame from the buffer */
-    _framebuf.free_frame(resp_frame);
-    
+    _framebuf_syncr.free_frame(resp_frame);
+
     return resp;
 }
 
@@ -663,82 +797,11 @@
     return send_data(remoteDevice, data, len, syncr);
 }
 
-#if defined(ENABLE_PM_SUPPORT)
-
-RadioStatus XBee::set_pm_control(PmMode mode, PinName on_sleep, PinName sleep_rq)
-{
-    if (on_sleep != NC) {
-        _on_sleep = new InterruptIn(on_sleep);
-    }
-    if (sleep_rq != NC) {
-        _sleep_req = new DigitalOut(sleep_rq);
-    }
-    _pm_mode = mode;
-    /* TODO, set PM mode in the radio */
-    //return 0;
-    return Success;
-}
-
-
-RadioStatus XBee::get_pm_mode(PmMode *mode)
-{
-    *mode = _pm_mode;
-    return Success;
-}
-
-RadioStatus XBee::config_pm_timing(uint32_t before_sleep_ms, uint32_t total_sleep_period_ms)
-{
-    UNUSED_PARAMETER(before_sleep_ms);
-    UNUSED_PARAMETER(total_sleep_period_ms);
-    return Success;
-}
-
-RadioStatus XBee::enter_sleep_mode()
-{
-    if (_sleep_req == NULL)
-        return sleep_now();
-    
-    _sleep_req->write(1);
-    return Success;
-}
-
-void XBee::exit_sleep_mode()
-{
-    /* TODO, check also mode? */
-    if (_sleep_req != NULL)
-        _sleep_req->write(0);
-}
-
-bool XBee::is_sleeping()
-{
-    /* TODO */
-    return true;
-}
-         
-
-
-void XBee::register_wakeup_cb(void (*f)(void))
-{
-    if (_on_sleep == NULL)
-        return;
-    
-    _on_sleep->rise(f);
-}
-
-void XBee::unregister_wakeup_cb()
-{
-    _on_sleep->disable_irq();
-    _on_sleep->rise(NULL);
-}
-
-#endif /* defined(ENABLE_PM_SUPPORT) */
-
-
-uint32_t XBee::process_rx_frames(void)
+uint32_t XBee::process_rx_frames()
 {
     ApiFrame *frame = NULL;
 
-    while ((frame = _framebuf.get_next_complete_frame_app()) != NULL) {
+    while ((frame = _framebuf_app.get_next_complete_frame()) != NULL) {
         for (int i = 0; i < MAX_FRAME_HANDLERS; i++) {
 
             if (_fhandlers[i] == NULL) {
@@ -753,12 +816,17 @@
 
             _fhandlers[i]->process_frame_data(frame);
         }
-            
+
         /* Once processed, remove the frame from the buffer */
-        _framebuf.free_frame(frame);
-    }    
+        _framebuf_app.free_frame(frame);
+    }
 
-    return _framebuf.get_dropped_frames_count();
+    const uint32_t dropped_frames = _framebuf_app.get_dropped_frames_count();
+    if (dropped_frames != 0) {
+        digi_log(LogLevelWarning, "process_rx_frames: %d frames dropped!!!\r\n", dropped_frames);
+    }
+
+    return dropped_frames;
 }
 
 void XBee::register_modem_status_cb(modem_status_cb_t function)
@@ -780,3 +848,14 @@
     }
 }
 
+int XBee::get_AI(void)
+{
+    uint32_t atai;
+    const AtCmdFrame::AtCmdResp status = get_param("AI", &atai);
+
+    if (status != AtCmdFrame::AtCmdRespOk) {
+        digi_log(LogLevelError, "get_association_indication() failed with %d\r\n", status);
+        return -1;
+    }
+    return atai;
+}
--- a/XBee/XBee.h	Mon May 18 13:16:55 2015 +0200
+++ b/XBee/XBee.h	Mon Jun 01 18:59:43 2015 +0200
@@ -47,44 +47,11 @@
  * @{
  */
 /**
- * RadioStatus 
+ * RadioStatus
  */
 enum RadioStatus {
     Success         = 0,    /**< Success */
     Failure         = -1,   /**< Failure */
-    OpNotSupported  = -2,   /**< Option Not Supported */
-};
-/**
- * @}
- */
-
-/**
- * @defgroup RadioType
- * @{
- */
-/**
- * RadioType 
- */
-enum RadioType {
-    Unknown     = 0,        /**< Not detected yet */
-    XB24_A_S1   = 0x17,     /**< S1 */
-    XBP24_A_S1  = 0x18,     /**< S1 */
-    XB24_B_S2   = 0x19,     /**< S2 */
-    XBP24_B_S2  = 0x1A,     /**< S2 */
-    XBP09_D     = 0x1B,     /**< S4 */
-    XBP09_XC    = 0x1C,     /**< S3 */
-    XBP08_D     = 0x1D,     /**< 868MHz S5 */
-    XBP24_B_S2B = 0x1E,     /**< S2B */
-    XB24_WF     = 0x1F,     /**< S6 */
-    XBP24_C_SMT = 0x21,     /**< XBee PRO SMT S2C */
-    XB24_C_SMT  = 0x22,     /**< XBee SMT S2C */
-    XBP09_XC_B  = 0x23,     /**< S3B */
-    XBP09_B     = 0x23,     /**< S3B */
-    XB8         = 0x24,     /**< S8 */
-    XB2B_WF_TH  = 0x27,     /**< S6B TH */
-    XB2B_WF_SMT = 0x28,     /**< S6B SMT */
-    XBP24_C_TH  = 0x2D,     /**< S2C TH */
-    XB24_C_TH   = 0x2E,     /**< S2C TH */
 };
 /**
  * @}
@@ -95,7 +62,7 @@
  * @{
  */
 /**
- * TxStatus 
+ * TxStatus
  */
 enum TxStatus {
     TxStatusSuccess            = 0,     /**< Success */
@@ -124,46 +91,11 @@
  */
 
 /**
- * @defgroup PmMode
- * @{
- */
-/**
- * PmMode 
- */
-enum PmMode {
-    SleepDisabled       = 0,  /**< SleepDisabled */
-    PinSleep            = 1,  /**< PinSleep */
-    PinDoze             = 2,  /**< PinDoze */
-    CyclicSeleep        = 4,  /**< CyclicSeleep */
-    CyclicSeleepPinW    = 5,  /**< CyclicSeleepPinW */
-};
-/**
- * @}
- */
- 
- /**
- * @defgroup NetworkRole
- * @{
- */
-/**
- * NetworkRole 
- */
-enum NetworkRole {
-    UnknownRole,            /**< Unknown Role */
-    Coordinator,            /**< Coordinator */
-    Router,                 /**< Router */
-    EndDevice,              /**< EndDevice */
-};
-/**
- * @}
- */
-
-/**
  * @defgroup RadioLocation
  * @{
  */
 /**
- * RadioLocation 
+ * RadioLocation
  */
 enum RadioLocation {
     RadioLocal     = 0,     /**< Local Radio */
@@ -172,7 +104,7 @@
 /**
  * @}
  */
- 
+
 /** Parent Class for XBee modules, not to be directly used */
 class XBee
 {
@@ -187,16 +119,14 @@
     RadioStatus wait_for_module_to_reset(volatile uint16_t *rst_cnt_p, uint16_t init_rst_cnt);
 
     protected:
-    /** timer used by local and remote objects */
-    static Timer        _timer;
-
     /** buffer to store the received frames */
-    static FrameBuffer _framebuf;
+    static FrameBuffer _framebuf_app;
+    static FrameBuffer _framebuf_syncr;
 
     public:
- 
+
         /**
-         * RadioMode 
+         * RadioMode
          */
         enum RadioMode {
             ModeUnknown     = 0,  /**< Unknown */
@@ -216,11 +146,11 @@
          * to this baud rate (ATBD parameter). By default it is configured to 9600 bps
          * */
         XBee(PinName tx, PinName rx, PinName reset = NC, PinName rts = NC, PinName cts = NC, int baud = 9600);
- 
+
         XBee(const XBee& other); /* Intentionally not implemented */
         /** Class destructor */
         virtual ~XBee();
-        
+
         /** init-  initializes object
          * This function must be called just after creating the object so it initializes internal data.
          * @returns
@@ -235,12 +165,6 @@
          */
         uint64_t get_addr64() const;
 
-        /** get_addr16 - returns the 16bit address of the local device
-         *
-         *  @returns the 16-bit address of the local device.
-         */
-        uint16_t get_addr16() const;
-
         /** get_network_address - gets the 16bit network address of the device
          *
          *  @param addr pointer where the device 16bit network address will be stored
@@ -266,8 +190,8 @@
          *     Failure otherwise
          */
         RadioStatus software_reset();
- 
-        /** device_reset - performs a hardware reset if there is a GPIO connected to the 
+
+        /** device_reset - performs a hardware reset if there is a GPIO connected to the
          * reset line of the device. Otherwise, performs a firmware reset.
          *
          *  @returns
@@ -279,12 +203,6 @@
 #endif
         RadioStatus device_reset();
 
-        /** get_radio_type - returns the type of radio, in most cases the hardware version
-         *
-         *  @returns the radio type
-         */
-        RadioType get_radio_type() const;
-
         /** set_tx_options - sets the transmit options byte, used with the transmit frames.
          *                   Valid flags are:
          *                       - DISABLE_RETRIES_AND_ROUTE_REPAIR
@@ -295,24 +213,11 @@
          */
         void set_tx_options(uint8_t options);
 
-        /** set_broadcast_radius - sets the max number of hops for a broadcast msg.
-         *                         When set to 0 uses the maximum possible.
-         *
-         *  @param bc_radius variable with the broadcast radious
-         */
-        void set_broadcast_radius(uint8_t bc_radius);
-
         /** get_tx_options - returns the tx options byte configured in the library.
          *
          *  @returns the tx options byte configured in the library.
          */
         uint8_t get_tx_options() const;
-        
-        /** get_bc_radius - returns the broadcast radius configured in the library.
-         *
-         *  @returns the broadcast radius configured in the library.
-         */
-        uint8_t get_bc_radius() const;
 
         /************************ Configuration member methods *************************/
         /** write_config - write settings to non volatile memory
@@ -322,7 +227,7 @@
          *     Failure otherwise
          */
         RadioStatus write_config();
-       
+
         /** config_io_sample_destination - configures to which node a remote module will send its IO Samples to.
          * @Note: this will modify 'remote' DH and DL parameters, if the remote node is configured in transparent mode this could lead to unwanted behavior.
          * Consult the module's reference manual for more information.
@@ -362,13 +267,13 @@
          *     Failure otherwise
          */
         RadioStatus get_power_level(uint8_t * const level);
-        
+
         /** get_hw_version - gets the hardware version of the radio
          *
          *  @returns the hardware version of the radio
          */
         uint16_t get_hw_version() const;
-        
+
         /** get_fw_version - gets the firmware version of the radio
          *
          *  @returns the firmware version of the radio
@@ -393,9 +298,28 @@
          */
         RadioStatus get_node_identifier(char * const node_id);
 
+        /** enable_network_encryption - Enable network encryption.
+         *
+         *  @param enable whether to enable this feature or not
+         *  @returns
+         *     Success if the operation was successful,
+         *     Failure otherwise
+         */
+        RadioStatus enable_network_encryption(bool enable);
+
+        /** set_network_encryption_key - Sets the 128-bit AES key used for encryption and decryption. Setting it to 0 will cause the coordinator to transmit the network key in the clear to joining devices, and will cause joining devices to acquire the network key in the clear when joining.
+         *  It is not recommended to set the key programmatically, because it could be read through the raw serial port bits.
+         *  @param key pointer to the 128-bit AES key
+         *  @param length size of the buffer pointed by 'key'
+         *  @returns
+         *     Success if the operation was successful,
+         *     Failure otherwise
+         */
+        RadioStatus set_network_encryption_key(const uint8_t * const key, const uint16_t length);
+
         /** start_node_discovery - starts a node discovery operation. The responses
          * have to be processes on the callback function that have to be registered
-         * for that purpose
+         * for that purpose.
          *
          *  @returns
          *     Success if the operation was successful,
@@ -403,6 +327,11 @@
          */
         RadioStatus start_node_discovery();
 
+        /** is_node_discovery_in_progress - checks if node discovery is in progress.
+         *  @returns true if node discovery is in progress, false otherwise
+         */
+        bool is_node_discovery_in_progress();
+
 #define XBEEZB_ND_OPTION_APPEND_DD          (1 << 0)
 #define XBEEZB_ND_OPTION_SELF_RESPONSE      (1 << 1)
 #define XBEE802_ND_OPTION_SELF_RESPONSE     (1 << 0)
@@ -437,7 +366,7 @@
          *  @param timeout_ms new timeout in ms
          */
         void set_timeout(uint16_t timeout_ms);
-        
+
         /** get_timeout - gets the timeout in ms configured in the library. This value
          *                is used in sync commands
          *
@@ -445,7 +374,7 @@
          */
         uint16_t get_timeout() const;
 
-        /* ... */     
+        /* ... */
 
         /*********************** send_data member methods ************************/
         /** send_data - sends data to a remote device
@@ -459,7 +388,7 @@
          *     the error code otherwise
          */
         virtual TxStatus send_data(const RemoteXBee& remote, const uint8_t *const data, uint16_t len, bool syncr = true) = 0;
-        
+
         /** send_data_broadcast - sends data to all devices in the network, using the broadcast address.
          *
          *  @param data pointer to the data that will be sent
@@ -470,7 +399,7 @@
          *     the error code otherwise
          */
         TxStatus send_data_broadcast(const uint8_t *const data, uint16_t len, bool syncr = true);
-        
+
         /** set_param - sets a parameter in the local radio by sending an AT command and waiting for the response.
          *
          *  @param param parameter to be set.
@@ -478,29 +407,29 @@
          *  @returns the command response status.
          */
         AtCmdFrame::AtCmdResp set_param(const char * const param, uint32_t data);
-        
+
         /** set_param - sets a parameter in the local radio by sending an AT command and waiting for the response.
          *
          *  @param param parameter to be set.
-         *  @param data the parameter value byte array (len bytes) to be set. 
-         *  @param len number of bytes of the parameter value. 
+         *  @param data the parameter value byte array (len bytes) to be set.
+         *  @param len number of bytes of the parameter value.
          *  @returns the command response status.
          */
         AtCmdFrame::AtCmdResp set_param(const char * const param, const uint8_t * data = NULL, uint16_t len = 0);
-        
+
         /** get_param - gets a parameter from the local radio by sending an AT command and waiting for the response.
          *
          *  @param param parameter to be get.
-         *  @param data pointer where the param value (4 bytes) will be stored. 
+         *  @param data pointer where the param value (4 bytes) will be stored.
          *  @returns the command response status.
          */
         AtCmdFrame::AtCmdResp get_param(const char * const param, uint32_t * const data);
-      
+
         /** get_param - gets a parameter from the local radio by sending an AT command and waiting for the response.
          *
          *  @param param parameter to be get.
-         *  @param data pointer where the param value (n bytes) will be stored. 
-         *  @param len pointer where the number of bytes of the param value will be stored. 
+         *  @param data pointer where the param value (n bytes) will be stored.
+         *  @param len pointer where the number of bytes of the param value will be stored.
          *  @returns the command response status.
          */
         AtCmdFrame::AtCmdResp get_param(const char * const param, uint8_t * const data, uint16_t * const len);
@@ -513,110 +442,37 @@
          *  @returns the command response status.
          */
         virtual AtCmdFrame::AtCmdResp set_param(const RemoteXBee& remote, const char * const param, uint32_t data) = 0;
-        
+
         /** set_param - sets a parameter in a remote radio by sending an AT command and waiting for the response.
          *
          *  @param remote remote device
          *  @param param parameter to be set.
-         *  @param data the parameter value byte array (len bytes) to be set. 
+         *  @param data the parameter value byte array (len bytes) to be set.
          *  @param len number of bytes of the parameter value.
          *  @returns the command response status.
          */
         virtual AtCmdFrame::AtCmdResp set_param(const RemoteXBee& remote, const char * const param, const uint8_t * data = NULL, uint16_t len = 0) = 0;
-        
+
         /** get_param - gets a parameter from a remote radio by sending an AT command and waiting for the response.
          *
          *  @param remote remote device
          *  @param param parameter to be get.
-         *  @param data pointer where the param value (4 bytes) will be stored. 
+         *  @param data pointer where the param value (4 bytes) will be stored.
          *  @returns the command response status.
          */
         virtual AtCmdFrame::AtCmdResp get_param(const RemoteXBee& remote, const char * const param, uint32_t * const data) = 0;
-      
+
         /** get_param - gets a parameter from a remote radio by sending an AT command and waiting for the response.
          *
          *  @param remote remote device
          *  @param param parameter to be get.
-         *  @param data pointer where the param value (n bytes) will be stored. 
-         *  @param len pointer where the number of bytes of the param value will be stored. 
+         *  @param data pointer where the param value (n bytes) will be stored.
+         *  @param len pointer where the number of bytes of the param value will be stored.
          *  @returns the command response status.
          */
         virtual AtCmdFrame::AtCmdResp get_param(const RemoteXBee& remote, const char * const param, uint8_t * const data, uint16_t * const len) = 0;
 
-#if defined(ENABLE_PM_SUPPORT)
-        /** set_pm_control - sets the operational mode of the Power Management on
-         *                   the radio and registers the GPIOs used to handle the
-         *                   Power Management
-         *
-         *  @param mode operational mode of the power management
-         *  @param on_sleep pin used to detect the on/sleep status of the module
-         *  @param sleep_rq pin used to request the module to go to sleep (when pin
-         *         sleep mode is used
-         *  @returns the result of the configuration operation
-         *     Success if the operation was successful,
-         *     Failure otherwise
-         */
-         RadioStatus set_pm_control(PmMode mode, PinName on_sleep = NC, PinName sleep_rq = NC);
-
-        /** get_pm_mode - gets the power management mode programmed in the radio.
-         *
-         *  @param mode pointer where the read mode will be stored.
-         *  @returns the result of the configuration operation
-         *     Success if the operation was successful,
-         *     Failure otherwise
-         */
-         RadioStatus get_pm_mode(PmMode *mode);
-
-        /** config_pm_timing - configures the power management timing parameters.
-         *
-         *  @param before_sleep_ms number of miliseconds of inactivity before the radio will
-         *                         automatically go to sleep again (when using cyclic sleep).
-         *  @param total_sleep_period_ms time interval in ms the radio will be sleeping. Once
-         *                               this time passes, the radio will wakeup, will check for
-         *                               packets and will wait before_sleep_ms of inactivity
-         *                               before entering again in sleep mode.
-         *  @returns the result of the configuration operation
-         *     Success if the operation was successful,
-         *     Failure otherwise
-         */
-         RadioStatus config_pm_timing(uint32_t before_sleep_ms, uint32_t total_sleep_period_ms);
-
-        /** enter_sleep_mode - sets the radio into low power mode. If the pm working mode
-         *                     is pin-sleep, then it will use the GPIO, otherwise, it will
-         *                     use the serial interface.
-         *
-         *  @note the method does not wait until the radio enters in sleep mode, it returns
-         *        without making any verification.
-         *  @returns the result of the operation
-         *     Success if the operation was successful,
-         *     Failure otherwise
-         */
-         RadioStatus enter_sleep_mode();
-
-        /** exit_sleep_mode - for the pm mode called pin-sleep, sets the radio into active power
-         *                    using the corresponding GPIO.
-         *
-         */
-         void exit_sleep_mode();
-
-        /** is_sleeping - checks if the radio is sleeping or if its active.
-         *
-         *  @returns true if the radio is sleeping, false otherwisw
-         */
-         bool is_sleeping();
-         
-        /** register_wakeup_cb - registers the callback function that will be called
-         *                       when the radio wakes up from sleep mode.
-         *
-         *  @param f function pointer with the callback function
-         */
-        void register_wakeup_cb(void (*f)(void));
-
-        /** unregister_wakeup_cb - removes the wakeup callback */
-        void unregister_wakeup_cb();
-#endif  /* defined(ENABLE_PM_SUPPORT) */
-
-        /** process_rx_frames - method that process the frames queued in the reception
+        /** process_rx_frames - method that processes the frames queued in the reception
          *                      buffer. Calls the process_frame_data method of the frame
          *                      handlers registered
          *
@@ -648,20 +504,20 @@
             ZNet,
 #endif
         };
-        /** send_byte_escaping_if - sends a byte, through the serial interface, to 
+        /** send_byte_escaping_if - sends a byte, through the serial interface, to
          * the radio, escaping the byte if the working mode of the radio is API2.
          *
          *  @param line PWM line being set
          *  @param data the byte that will be send to radio
          */
         void send_byte_escaping_if(uint8_t data);
-    
+
         /** uart_read_cb - serial interface callback, called when data is received on
          * the serial port. The function parses the incoming data and, when a good
          * frame is detected, saves it in the frame list
          */
         void uart_read_cb();
-    
+
         /** get_this_api_frame - searches in the FrameBuffer for an incoming frame
          *                       with frameid equal to id and frame type equal to type
          *                       or type2. If after timeout the frame hast not been found,
@@ -670,14 +526,14 @@
          *  @param id id of the frame we are looking for.
          *  @param type tye type we expect the frame to be.
          *  @param type2 alternative valid type, if provided.
-         *  @returns a pointer to the frame found in the FrameBuffer or a null pointer if 
+         *  @returns a pointer to the frame found in the FrameBuffer or a null pointer if
          *           the frame has not been found and the timeout expired.
          */
-        ApiFrame * get_this_api_frame(uint8_t id, ApiFrame::ApiFrameType type, 
+        ApiFrame * get_this_api_frame(uint8_t id, ApiFrame::ApiFrameType type,
                     ApiFrame::ApiFrameType type2 = ApiFrame::Invalid);
 
         /** send_api_frame - method to send, over the serial port, an API frame
-         * 
+         *
          * @param frame pointer to the frame that will be sent.
          */
 #if defined(UNIT_TEST)
@@ -687,15 +543,15 @@
 
         /** update_radio_status - method called when a modem status frame is received
          *  to update the internal status variables of the library.
-         *  @note This is not a pure virtual function because it can be called while 
+         *  @note This is not a pure virtual function because it can be called while
          *        the object is being constructed and we need the implementation of the
-         *        base class.         
+         *        base class.
          *
          *  @param status byte with the status received in the modem status frame
          */
         virtual void radio_status_update(AtCmdFrame::ModemStatus modem_status);
-        
-        /** Method used internaly by the derived classes to transmit data to 
+
+        /** Method used internaly by the derived classes to transmit data to
          * remote nodes, waiting for the answer from the device
          *
          *  @param frame frame that will be sent to the radio (have to be a
@@ -709,25 +565,20 @@
         /** send_at_cmd - sends an AT command to the radio and waits for the response.
          *
          *  @param frame api frame with the command and command params.
-         *  @param buf pointer where the param response (n bytes) will be stored. 
-         *  @param len pointer where the number of bytes of the param response will be stored. 
-         *  @param radio_location radio location, either RadioLocal or RadioRemote. 
-         *  @param reverse reverse the byte ordering of the response saved in buf. 
+         *  @param buf pointer where the param response (n bytes) will be stored.
+         *  @param len pointer where the number of bytes of the param response will be stored.
+         *  @param radio_location radio location, either RadioLocal or RadioRemote.
+         *  @param reverse reverse the byte ordering of the response saved in buf.
          *  @returns the command response status.
          */
         AtCmdFrame::AtCmdResp send_at_cmd(AtCmdFrame *frame,
                     uint8_t *const buf, uint16_t *const len, RadioLocation radio_location = RadioLocal, bool reverse = true);
-                    
+
         /* send_at_cmd - methods used internally by other methods */
         AtCmdFrame::AtCmdResp send_at_cmd(AtCmdFrame *frame);
         AtCmdFrame::AtCmdResp send_at_cmd(AtCmdFrame *frame, uint8_t *data);
         AtCmdFrame::AtCmdResp send_at_cmd(AtCmdFrame *frame, uint16_t *data);
         AtCmdFrame::AtCmdResp send_at_cmd(AtCmdFrame *frame, uint32_t *data);
-        
-#if defined(ENABLE_PM_SUPPORT)
-        /** Sets the radio into low power mode. This method is used by enter_sleep_mode() */
-        RadioStatus sleep_now();
-#endif  /* defined(ENABLE_PM_SUPPORT) */
 
         /** register_frame_handler - registers an object to handle incoming frames from
          *                           the radio.
@@ -777,15 +628,20 @@
          */
         bool check_radio_flow_control();
 
+        /** get_AI - reads the AI parameter.
+         *
+         *  @returns
+         *      -1 if an error occurred when reading AI.
+         *      0-0xFF the AI value.
+         */
+        int get_AI(void);
+
         /** serial hardware flow control selected by the user (RTSCTS, RTS,CTS) */
         SerialBase::Flow _serial_flow_type;
 
         /** Operating mode of the module (API1, API2,...) */
         RadioMode   _mode;
 
-        /** Type of radio, mainly the hardware version, but may differ in some cases */
-        RadioType   _type;
-        
         /** Hardware version value of the radio */
         uint16_t    _hw_version;
 
@@ -793,28 +649,22 @@
         uint16_t    _fw_version;
 
         /** Timeout in ms for sync operations (when we wait for a response) */
-        uint16_t    _timeout_ms;     
+        uint16_t    _timeout_ms;
 
         /** Device 64 bit address (SH, SL) */
         uint64_t      _dev_addr64;
 
-        /** Device 16 bit address (MY) */        
-        uint16_t    _dev_addr16;
-       
         /** Serial Interface, use RawSerial as we dont use the streams */
         RawSerial   *_uart;
 
         /** IO connected to the radio reset line */
-        DigitalOut  *_reset;         
-        
+        DigitalOut  *_reset;
+
         /** Transmit options byte */
         uint8_t     _tx_options;
 
-        /** Broadcast radius, number of hops a broadcast transmission can occur.
-         *  When set to 0 it will use the maximum */
-        uint8_t     _bc_radius;
-        /** Array of frame handler pointers. We use an array instead of a vector or other 
-         *  data structure to save memory and avoid dynamic memory allocation, to avoid 
+        /** Array of frame handler pointers. We use an array instead of a vector or other
+         *  data structure to save memory and avoid dynamic memory allocation, to avoid
          *  memory fragmentation */
         FrameHandler *_fhandlers[MAX_FRAME_HANDLERS];
 
@@ -824,8 +674,6 @@
         /** Watchdog reset counter, automatically updated by the library */
         volatile uint16_t    _wd_reset_cnt;
 
-        uint16_t    _reset_timeout;
-
         /** Frame handler used for the Modem Status packets. Automatically registered when a callback
          *  function is registered */
         FH_ModemStatus  *_modem_status_handler;
@@ -836,14 +684,14 @@
         /** Library is initializing */
         bool _initializing;
 
-#if defined(ENABLE_PM_SUPPORT)
-        /* Power Management mode used by the radio */
-        PmMode      _pm_mode;
-        /** IO connected to the radio on_sleep line */
-        InterruptIn *_on_sleep;         
-        /** IO connected to the radio sleep_req line */
-        DigitalOut  *_sleep_req;
-#endif
+        /** Timer used for node discovery */
+        Timer _nd_timer;
+
+        /** node discovery timeout */
+        int _nd_timeout;
+
+        /** If a _get_remote_node_by_id() is in progress, this keeps the expected frame id */
+        uint8_t _node_by_ni_frame_id;
 };
 
 }   /* namespace XBeeLib */
--- a/XBee802/XBee802.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/XBee802/XBee802.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -19,11 +19,10 @@
 /* Class constructor */
 XBee802::XBee802(PinName tx, PinName rx, PinName reset, PinName rts, PinName cts, int baud) :
         XBee(tx, rx, reset, rts, cts, baud),
-        _sync_lost_cnt(0), _nd_handler(NULL), _rx_64b_handler(NULL), _rx_16b_handler(NULL),
+        _nd_handler(NULL), _rx_64b_handler(NULL), _rx_16b_handler(NULL),
         _io_data_64b_handler(NULL), _io_data_16b_handler(NULL)
 {
 
-    _reset_timeout = RESET_TIMEOUT_MS;
 }
 
 /* Class destructor */
@@ -37,6 +36,14 @@
 RadioStatus XBee802::init()
 {
     RadioStatus retval = XBee::init();
+    uint16_t addr16;
+    RadioStatus error = get_network_address(&addr16);
+    if (error == Success) {
+        digi_log(LogLevelInfo, "ADDR16: %04x\r\n", addr16);
+    } else {
+        digi_log(LogLevelInfo, "ADDR16: UNKNOWN\r\n");
+    }
+
     const RadioProtocol radioProtocol = get_radio_protocol();
     if (radioProtocol != Raw_802_15_4) {
         digi_log(LogLevelError, "Radio protocol does not match, needed a %d got a %d\r\n", Raw_802_15_4, radioProtocol);
@@ -77,8 +84,9 @@
 
     uint32_t var32;
     cmdresp = get_param("CH", &var32);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
+    if (cmdresp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
+    }
     *channel = var32;
     return Success;
 }
@@ -103,8 +111,9 @@
 
     uint32_t var32;
     cmdresp = get_param("ID", &var32);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
+    if (cmdresp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
+    }
     *panid = var32;
     return Success;
 }
@@ -123,15 +132,14 @@
 void XBee802::radio_status_update(AtCmdFrame::ModemStatus modem_status)
 {
     /* Update the radio status variables */
-    if (modem_status == AtCmdFrame::HwReset)
+    if (modem_status == AtCmdFrame::HwReset) {
         _hw_reset_cnt++;
-    else if (modem_status == AtCmdFrame::WdReset)
+    } else if (modem_status == AtCmdFrame::WdReset) {
         _wd_reset_cnt++;
-    else if (modem_status == AtCmdFrame::SyncLost)
-        _sync_lost_cnt++;
+    }
 
     _modem_status = modem_status;
-    
+
     digi_log(LogLevelDebug, "\r\nUpdating radio status: %02x\r\n", modem_status);
 }
 
@@ -172,10 +180,16 @@
     return TxStatusInvalidAddr;
 }
 
+XBee802::AssocStatus XBee802::get_assoc_status(void)
+{
+    return (AssocStatus)get_AI();
+}
+
 RemoteXBee802 XBee802::get_remote_node_by_id(const char * const node_id)
 {
     uint64_t addr64;
     uint16_t addr16;
+
     _get_remote_node_by_id(node_id, &addr64, &addr16);
     return RemoteXBee802(addr64, addr16);
 }
@@ -419,21 +433,18 @@
 {
     AtCmdFrame::AtCmdResp cmdresp;
     char iocmd[3] = { 'M', '0', '\0' };
-    
+
     if (line != PWM0 && line != PWM1) {
         return Failure;
     }
     if (line == PWM1) {
         iocmd[1] = '1';
     }
-        
+
     uint16_t pwm_val = (uint16_t)(duty_cycle * DR_PWM_MAX_VAL / 100);
 
     cmdresp = set_param(remote, iocmd, pwm_val);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
-        return Failure;
-    
-    return Success;
+    return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
 }
 
 IOSample802 XBee802::get_iosample(const RemoteXBee& remote)
@@ -478,8 +489,9 @@
     uint8_t pr;
 
     cmdresp = get_param(remote, "PR", &var32);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
+    if (cmdresp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
+    }
     pr = var32;
 
     const uint8_t dio_mask = get_dio_mask(line);
@@ -495,10 +507,7 @@
     }
 
     cmdresp = set_param(remote, "PR", pr);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
-        return Failure;
-
-    return Success;
+    return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
 }
 
 static uint8_t get_dio_ic_mask(XBee802::IoLine line)
@@ -539,29 +548,29 @@
     }
 
     cmdresp = set_param(remote, "IC", ic);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
-        return Failure;
+    return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
+}
 
-    return Success;
-}
-    
 #ifdef GET_PWM_AVAILABLE
 RadioStatus XBee802::get_pwm(const RemoteXBee& remote, IoLine line, float * const duty_cycle)
 {
     AtCmdFrame::AtCmdResp cmdresp;
     char iocmd[3] = { 'M', '0', '\0' };
-    
-    if (line != PWM0 && line != PWM1)
+
+    if (line != PWM0 && line != PWM1) {
         return Failure;
+    }
 
-    if (line == PWM1)
+    if (line == PWM1) {
         iocmd[1] = '1';
-        
+    }
+
     uint16_t pwm_val;
 
     cmdresp = get_param(remote, iocmd, &pwm_val);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
+    if (cmdresp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
+    }
 
     *duty_cycle = (float)(pwm_val * 100 / DR_PWM_MAX_VAL);
 
--- a/XBee802/XBee802.h	Mon May 18 13:16:55 2015 +0200
+++ b/XBee802/XBee802.h	Mon Jun 01 18:59:43 2015 +0200
@@ -41,7 +41,29 @@
             PWM0,         /**< PWM0 pin */
             PWM1           /**< PWM1 pin */
         };
-  
+
+        enum AssocStatus {
+            ErrorReading        = -1,       /**< Error occurred when reading parameter. */
+            Joined              = 0x00,     /**< Successful Completion - Coordinator successfully started or End Device association complete. */
+            ActiveScanTimeOut   = 0x01,     /**< Active Scan Timeout. */
+            NoPANs              = 0x02,     /**< Active Scan found no PANs. */
+            JoinNotAllowed      = 0x03,     /**< Active Scan found PAN, but the Coordinator's Allow Association bit is not set. */
+            BeaconsFailed       = 0x04,     /**< Active Scan found PAN, but Coordinator and End Device are not configured to support beacons. */
+            BadPAN              = 0x05,     /**< Active Scan found PAN, but Coordinator ID (PAN ID) value does not match the ID of the End Device. */
+            BadChannel          = 0x06,     /**< Active Scan found PAN, but Coordinator CH (Channel) value does not match the CH of the End Device */
+            EnergyScanTimeout   = 0x07,     /**< Energy Scan timed out. */
+            CoordStartFailed    = 0x08,     /**< Coordinator start request failed. */
+            CoordBadParameters  = 0x09,     /**< Coordinator could not start due to Invalid Parameter. */
+            CoordRealignment    = 0x0A,     /**< Coordinator Realignment is in progress. */
+            AssocReqNotSent     = 0x0B,     /**< Association Request not sent. */
+            AssocReqTimeout     = 0x0C,     /**< Association Request timed out - no reply was received. */
+            AssocReqInvalidPara = 0x0D,     /**< Association Request had an Invalid Parameter. */
+            AssocReqChannelFail = 0x0E,     /**< Association Request Channel Access Failure - Request was not transmitted - CCA failure. */
+            RemCoordNoACK       = 0x0F,     /**< Remote Coordinator did not send an ACK after Association Request was sent. */
+            RemCoordLateACK     = 0x10,     /**< Remote Coordinator did not reply to the Association Request, but an ACK was received after sending the request. */
+            Associating         = 0xFF      /**< RF Module is attempting to associate. */
+        };
+
         /** Class constructor
          * @param tx the TX pin of the UART that will interface the XBee module
          * @param rx the RX pin of the UART that will interface the XBee module
@@ -52,10 +74,10 @@
          * to this baud rate (ATBD parameter). By default it is configured to 9600 bps
          */
         XBee802(PinName tx, PinName rx, PinName reset = NC, PinName rts = NC, PinName cts = NC, int baud = 9600);
- 
+
         /** Class destructor */
         virtual ~XBee802();
-        
+
         /** init -  initializes object
          * This function must be called just after creating the object so it initializes internal data.
          * @returns
@@ -64,7 +86,7 @@
          */
         RadioStatus init();
 
-        /** set_panid - sets the 16 bit PAN ID.        
+        /** set_panid - sets the 16 bit PAN ID.
          *
          *  @param panid the PAN ID value that will be set on the radio
          *  @returns
@@ -72,7 +94,7 @@
          *     Failure otherwise
          */
         RadioStatus set_panid(uint16_t panid);
-        
+
         /** get_panid - gets the configured 16 bit PAN ID
          *
          *  @param panid pointer where the read PAN ID value will be stored
@@ -81,7 +103,7 @@
          *     Failure otherwise
          */
         RadioStatus get_panid(uint16_t * const panid);
-        
+
         /** set_channel - sets the network channel number
          *
          *  @param channel the channel in which the radio operates. Range is 0x0B - 0x1A for XBee and 0x0C - 0x17 for XBee-PRO.
@@ -129,7 +151,7 @@
 
         /** unregister_receive_cb - removes the rx packet callback */
         void unregister_receive_cb();
-        
+
         /** register_io_sample_cb - registers the callback function that will be called
          * when a IO Sample Data packet is received
          *
@@ -153,6 +175,12 @@
          */
         virtual TxStatus send_data(const RemoteXBee& remote, const uint8_t *const data, uint16_t len, bool syncr = true);
 
+        /** get_assoc_status - returns current network association status. This wraps AI parameter, for more information refer to moudle's Reference Manual.
+         *
+         *  @returns an AssocStatus with current network association status.
+         */
+        AssocStatus get_assoc_status(void);
+
         /** get_remote_node_by_id - searches for a device in the network with the specified Node Identifier.
          *
          *  @param node_id node id of the device we are looking for
@@ -172,12 +200,12 @@
          *  @returns the command response status.
          */
         virtual AtCmdFrame::AtCmdResp set_param(const RemoteXBee& remote, const char * const param, uint32_t data);
-        
+
         /** set_param - sets a parameter in a remote radio by sending an AT command and waiting for the response.
          *
          *  @param remote remote device
          *  @param param parameter to be set.
-         *  @param the parameter value byte array (len bytes) to be set. 
+         *  @param the parameter value byte array (len bytes) to be set.
          *  @param len number of bytes of the parameter value.
          *  @returns the command response status.
          */
@@ -185,22 +213,22 @@
 
         /* Allow using XBee::get_param() methods for local radio from this class */
         using XBee::get_param;
-        
+
         /** get_param - gets a parameter from a remote radio by sending an AT command and waiting for the response.
          *
          *  @param remote remote device
          *  @param param parameter to be get.
-         *  @param data pointer where the param value (4 bytes) will be stored. 
+         *  @param data pointer where the param value (4 bytes) will be stored.
          *  @returns the command response status.
          */
         virtual AtCmdFrame::AtCmdResp get_param(const RemoteXBee& remote, const char * const param, uint32_t * const data);
-      
+
         /** get_param - gets a parameter from a remote radio by sending an AT command and waiting for the response.
          *
          *  @param remote remote device
          *  @param param parameter to be get.
-         *  @param data pointer where the param value (n bytes) will be stored. 
-         *  @param len pointer where the number of bytes of the param value will be stored. 
+         *  @param data pointer where the param value (n bytes) will be stored.
+         *  @param len pointer where the number of bytes of the param value will be stored.
          *  @returns the command response status.
          */
         virtual AtCmdFrame::AtCmdResp get_param(const RemoteXBee& remote, const char * const param, uint8_t * const data, uint16_t * const len);
@@ -323,17 +351,14 @@
             return (_hw_version & 0xFF00U) == 0x1800U;
         }
 
-        /** Synchronization lost counter, automatically updated by the library */
-        volatile uint16_t    _sync_lost_cnt;
-
         /** Frame handler used for the node discovery. Registered when a callback function
          * is registered */
         FH_NodeDiscovery802  *_nd_handler;
-        
+
          /** Frame handler used for the rx 64 bit packets. Automatically registered when a callback
-         *  function is registered */         
+         *  function is registered */
         FH_RxPacket64b802  *_rx_64b_handler;
-        
+
          /** Frame handler used for the rx 16 bit packets. Automatically registered when a callback
          *  function is registered */
         FH_RxPacket16b802  *_rx_16b_handler;
@@ -346,13 +371,13 @@
         *  function is registered */
         FH_IoDataSampe16b802  *_io_data_16b_handler;
 
-        /** Method called directly by the library when a modem status frame is received to 
+        /** Method called directly by the library when a modem status frame is received to
          * update the internal status variables */
         virtual void radio_status_update(AtCmdFrame::ModemStatus modem_status);
 
         /* Allow using XBee::send_data() methods from this class */
         using XBee::send_data;
-    
+
     private:
 
 };
--- a/XBeeLib.h	Mon May 18 13:16:55 2015 +0200
+++ b/XBeeLib.h	Mon Jun 01 18:59:43 2015 +0200
@@ -9,19 +9,19 @@
  * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
  * =======================================================================
  */
- 
+
 /** @file
  */
 
 #ifndef __XBEE_H_
 #define __XBEE_H_
 
-#define XB_LIBRARY_VERSION          0x00010500U
+#define XB_LIBRARY_VERSION          0x01000007U
 #define XB_MAJOR_VERSION            ((XB_LIBRARY_VERSION >> 24) & 0xFFU)
 #define XB_MINOR_VERSION            ((XB_LIBRARY_VERSION >> 16) & 0xFFU)
 #define XB_PATCH_LEVEL              ((XB_LIBRARY_VERSION >> 8) & 0xFFU)
 #define XB_BUILD_ID                 (XB_LIBRARY_VERSION & 0xFFU)
- 
+
 /**/
 #define XB_LIB_BANNER               "\r\n\r\n" "mbed Digi International Inc., XBeeLib v%d.%d.%d" "\r\n", \
                                         XB_MAJOR_VERSION, XB_MINOR_VERSION, XB_PATCH_LEVEL
--- a/XBeeZB/XBeeZB.cpp	Mon May 18 13:16:55 2015 +0200
+++ b/XBeeZB/XBeeZB.cpp	Mon Jun 01 18:59:43 2015 +0200
@@ -16,33 +16,17 @@
 
 using namespace XBeeLib;
 
+#define BROADCAST_RADIUS_USE_NH 0x00
+
 /* Class constructor */
 XBeeZB::XBeeZB(PinName tx, PinName rx, PinName reset, PinName rts, PinName cts, int baud) :
-         XBee(tx, rx, reset, rts, cts, baud), _nw_role(UnknownRole), _joined_network(false),
-        _vcc_exceeded_cnt(0), _broadcast_radious(0), _nd_handler(NULL), 
-        _rx_pkt_handler(NULL), _io_data_handler(NULL)
+         XBee(tx, rx, reset, rts, cts, baud), _nd_handler(NULL), _rx_pkt_handler(NULL), _io_data_handler(NULL)
 {
-    _reset_timeout = RESET_TIMEOUT_MS;
 }
 
 RadioStatus XBeeZB::init()
 {
     RadioStatus retval = XBee::init();
-    /* Determine the role of this device in the network */
-    switch(_fw_version & 0xFF00) {
-        case 0x2100:
-            _nw_role = Coordinator;
-            break;
-        case 0x2300:
-            _nw_role = Router;
-            break;
-        case 0x2900:
-            _nw_role = EndDevice;
-            break;
-        default:
-            _nw_role = UnknownRole;
-            break;
-    }
 
     const RadioProtocol radioProtocol = get_radio_protocol();
     if (radioProtocol != ZigBee) {
@@ -82,8 +66,9 @@
 
     uint32_t var32;
     cmdresp = get_param("SC", &var32);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
+    if (cmdresp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
+    }
     *chmask = var32;
     return Success;
 }
@@ -205,45 +190,18 @@
     AtCmdFrame::AtCmdResp cmdresp;
 
     cmdresp = set_param("JV", (uint8_t)enable);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
-        return Failure;
-    return Success;
+    return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
 }
 
-RadioStatus XBeeZB::enable_network_encryption(bool enable)
+RadioStatus XBeeZB::set_network_security_key(const uint8_t * const key, const uint16_t length)
 {
-    AtCmdFrame::AtCmdResp cmdresp;
-
-    cmdresp = set_param("EE", enable);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
-        return Failure;
-    return Success;
-}
-
-RadioStatus XBeeZB::set_encryption_key(const uint8_t * const key, const uint16_t length)
-{
-    if (key == NULL || length == 0) {
+    if (key == NULL || length == 0 || length > 16) {
         return Failure;
     }
     AtCmdFrame::AtCmdResp cmdresp;
 
     cmdresp = set_param("NK", key, length);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
-        return Failure;
-    return Success;
-}
-
-RadioStatus XBeeZB::set_tc_link_key(const uint8_t * const key, const uint16_t length)
-{
-    if (key == NULL || length == 0) {
-        return Failure;
-    }
-    AtCmdFrame::AtCmdResp cmdresp;
-
-    cmdresp = set_param("KY", key, length);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
-        return Failure;
-    return Success;
+    return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
 }
 
 RadioStatus XBeeZB::set_encryption_options(const uint8_t options)
@@ -251,9 +209,7 @@
     AtCmdFrame::AtCmdResp cmdresp;
 
     cmdresp = set_param("EO", options);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
-        return Failure;
-    return Success;
+    return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
 }
 
 void XBeeZB::radio_status_update(AtCmdFrame::ModemStatus modem_status)
@@ -261,18 +217,9 @@
     /* Update the radio status variables */
     if (modem_status == AtCmdFrame::HwReset) {
         _hw_reset_cnt++;
-        _joined_network = false;
-    }
-    else if (modem_status == AtCmdFrame::WdReset) {
+    } else if (modem_status == AtCmdFrame::WdReset) {
         _wd_reset_cnt++;
-        _joined_network = false;
     }
-    else if (modem_status == AtCmdFrame::JoinedNW)
-        _joined_network = true;
-    else if (modem_status == AtCmdFrame::Disassociated)
-        _joined_network = false;
-    else if (modem_status == AtCmdFrame::VccExceeded)
-        _vcc_exceeded_cnt++;
 
     _modem_status = modem_status;
 
@@ -281,13 +228,14 @@
 
 TxStatus XBeeZB::send_data(const RemoteXBee& remote, const uint8_t *const data, uint16_t len, bool syncr)
 {
-    if (!remote.is_valid_addr64b())
+    if (!remote.is_valid_addr64b()) {
         return TxStatusInvalidAddr;
+    }
 
     const uint64_t remote64 = remote.get_addr64();
     const uint16_t remote16 = remote.get_addr16();
 
-    TxFrameZB frame = TxFrameZB(remote64, remote16, _broadcast_radious,
+    TxFrameZB frame = TxFrameZB(remote64, remote16, BROADCAST_RADIUS_USE_NH,
                                 _tx_options, data, len);
     if (syncr) {
         return send_data(&frame);
@@ -298,18 +246,19 @@
     }
 }
 
-TxStatus XBeeZB::send_data(const RemoteXBee& remote, uint8_t source_ep, 
+TxStatus XBeeZB::send_data(const RemoteXBee& remote, uint8_t source_ep,
                                 uint8_t dest_ep, uint16_t cluster_id, uint16_t profile_id,
                                 const uint8_t *const data, uint16_t len, bool syncr)
 {
-    if (!remote.is_valid_addr64b())
+    if (!remote.is_valid_addr64b()) {
         return TxStatusInvalidAddr;
+    }
 
     const uint64_t remote64 = remote.get_addr64();
     const uint16_t remote16 = remote.get_addr16();
 
     TxFrameZB frame = TxFrameZB(remote64, remote16, source_ep, dest_ep,
-                                cluster_id, profile_id, _broadcast_radious,
+                                cluster_id, profile_id, BROADCAST_RADIUS_USE_NH,
                                 _tx_options, data, len);
     if (syncr) {
         return send_data(&frame);
@@ -317,16 +266,14 @@
         frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
         send_api_frame(&frame);
         return TxStatusSuccess;
-
     }
 }
-                              
+
 TxStatus XBeeZB::send_data_to_coordinator(const uint8_t *const data, uint16_t len, bool syncr)
 {
     const uint64_t remaddr = ADDR64_COORDINATOR;
-    
-    TxFrameZB frame = TxFrameZB(remaddr, ADDR16_UNKNOWN, _broadcast_radious,
-                                _tx_options, data, len);
+
+    TxFrameZB frame = TxFrameZB(remaddr, ADDR16_UNKNOWN, BROADCAST_RADIUS_USE_NH, _tx_options, data, len);
     if (syncr) {
         return send_data(&frame);
     } else {
@@ -344,14 +291,14 @@
     return RemoteXBeeZB(addr64, addr16);
 }
 
-NetworkRole XBeeZB::get_network_role()
+XBeeZB::AssocStatus XBeeZB::get_assoc_status(void)
 {
-    return _nw_role;
+    return (AssocStatus)get_AI();
 }
 
 bool XBeeZB::is_joined()
 {
-    return _joined_network;
+    return get_assoc_status() == Joined ? true : false;
 }
 
 void XBeeZB::register_node_discovery_cb(node_discovery_zb_cb_t function)
@@ -413,8 +360,9 @@
 
 AtCmdFrame::AtCmdResp XBeeZB::get_param(const RemoteXBee& remote, const char * const param, uint32_t * const data)
 {
-    if (!remote.is_valid_addr64b())
+    if (!remote.is_valid_addr64b()) {
         return AtCmdFrame::AtCmdRespInvalidAddr;
+    }
 
     const uint64_t remote64 = remote.get_addr64();
     const uint16_t remote16 = remote.get_addr16();
@@ -424,16 +372,18 @@
     AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param);
     atCmdResponse = send_at_cmd(&cmd_frame, (uint8_t *)data, &len, RadioRemote);
 
-    if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len > sizeof *data)
+    if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len > sizeof *data) {
         atCmdResponse = AtCmdFrame::AtCmdRespLenMismatch;
+    }
 
     return atCmdResponse;
 }
 
 AtCmdFrame::AtCmdResp XBeeZB::set_param(const RemoteXBee& remote, const char * const param, uint32_t data)
 {
-    if (!remote.is_valid_addr64b())
+    if (!remote.is_valid_addr64b()) {
         return AtCmdFrame::AtCmdRespInvalidAddr;
+    }
 
     const uint64_t remote64 = remote.get_addr64();
     const uint16_t remote16 = remote.get_addr16();
@@ -444,8 +394,9 @@
 
 AtCmdFrame::AtCmdResp XBeeZB::set_param(const RemoteXBee& remote, const char * const param, const uint8_t * data, uint16_t len)
 {
-    if (!remote.is_valid_addr64b())
+    if (!remote.is_valid_addr64b()) {
         return AtCmdFrame::AtCmdRespInvalidAddr;
+    }
 
     const uint64_t remote64 = remote.get_addr64();
     const uint16_t remote16 = remote.get_addr16();
@@ -457,8 +408,9 @@
 AtCmdFrame::AtCmdResp XBeeZB::get_param(const RemoteXBee& remote, const char * const param, uint8_t * const data, uint16_t * const len)
 {
 
-    if (!remote.is_valid_addr64b())
+    if (!remote.is_valid_addr64b()) {
         return AtCmdFrame::AtCmdRespInvalidAddr;
+    }
 
     const uint64_t remote64 = remote.get_addr64();
     const uint16_t remote16 = remote.get_addr16();
@@ -514,10 +466,7 @@
 
 RadioStatus XBeeZB::set_dio(const RemoteXBee& remote, IoLine line, DioVal val)
 {
-    if (val == Low)
-        return set_pin_config(remote, line, DigitalOutLow);
-    else
-        return set_pin_config(remote, line, DigitalOutHigh);
+    return set_pin_config(remote, line, val == Low ? DigitalOutLow : DigitalOutHigh);
 }
 
 RadioStatus XBeeZB::get_dio(const RemoteXBee& remote, IoLine line, DioVal * const val)
@@ -599,8 +548,9 @@
     }
 
     cmdresp = set_param(remote, "PR", pr);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
+    if (cmdresp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
+    }
 
     return Success;
 }
@@ -643,8 +593,9 @@
     }
 
     cmdresp = set_param(remote, "IC", ic);
-    if (cmdresp != AtCmdFrame::AtCmdRespOk)
+    if (cmdresp != AtCmdFrame::AtCmdRespOk) {
         return Failure;
+    }
 
     return Success;
 }
--- a/XBeeZB/XBeeZB.h	Mon May 18 13:16:55 2015 +0200
+++ b/XBeeZB/XBeeZB.h	Mon Jun 01 18:59:43 2015 +0200
@@ -44,6 +44,25 @@
             SUPPLY_VOLTAGE = 7, /**< SUPPLY_VOLTAGE is not a real pin */
         };
 
+        enum AssocStatus {
+            ErrorReading    = -1,       /**< Error occurred when reading parameter. */
+            Joined          = 0x00,     /**< Successfully formed or joined a network. (Coordinators form a network, routers and end devices join a network.) */
+            NoPANs          = 0x21,     /**< Scan found no PANs */
+            NoValidPAN      = 0x22,     /**< Scan found no valid PANs based on current SC and ID settings */
+            JoinNotAllowed  = 0x23,     /**< Valid Coordinator or Routers found, but they are not allowing joining (NJ expired). */
+            NoBeacons       = 0x24,     /**< No joinable beacons were found. */
+            Unexpected      = 0x25,     /**< Unexpected state, node should not be attempting to join at this time. */
+            JoinFailed      = 0x27,     /**< Node Joining attempt failed (typically due to incompatible security settings). */
+            CoordStartFail  = 0x2A,     /**< Coordinator start attempt failed */
+            CheckingCoord   = 0x2B,     /**< Checking for an existing coordinator. */
+            LeaveFail       = 0x2C,     /**< Attempt to leave the network failed. */
+            JoinNoResponse  = 0xAB,     /**< Attempted to join a device that did not respond. */
+            SecKeyUnsec     = 0xAC,     /**< Secure join error - network security key received unsecured. */
+            SecKeyNotRec    = 0xAD,     /**< Secure join error - network security key not received. */
+            SecBadKey       = 0xAF,     /**< Secure join error - joining device does not have the right preconfigured link key. */
+            Scanning        = 0xFF      /**< Scanning for a ZigBee network (routers and end devices). */
+        };
+
         /** Class constructor
          * @param tx the TX pin of the UART that will interface the XBee module
          * @param rx the RX pin of the UART that will interface the XBee module
@@ -54,10 +73,10 @@
          * to this baud rate (ATBD parameter). By default it is configured to 9600 bps
          */
         XBeeZB(PinName tx, PinName rx, PinName reset = NC, PinName rts = NC, PinName cts = NC, int baud = 9600);
- 
+
         /** Class destructor */
         virtual ~XBeeZB();
-        
+
         /** init-  initializes object
          * This function must be called just after creating the object so it initializes internal data.
          * @returns
@@ -66,7 +85,7 @@
          */
         RadioStatus init();
 
-        /** set_panid - sets the 64bit extended PAN ID.        
+        /** set_panid - sets the 64bit extended PAN ID.
          *
          *  @note on ZigBee devices, if set to 0, the coordinator will select a random PAN ID
          *           and the routers will join any extended PAN ID
@@ -76,7 +95,7 @@
          *     Failure otherwise
          */
         RadioStatus set_panid(uint64_t panid);
-        
+
         /** get_configured_panid - gets the configured PAN ID, as it was set by @ref set_panid().
          *
          *  @note on ZigBee devices, if set to 0, the coordinator will select a random PAN ID
@@ -161,16 +180,7 @@
          */
         RadioStatus check_for_coordinator_at_start(bool enable);
 
-        /** enable_network_encryption - Enable network encryption.
-         *
-         *  @param enable whether to enable this feature or not
-         *  @returns
-         *     Success if the operation was successful,
-         *     Failure otherwise
-         */
-        RadioStatus enable_network_encryption(bool enable);
-
-        /** set_encryption_key - Set the 128-bit AES network encryption key. If set to 0 (default), the module will select a random network key.
+        /** set_network_security_key - (Coordinator only) Set the 128-bit AES network encryption key. If set to 0 (default), the module will select a random network key.
          *  It is not recommended to set the key programmatically, because it could be read through the raw serial port bits.
          *  @param key pointer to the 128-bit AES key
          *  @param length size of the buffer pointed by 'key'
@@ -178,17 +188,7 @@
          *     Success if the operation was successful,
          *     Failure otherwise
          */
-        RadioStatus set_encryption_key(const uint8_t * const key, const uint16_t length);
-
-        /** set_tc_link_key - Set the Trust Center 128-bit AES link key. Setting it to 0 will cause the coordinator to transmit the network key in the clear to joining devices, and will cause joining devices to acquire the network key in the clear when joining.
-         *  It is not recommended to set the key programmatically, because it could be read through the raw serial port bits.
-         *  @param key pointer to the 128-bit AES key
-         *  @param length size of the buffer pointed by 'key'
-         *  @returns
-         *     Success if the operation was successful,
-         *     Failure otherwise
-         */
-        RadioStatus set_tc_link_key(const uint8_t * const key, const uint16_t length);
+        RadioStatus set_network_security_key(const uint8_t * const key, const uint16_t length);
 
 #define XBEE_ZB_ENC_OPT_SEND_KEY_ON_JOIN    0x01
 #define XBEE_ZB_ENC_OPT_USE_TRUST_CENTER    0x02
@@ -232,15 +232,8 @@
         /** unregister_io_sample_cb - removes the IO Sample Data reception callback */
         void unregister_io_sample_cb();
 
-        /** get_network_role - returns the role of this device in the ZigBee network
-         *
-         *  @returns the role of this device
-         */
-        NetworkRole get_network_role();
-        /**  */
-        
         /*********************** send_data member methods ************************/
-        /** send_data - sends data to a remote device 
+        /** send_data - sends data to a remote device
          *
          *  @param remote remote device
          *  @param data pointer to the data that will be sent
@@ -250,7 +243,7 @@
          *     TxStatusSuccess if the operation was successful,
          *     the error code otherwise
          */
-        virtual TxStatus send_data(const RemoteXBee& remote, const uint8_t *const data, uint16_t len, bool syncr = true);                                
+        virtual TxStatus send_data(const RemoteXBee& remote, const uint8_t *const data, uint16_t len, bool syncr = true);
 
         /** send_data - sends data to a remote device. This method uses
          *                   the explicit addressing frame, allowing to use source and
@@ -268,7 +261,7 @@
          *     TxStatusSuccess if the operation was successful,
          *     the error code otherwise
          */
-        TxStatus send_data(const RemoteXBee& remote, uint8_t source_ep, 
+        TxStatus send_data(const RemoteXBee& remote, uint8_t source_ep,
                                 uint8_t dest_ep, uint16_t cluster_id, uint16_t profile_id,
                                 const uint8_t *const data, uint16_t len, bool syncr = true);
 
@@ -283,11 +276,17 @@
          */
         TxStatus send_data_to_coordinator(const uint8_t *const data, uint16_t len, bool syncr = true);
 
+        /** get_assoc_status - returns current network association status. This wraps AI parameter, for more information refer to moudle's Reference Manual.
+         *
+         *  @returns an AssocStatus with current network association status.
+         */
+        AssocStatus get_assoc_status(void);
+
         /** is_joined - checks if the device is joined to ZigBee network
          *  @returns true if joined, false otherwise
          */
         bool is_joined();
-        
+
         /** get_remote_node_by_id - searches for a device in the network with the specified Node Identifier.
          *
          *  @param node_id node id of the device we are looking for
@@ -307,17 +306,17 @@
          *  @returns the command response status.
          */
         virtual AtCmdFrame::AtCmdResp set_param(const RemoteXBee& remote, const char * const param, uint32_t data);
-        
+
         /** set_param - sets a parameter in a remote radio by sending an AT command and waiting for the response.
          *
          *  @param remote remote device
          *  @param param parameter to be set.
-         *  @param data the parameter value byte array (len bytes) to be set. 
+         *  @param data the parameter value byte array (len bytes) to be set.
          *  @param len number of bytes of the parameter value.
          *  @returns the command response status.
          */
         virtual AtCmdFrame::AtCmdResp set_param(const RemoteXBee& remote, const char * const param, const uint8_t * data = NULL, uint16_t len = 0);
-        
+
         /* Allow using XBee::get_param() methods for local radio from this class */
         using XBee::get_param;
 
@@ -325,17 +324,17 @@
          *
          *  @param remote remote device
          *  @param param parameter to be get.
-         *  @param data pointer where the param value (4 bytes) will be stored. 
+         *  @param data pointer where the param value (4 bytes) will be stored.
          *  @returns the command response status.
          */
         virtual AtCmdFrame::AtCmdResp get_param(const RemoteXBee& remote, const char * const param, uint32_t * const data);
-      
+
         /** get_param - gets a parameter from a remote radio by sending an AT command and waiting for the response.
          *
          *  @param remote remote device
          *  @param param parameter to be get.
-         *  @param data pointer where the param value (n bytes) will be stored. 
-         *  @param len pointer where the number of bytes of the param value will be stored. 
+         *  @param data pointer where the param value (n bytes) will be stored.
+         *  @param len pointer where the number of bytes of the param value will be stored.
          *  @returns the command response status.
          */
         virtual AtCmdFrame::AtCmdResp get_param(const RemoteXBee& remote, const char * const param, uint8_t * const data, uint16_t * const len);
@@ -427,18 +426,6 @@
         RadioStatus enable_dio_change_detection(const RemoteXBee& remote, IoLine line, bool enable);
 
     protected:
-        /** Role of this device in the ZigBee network (coord, router or end device) */
-        NetworkRole      _nw_role;
-    
-        /** Indicates if the device is joined to a network. This variable is automatically updated
-         * by the library. If the device is acting as coordinator, its value its true */
-        volatile bool        _joined_network;
-
-        /** Vcc exceeded counter, automatically updated by the library */
-        volatile uint16_t    _vcc_exceeded_cnt;
-
-        /* TODO, add setter/getter */
-        uint8_t     _broadcast_radious;
 
         /** Frame handler used for the node discovery. Registered when a callback function
          * is registered */
@@ -447,12 +434,12 @@
         /** Frame handler used for the rx packets. Automatically registered when a callback
          *  function is registered */
         FH_RxPacketZB  *_rx_pkt_handler;
-    
+
         /** Frame handler used for the IO Data Sample packets. Automatically registered when a callback
          *  function is registered */
         FH_IoDataSampeZB  *_io_data_handler;
 
-        /** Method called directly by the library when a modem status frame is received to 
+        /** Method called directly by the library when a modem status frame is received to
          * update the internal status variables */
         virtual void radio_status_update(AtCmdFrame::ModemStatus modem_status);