Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: DigiLogger
Fork of XBeeLib_vs by
Revision 6:06522f3a6642, committed 2016-07-28
- Comitter:
- hbujanda
- Date:
- Thu Jul 28 10:17:20 2016 +0200
- Parent:
- 5:da2ea7a76243
- Child:
- 7:3ac2a461ce76
- Commit message:
- Automatic upload
Changed in this revision
--- a/FrameHandlers/FH_AtCmdResp.cpp Thu Mar 31 11:39:30 2016 +0200
+++ b/FrameHandlers/FH_AtCmdResp.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -159,3 +159,50 @@
node_discovery_cb(remote, nodeid);
}
+
+/** Class constructor */
+FH_NodeDiscoveryDM::FH_NodeDiscoveryDM() :
+ FH_AtCmdResp(ApiFrame::AtCmdResp), node_discovery_cb(NULL)
+{
+}
+
+/** Class destructor */
+FH_NodeDiscoveryDM::~FH_NodeDiscoveryDM()
+{
+}
+
+void FH_NodeDiscoveryDM::register_node_discovery_cb(node_discovery_dm_cb_t function)
+{
+ node_discovery_cb = function;
+}
+
+void FH_NodeDiscoveryDM::unregister_node_discovery_cb()
+{
+ node_discovery_cb = NULL;
+}
+
+
+void FH_NodeDiscoveryDM::process_frame_data(const ApiFrame *const frame)
+{
+ /* 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' ||
+ frame->get_data_at(ATCMD_RESP_CMD_HIGH_OFFSET) != 'D') {
+ return;
+ }
+
+ if (frame->get_data_at(ATCMD_RESP_STATUS_OFFSET) != AtCmdFrame::AtCmdRespOk) {
+ return;
+ }
+
+ const uint8_t * const data = frame->get_data(); /* The data payload we get here is the full AT command response payload, excluding the frameid. Keep that in mind for the offsets */
+ 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];
+ RemoteXBeeDM remote = RemoteXBeeDM(addr64);
+
+ node_discovery_cb(remote, node_id);
+}
\ No newline at end of file
--- a/FrameHandlers/FH_AtCmdResp.h Thu Mar 31 11:39:30 2016 +0200
+++ b/FrameHandlers/FH_AtCmdResp.h Thu Jul 28 10:17:20 2016 +0200
@@ -82,6 +82,40 @@
* @defgroup callback_types "Callback types declaration"
* @{
*/
+/** Node Discovery Response callback type declaration for ZigBee
+ * @param remote discovered remote node.
+ * @param node_id Node Identifier (NI parameter) of remote.
+ */
+typedef void (*node_discovery_dm_cb_t)(const RemoteXBeeDM& remote, char const * const node_id);
+/**
+ * @}
+ */
+
+class FH_NodeDiscoveryDM : public FH_AtCmdResp
+{
+ private:
+ /** Callback function, invoked (if registered) when an at command response packet is received */
+ node_discovery_dm_cb_t node_discovery_cb;
+
+ public:
+
+ /** Class constructor */
+ FH_NodeDiscoveryDM();
+
+ /** Class destructor */
+ virtual ~FH_NodeDiscoveryDM();
+
+ virtual void process_frame_data(const ApiFrame *const frame);
+
+ virtual void register_node_discovery_cb(node_discovery_dm_cb_t function);
+
+ virtual void unregister_node_discovery_cb();
+};
+
+/**
+ * @defgroup callback_types "Callback types declaration"
+ * @{
+ */
/** Node Discovery Response callback type declaration for 802.15.4
* @param remote discovered remote node.
* @param node_id Node Identifier (NI parameter) of remote.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/FrameHandlers/FH_IoDataSampleDM.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#include "XBeeLib.h"
+
+using namespace XBeeLib;
+
+/** Class constructor */
+FH_IoDataSampeDM::FH_IoDataSampeDM() : FrameHandler(ApiFrame::IoSampleRxZBDM),
+ io_data_cb(NULL)
+{
+}
+
+/** Class destructor */
+FH_IoDataSampeDM::~FH_IoDataSampeDM()
+{
+}
+
+void FH_IoDataSampeDM::register_io_data_cb(io_data_cb_dm_t function)
+{
+ io_data_cb = function;
+}
+
+void FH_IoDataSampeDM::unregister_io_data_cb()
+{
+ io_data_cb = NULL;
+}
+
+/* DM RX packet offsets */
+#define DM_IO_SAMPLE_DATA_OFFSET 11
+
+void FH_IoDataSampeDM::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;
+ }
+
+ /* We got an IO packet, decode it... */
+ const uint64_t sender64 = addr64_from_uint8_t(datap);
+ const RemoteXBeeDM sender = RemoteXBeeDM(sender64);
+ const IOSampleDM ioSample = IOSampleDM(&datap[DM_IO_SAMPLE_DATA_OFFSET], frame->get_data_len() - DM_IO_SAMPLE_DATA_OFFSET);
+
+ io_data_cb(sender, ioSample);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/FrameHandlers/FH_IoDataSampleDM.h Thu Jul 28 10:17:20 2016 +0200
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#if !defined(__FH_IO_DATA_SAMPLE_DM_H_)
+#define __FH_IO_DATA_SAMPLE_DM_H_
+
+#include "FrameHandler.h"
+#include "RemoteXBee/RemoteXBee.h"
+
+namespace XBeeLib {
+
+class IOSampleDM;
+
+/**
+ * @defgroup callback_types "Callback types declaration"
+ * @{
+ */
+/** IO Data Sample reception (ZigBee modules) callback type declaration
+ * @param remote the remote module that sent the data
+ * @param sample_data a referece to an @ref IOSampleDM that can be queried for the IoLines' values
+ */
+typedef void (*io_data_cb_dm_t)(const RemoteXBeeDM& remote, const IOSampleDM& sample_data);
+/**
+ * @}
+ */
+
+class FH_IoDataSampeDM : public FrameHandler
+{
+ public:
+ /** Class constructor */
+ FH_IoDataSampeDM();
+
+ /** Class destructor */
+ virtual ~FH_IoDataSampeDM();
+
+ virtual void process_frame_data(const ApiFrame *const frame);
+
+ void register_io_data_cb(io_data_cb_dm_t function);
+
+ void unregister_io_data_cb();
+
+ private:
+ /** Callback function, invoked if registered */
+ io_data_cb_dm_t io_data_cb;
+};
+
+} /* namespace XBeeLib */
+
+#endif /* __FH_IO_DATA_SAMPLE_DM_H_ */
--- a/FrameHandlers/FH_IoDataSampleZB.cpp Thu Mar 31 11:39:30 2016 +0200
+++ b/FrameHandlers/FH_IoDataSampleZB.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -15,7 +15,7 @@
using namespace XBeeLib;
/** Class constructor */
-FH_IoDataSampeZB::FH_IoDataSampeZB() : FrameHandler(ApiFrame::IoSampleRxZB),
+FH_IoDataSampeZB::FH_IoDataSampeZB() : FrameHandler(ApiFrame::IoSampleRxZBDM),
io_data_cb(NULL)
{
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/FrameHandlers/FH_RxPacketDM.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#include "FH_RxPacketDM.h"
+
+using namespace XBeeLib;
+
+/** Class constructor */
+FH_RxPacketDM::FH_RxPacketDM() : FrameHandler(ApiFrame::RxPacketAO0), receive_cb(NULL)
+{
+}
+
+/** Class destructor */
+FH_RxPacketDM::~FH_RxPacketDM()
+{
+}
+
+void FH_RxPacketDM::register_receive_cb(receive_dm_cb_t function)
+{
+ receive_cb = function;
+}
+
+void FH_RxPacketDM::unregister_receive_cb(void)
+{
+ receive_cb = NULL;
+}
+
+/* DM RX packet offsets */
+#define DM_RX_OPTIONS_OFFSET 10
+#define DM_RX_DATA_OFFSET 11
+#define DM_RX_OVERHEAD (8+2+1)
+
+#define BROADCAST_PACKET 0x02
+
+void FH_RxPacketDM::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) {
+ return;
+ }
+
+ /* We got a rx packet, decode it... */
+ const uint8_t *datap = frame->get_data();
+ const uint64_t sender64 = addr64_from_uint8_t(datap);
+ const uint8_t rx_options = datap[DM_RX_OPTIONS_OFFSET];
+ const RemoteXBeeDM sender = RemoteXBeeDM(sender64);
+
+ receive_cb(sender, rx_options & BROADCAST_PACKET, &datap[DM_RX_DATA_OFFSET], frame->get_data_len() - DM_RX_OVERHEAD);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/FrameHandlers/FH_RxPacketDM.h Thu Jul 28 10:17:20 2016 +0200
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#if !defined(__FH_RX_PACKET_DM_H_)
+#define __FH_RX_PACKET_DM_H_
+
+#include "FrameHandler.h"
+#include "RemoteXBee/RemoteXBee.h"
+
+namespace XBeeLib {
+
+/**
+ * @defgroup callback_types "Callback types declaration"
+ * @{
+ */
+/** receive callback type declaration
+ * @param remote the remote module that sent the data
+ * @param broadcast a boolean to tell if the message was broadcast (true) or unicast (false)
+ * @param data a pointer to data sent by @b remote.
+ * @param len length (in bytes) of @b data buffer
+ */
+typedef void (*receive_dm_cb_t)(const RemoteXBeeDM& remote, bool broadcast, const uint8_t *const data, uint16_t len);
+/**
+ * @}
+ */
+
+class FH_RxPacketDM : public FrameHandler
+{
+ private:
+ /** Callback function, invoked if registered */
+ receive_dm_cb_t receive_cb;
+
+ public:
+ /** Class constructor */
+ FH_RxPacketDM();
+
+ /** Class destructor */
+ virtual ~FH_RxPacketDM();
+
+ /** 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_dm_cb_t function);
+
+ void unregister_receive_cb();
+};
+
+} /* namespace XBeeLib */
+
+#endif /* __FH_RX_PACKET_DM_H_ */
--- a/Frames/ApiFrame.h Thu Mar 31 11:39:30 2016 +0200
+++ b/Frames/ApiFrame.h Thu Jul 28 10:17:20 2016 +0200
@@ -29,8 +29,8 @@
TxReq16Bit = 0x01, /**< TxReq16Bit: Only for 802.15.4 modules */
AtCmd = 0x08, /**< AtCmd */
AtCmdQueuePV = 0x09, /**< AtCmdQueuePV */
- TxReqZB = 0x10, /**< TxReqZB: Only for ZigBee modules */
- ExpAddrCmd = 0x11, /**< ExpAddrCmd: Only for ZigBee modules */
+ TxReqZBDM = 0x10, /**< TxReqZBDM: Only for ZigBee and DigiMesh modules */
+ ExpAddrCmd = 0x11, /**< ExpAddrCmd: Only for ZigBee modules and DigiMesh */
RemoteCmdReq = 0x17, /**< RemoteCmdReq */
CreateSrcRoute = 0x21, /**< CreateSrcRoute */
RxPacket64Bit = 0x80, /**< RxPacket64Bit: Only for 802.15.4 modules */
@@ -40,12 +40,14 @@
AtCmdResp = 0x88, /**< AtCmdResp */
TxStatus = 0x89, /**< TxStatus */
AtModemStatus = 0x8A, /**< AtModemStatus */
- TxStatusZB = 0x8B, /**< TxStatusZB: Only for ZigBee modules */
- RxPacketAO0 = 0x90, /**< RxPacketAO0: Only for ZigBee modules */
- RxPacketAO1 = 0x91, /**< RxPacketAO1: Only for ZigBee modules */
- IoSampleRxZB = 0x92, /**< IoSampleRxZB: Only for ZigBee modules */
+ TxStatusZBDM = 0x8B, /**< TxStatusZBDM: Only for ZigBee and DigiMesh modules */
+ RouteInfo = 0x8D, /**< RouteInfo: Only for DigiMesh modules */
+ AggregateAddr = 0x8E, /**< AggregateAddr: Only for DigiMesh modules */
+ RxPacketAO0 = 0x90, /**< RxPacketAO0: Only for ZigBee and DigiMesh modules */
+ RxPacketAO1 = 0x91, /**< RxPacketAO1: Only for ZigBee and DigiMesh modules */
+ IoSampleRxZBDM = 0x92, /**< IoSampleRxZBDM: Only for ZigBee and DigiMesh modules */
SensorRxIndAO0 = 0x94, /**< SensorRxIndAO0: Only for ZigBee modules */
- NodeIdentIndAO0 = 0x95, /**< NodeIdentIndAO0: Only for ZigBee modules */
+ NodeIdentIndAO0 = 0x95, /**< NodeIdentIndAO0: Only for ZigBee and DigiMesh modules */
RemoteCmdResp = 0x97, /**< RemoteCmdResp */
OtaFwUpStatus = 0xA0, /**< OtaFwUpStatus */
RouteRecInd = 0xA1, /**< RouteRecInd */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Frames/DigiMeshFrames.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#include "DigiMeshFrames.h"
+
+#define FRAME_ID_LEN 1
+#define ADDR64_LEN 8
+#define ADDR16_LEN 2
+#define BROADCAST_RADIOUS_LEN 1
+#define OPTIONS_LEN 1
+#define TX_REQUEST_OVERHEAD (FRAME_ID_LEN + ADDR64_LEN + \
+ ADDR16_LEN + BROADCAST_RADIOUS_LEN + \
+ OPTIONS_LEN)
+#define SOURCE_EP_LEN 1
+#define DEST_EP_LEN 1
+#define CLUSTER_ID_LEN 2
+#define PROFILE_ID_LEN 2
+
+#define EXP_ADDR_OVERHEAD (TX_REQUEST_OVERHEAD + SOURCE_EP_LEN + \
+ DEST_EP_LEN + CLUSTER_ID_LEN + \
+ PROFILE_ID_LEN)
+
+/** Class constructor */
+TxFrameDM::TxFrameDM(uint64_t addr, uint16_t addr16, uint8_t broadcast_rad, uint8_t tx_opt,
+ 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,
+ * the broad cast radious, the options byte and the frame data */
+
+ frame_data[0] = _frame_id;
+ rmemcpy(&frame_data[1], (const uint8_t *)&addr, sizeof addr);
+ frame_data[9] = (uint8_t)(addr16 >> 8);
+ frame_data[10] = (uint8_t)addr16;
+ frame_data[11] = broadcast_rad;
+ frame_data[12] = tx_opt;
+
+ if (len) {
+ memcpy(&frame_data[13], data, len);
+ }
+
+ set_api_frame(TxReqZBDM, frame_data, TX_REQUEST_OVERHEAD + len);
+}
+
+/** Class constructor */
+TxFrameDM::TxFrameDM(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,
+ 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,
+ * the end point source and destination addresses, the cluster and profile IDs,
+ * the broad cast radious, the options byte and the frame data */
+
+ frame_data[0] = _frame_id;
+ rmemcpy(&frame_data[1], (const uint8_t *)&addr, sizeof addr);
+ frame_data[9] = (uint8_t)(addr16 >> 8);
+ frame_data[10] = (uint8_t)addr16;
+ frame_data[11] = source_ep;
+ frame_data[12] = dest_ep;
+ frame_data[13] = (uint8_t)(cluster_id >> 8);
+ frame_data[14] = (uint8_t)cluster_id;
+ frame_data[15] = (uint8_t)(profile_id >> 8);
+ frame_data[16] = (uint8_t)profile_id;
+ frame_data[17] = broadcast_rad;
+ frame_data[18] = tx_opt;
+
+ if (len) {
+ memcpy(&frame_data[19], data, len);
+ }
+
+ set_api_frame(ExpAddrCmd, frame_data, EXP_ADDR_OVERHEAD + len);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Frames/DigiMeshFrames.h Thu Jul 28 10:17:20 2016 +0200
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#if !defined(__DIGIMESH_FRAME_H_)
+#define __DIGIMESH_FRAME_H_
+
+#include "ApiFrame.h"
+
+class TxFrameDM : public ApiFrame
+{
+ public:
+ /** Class constructor */
+ TxFrameDM(uint64_t addr, uint16_t addr16, uint8_t broadcast_rad,
+ uint8_t tx_opt, const uint8_t *const data, uint16_t len);
+
+ /** Class constructor */
+ TxFrameDM(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,
+ uint8_t tx_opt, const uint8_t *const data, uint16_t len);
+};
+
+#endif /* __DIGIMESH_FRAME_H_ */
--- a/Frames/ZigbeeFrames.cpp Thu Mar 31 11:39:30 2016 +0200
+++ b/Frames/ZigbeeFrames.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -51,7 +51,7 @@
memcpy(&frame_data[13], data, len);
}
- set_api_frame(TxReqZB, frame_data, TX_REQUEST_OVERHEAD + len);
+ set_api_frame(TxReqZBDM, frame_data, TX_REQUEST_OVERHEAD + len);
}
/** Class constructor */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IO/IOSampleDM.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#include "XBeeLib.h"
+#include "IO/IOSampleDM.h"
+
+#define IO_SAMPLE_DM_MIN_SIZE (2 + 1 + 2)
+
+using namespace XBeeLib;
+
+IOSampleDM::IOSampleDM(const uint8_t* const raw_data, size_t size)
+{
+ if (raw_data == NULL || size == 0) {
+ _digital_mask = 0;
+ _analog_mask = 0;
+ return;
+ }
+ assert(size >= IO_SAMPLE_DM_MIN_SIZE);
+ assert(size <= sizeof _sampled_data);
+
+ _digital_mask = UINT16(raw_data[1], raw_data[2]);
+ _analog_mask = raw_data[3];
+ _sampled_data_size = size - 4;
+ memcpy(&_sampled_data[0], &raw_data[4], _sampled_data_size);
+}
+
+IOSampleDM::~IOSampleDM()
+{
+
+}
+
+RadioStatus IOSampleDM::get_dio(XBeeDM::IoLine line, DioVal* const dio_value) const
+{
+ const uint16_t mask = 1 << line;
+ if (mask & _digital_mask) {
+ const uint16_t digital_channels = get_digital_channels();
+
+ *dio_value = digital_channels & mask ? High : Low;
+ return Success;
+ }
+ return Failure;
+}
+
+RadioStatus IOSampleDM::get_adc(XBeeDM::IoLine line, uint16_t* const val) const
+{
+ const uint8_t line_mask = 1 << line;
+ const bool adc_present = line_mask & _analog_mask;
+ if (!adc_present) {
+ return Failure;
+ }
+
+ uint8_t analog_data_idx = _digital_mask == 0 ? 0 : 2;
+ uint8_t line_sample = 0;
+
+ while (analog_data_idx < _sampled_data_size) {
+ if (_analog_mask & (1 << line_sample)) {
+ if (line_sample == line) {
+ /* Write the analog value */
+ *val = UINT16(_sampled_data[analog_data_idx], _sampled_data[analog_data_idx + 1]);
+ break;
+ }
+ analog_data_idx += 2;
+ }
+ line_sample++;
+ }
+
+ return Success;
+}
+
+inline uint16_t IOSampleDM::get_digital_channels(void) const
+{
+ if (_digital_mask == 0) {
+ return 0;
+ }
+ return UINT16(_sampled_data[0], _sampled_data[1]);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IO/IOSampleDM.h Thu Jul 28 10:17:20 2016 +0200
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#ifndef _IO_IOSAMPLEDM_H_
+#define _IO_IOSAMPLEDM_H_
+
+#define MAX_IO_SAMPLE_DM_LEN (2 + 2 * 5)
+
+namespace XBeeLib {
+
+/** Class to handle the incoming IO Data Samples in ZigBee modules */
+class IOSampleDM {
+ public:
+ /** Class constructor
+ * @param raw_data The IO Sample data, as returned by an "IS" command response or in the IoSampleRxZBDM (0x92) frames
+ * @param size size (in bytes) of raw_data.
+ */
+ IOSampleDM(const uint8_t* const raw_data = NULL, size_t size = 0);
+
+ /** Class destructor */
+ ~IOSampleDM();
+
+ /** get_dio - read the value of a DIO configured as digital input
+ *
+ * @param line DIO line being read
+ * @param val pointer where the DIO value read will be stored
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus get_dio(XBeeDM::IoLine line, DioVal* const dio_value) const;
+
+ /** get_adc - read the value of the espcified ADC line
+ *
+ * @param line ADC line being read
+ * @param val pointer where the value read from the ADC will be stored
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus get_adc(XBeeDM::IoLine line, uint16_t* const val) const;
+
+ /** is_valid - checks if the IOSampleDM object has at least one DIO or ADC sample.
+ * @returns true if valid, false otherwise
+ */
+ inline bool is_valid()
+ {
+ return _digital_mask != 0 || _analog_mask != 0;
+ }
+
+ protected:
+ uint16_t _digital_mask;
+ uint8_t _analog_mask;
+ uint8_t _sampled_data[MAX_IO_SAMPLE_DM_LEN];
+ uint8_t _sampled_data_size;
+
+ inline uint16_t get_digital_channels(void) const;
+};
+
+} /* namespace XBeeLib */
+
+#endif /* _IO_IOSAMPLEDM_H_ */
--- a/IO/IOSampleZB.h Thu Mar 31 11:39:30 2016 +0200
+++ b/IO/IOSampleZB.h Thu Jul 28 10:17:20 2016 +0200
@@ -21,7 +21,7 @@
class IOSampleZB {
public:
/** Class constructor
- * @param raw_data The IO Sample data, as returned by an "IS" command response or in the IoSampleRxZB (0x92) frames
+ * @param raw_data The IO Sample data, as returned by an "IS" command response or in the IoSampleRxZBDM (0x92) frames
* @param size size (in bytes) of raw_data.
*/
IOSampleZB(const uint8_t* const raw_data = NULL, size_t size = 0);
--- a/RemoteXBee/RemoteXBee.cpp Thu Mar 31 11:39:30 2016 +0200
+++ b/RemoteXBee/RemoteXBee.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -77,3 +77,15 @@
RemoteXBeeZB::~RemoteXBeeZB()
{
}
+
+RemoteXBeeDM::RemoteXBeeDM() : RemoteXBee()
+{
+}
+
+RemoteXBeeDM::RemoteXBeeDM(uint64_t remote64) : RemoteXBee(remote64)
+{
+}
+
+RemoteXBeeDM::~RemoteXBeeDM()
+{
+}
--- a/RemoteXBee/RemoteXBee.h Thu Mar 31 11:39:30 2016 +0200
+++ b/RemoteXBee/RemoteXBee.h Thu Jul 28 10:17:20 2016 +0200
@@ -154,6 +154,29 @@
}
};
+/** Class for DigiMesh Remote XBee modules */
+class RemoteXBeeDM : public RemoteXBee
+{
+ public:
+
+ /** Default Class constructor for a DigiMesh remote device (connected wirelessly). No address set.
+ */
+ RemoteXBeeDM();
+
+ /** Class constructor for a DigiMesh remote device (connected wirelessly) using 64bit addressing
+ * @param remote64 the 64-bit address (ATSH and ATSL parameters) of the remote XBee module
+ */
+ RemoteXBeeDM(uint64_t remote64);
+
+ /** Class destructor */
+ ~RemoteXBeeDM();
+
+ inline bool is_valid(void)
+ {
+ return is_valid_addr64b();
+ }
+};
+
} /* namespace XBeeLib */
#endif /* defined(__XBEE_REMOTE_H_) */
--- a/XBee/RadioConfig.cpp Thu Mar 31 11:39:30 2016 +0200
+++ b/XBee/RadioConfig.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -58,22 +58,6 @@
return Success;
}
-RadioStatus XBee::get_network_address(uint16_t * const addr16)
-{
- if (addr16 == NULL) {
- return Failure;
- }
- AtCmdFrame::AtCmdResp cmdresp;
-
- uint32_t var32;
- cmdresp = get_param("MY", &var32);
- if (cmdresp != AtCmdFrame::AtCmdRespOk) {
- return Failure;
- }
- *addr16 = var32;
- return Success;
-}
-
RadioStatus XBee::software_reset(void)
{
volatile uint16_t * const rst_cnt_p = &_wd_reset_cnt;
@@ -168,17 +152,15 @@
RadioStatus XBee::start_node_discovery()
{
- AtCmdFrame::AtCmdResp cmdresp;
- uint32_t nd_timeout_cfg;
+ RadioStatus status;
+ uint16_t nd_timeout;
- cmdresp = get_param("NT", &nd_timeout_cfg);
- if (cmdresp != AtCmdFrame::AtCmdRespOk) {
- return Failure;
+ status = get_node_discovery_timeout(&nd_timeout);
+ if (status != Success) {
+ return status;
}
- 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_timeout = nd_timeout;
_nd_timer.start();
@@ -217,15 +199,16 @@
const uint16_t old_timeout = _timeout_ms;
- uint32_t nd_timeout_100msec;
- const AtCmdFrame::AtCmdResp nt_resp = get_param("NT", &nd_timeout_100msec);
- if (nt_resp != AtCmdFrame::AtCmdRespOk) {
- _timeout_ms = 10000;
- } else {
- _timeout_ms = (uint16_t)nd_timeout_100msec * 100 + 1000;
+ RadioStatus status;
+ uint16_t nd_timeout;
+ bool wait_for_complete_timeout;
+
+ status = get_node_discovery_timeout(&nd_timeout, &wait_for_complete_timeout);
+ if (status != Success) {
+ return;
}
+ _timeout_ms = nd_timeout;
- const int nd_timeout = _timeout_ms;
Timer nd_timer = Timer();
nd_timer.start();
@@ -263,18 +246,20 @@
rmemcpy((uint8_t *)addr64, resp_frame->get_data() + ATCMD_RESP_DATA_OFFSET + sizeof *addr16, sizeof *addr64);
_framebuf_syncr.free_frame(resp_frame);
- while (nd_timer.read_ms() < nd_timeout) {
- wait_ms(10);
+ if (wait_for_complete_timeout) {
+ while (nd_timer.read_ms() < nd_timeout) {
+ wait_ms(10);
+ }
}
return;
}
-RadioStatus XBee::config_node_discovery(uint16_t timeout_ms, uint8_t options)
+RadioStatus XBee::config_node_discovery(uint16_t backoff_ms, uint8_t options)
{
AtCmdFrame::AtCmdResp cmdresp;
- cmdresp = set_param("NT", (uint8_t)(timeout_ms / 100));
+ cmdresp = set_param("NT", (uint8_t)(backoff_ms / 100));
if (cmdresp != AtCmdFrame::AtCmdRespOk) {
return Failure;
}
@@ -291,7 +276,7 @@
return Success;
}
-RadioStatus XBee::get_config_node_discovery(uint16_t * const timeout_ms, uint8_t * const options)
+RadioStatus XBee::get_config_node_discovery(uint16_t * const backoff_ms, uint8_t * const options)
{
AtCmdFrame::AtCmdResp cmdresp;
uint32_t var32;
@@ -300,7 +285,7 @@
if (cmdresp != AtCmdFrame::AtCmdRespOk) {
return Failure;
}
- *timeout_ms = var32;
+ *backoff_ms = var32;
cmdresp = get_param("NO", &var32);
if (cmdresp != AtCmdFrame::AtCmdRespOk) {
--- a/XBee/XBee.cpp Thu Mar 31 11:39:30 2016 +0200
+++ b/XBee/XBee.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -295,38 +295,40 @@
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 */
+ case ApiFrame::AtCmdResp:
+ case ApiFrame::RemoteCmdResp:
+ case ApiFrame::TxStatusZBDM:
+ case ApiFrame::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 */
+ case ApiFrame::RxPacket64Bit:
+ case ApiFrame::RxPacket16Bit:
+ case ApiFrame::Io64Bit:
+ case ApiFrame::Io16Bit:
+ case ApiFrame::AtModemStatus:
+ case ApiFrame::RxPacketAO0:
+ case ApiFrame::IoSampleRxZBDM:
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 */
+ case ApiFrame::RxPacketAO1:
+ case ApiFrame::SensorRxIndAO0:
+ case ApiFrame::NodeIdentIndAO0:
+ case ApiFrame::OtaFwUpStatus:
+ case ApiFrame::RouteRecInd:
+ case ApiFrame::Many2OneRRInd:
+ case ApiFrame::TxReq64Bit:
+ case ApiFrame::TxReq16Bit:
+ case ApiFrame::AtCmd:
+ case ApiFrame::AtCmdQueuePV:
+ case ApiFrame::TxReqZBDM:
+ case ApiFrame::ExpAddrCmd:
+ case ApiFrame::RemoteCmdReq:
+ case ApiFrame::CreateSrcRoute:
+ case ApiFrame::Invalid:
+ case ApiFrame::RouteInfo:
+ case ApiFrame::AggregateAddr:
framebuf = NULL;
break;
}
@@ -365,13 +367,13 @@
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 */
+ case ApiFrame::RemoteCmdResp:
+ case ApiFrame::TxStatusZBDM:
+ case ApiFrame::TxStatus:
framebuf = &_framebuf_syncr;
break;
- case ApiFrame::AtCmdResp: /**< AtCmdResp */
+ case ApiFrame::AtCmdResp:
if ((frame_cached[1] != _node_by_ni_frame_id ) && (frame_cached[2] == 'N') && (data == 'D'))
{
framebuf = &_framebuf_app;
@@ -380,31 +382,33 @@
}
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 */
+ case ApiFrame::RxPacket64Bit:
+ case ApiFrame::RxPacket16Bit:
+ case ApiFrame::Io64Bit:
+ case ApiFrame::Io16Bit:
+ case ApiFrame::AtModemStatus:
+ case ApiFrame::RxPacketAO0:
+ case ApiFrame::IoSampleRxZBDM:
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 */
+ case ApiFrame::RxPacketAO1:
+ case ApiFrame::SensorRxIndAO0:
+ case ApiFrame::NodeIdentIndAO0:
+ case ApiFrame::OtaFwUpStatus:
+ case ApiFrame::RouteRecInd:
+ case ApiFrame::Many2OneRRInd:
+ case ApiFrame::TxReq64Bit:
+ case ApiFrame::TxReq16Bit:
+ case ApiFrame::AtCmd:
+ case ApiFrame::AtCmdQueuePV:
+ case ApiFrame::TxReqZBDM:
+ case ApiFrame::ExpAddrCmd:
+ case ApiFrame::RemoteCmdReq:
+ case ApiFrame::CreateSrcRoute:
+ case ApiFrame::Invalid:
+ case ApiFrame::RouteInfo:
+ case ApiFrame::AggregateAddr:
framebuf = NULL;
break;
}
@@ -760,6 +764,9 @@
} else if (hw_version_msb == XB900HP_NZ) {
return DigiPoint;
} else if (hw_version_msb == XBP24C_TH_DIP || hw_version_msb == XB24C_TH_DIP || hw_version_msb == XBP24C_S2C_SMT) {
+ if (fw_4_bytes_len && fw_nibble_3 == 9) {
+ return DigiMesh;
+ }
if (fw_4_bytes_len && fw_nibble_3 == 5) {
return SmartEnergy;
}
@@ -787,12 +794,12 @@
/* Wait for the transmit status response packet */
resp_frame = get_this_api_frame(frame->get_frame_id(),
- ApiFrame::TxStatusZB, ApiFrame::TxStatus);
+ ApiFrame::TxStatusZBDM, ApiFrame::TxStatus);
if (resp_frame == NULL) {
return resp;
}
- uint8_t index = resp_frame->get_frame_type() == ApiFrame::TxStatusZB ?
+ uint8_t index = resp_frame->get_frame_type() == ApiFrame::TxStatusZBDM ?
TX_STATUS_OFFSET_ZB : TX_STATUS_OFFSET_802;
resp = (TxStatus)resp_frame->get_data_at(index);
--- a/XBee/XBee.h Thu Mar 31 11:39:30 2016 +0200
+++ b/XBee/XBee.h Thu Jul 28 10:17:20 2016 +0200
@@ -165,15 +165,6 @@
*/
uint64_t get_addr64() const;
- /** get_network_address - gets the 16bit network address of the device
- *
- * @param addr pointer where the device 16bit network address will be stored
- * @returns
- * Success if the operation was successful,
- * Failure otherwise
- */
- RadioStatus get_network_address(uint16_t * const addr);
-
/** hardware_reset - performs a hardware reset. The reset GPIO must have
* been provided to the constructor
*
@@ -338,7 +329,7 @@
/** config_node_discovery - configures the node discovery operation
*
- * @param timeout_ms max allowed time for devices in the network to answer
+ * @param backoff_ms max allowed time for devices in the network to answer
* to the Node Discovery request
* @param options node discovery options (flags)
* XBEE802_ND_OPTION_SELF_RESPONSE - to allow the module self responding (802.15.4 only)
@@ -348,18 +339,18 @@
* Success if the operation was successful,
* Failure otherwise
*/
- RadioStatus config_node_discovery(uint16_t timeout_ms, uint8_t options = 0);
+ RadioStatus config_node_discovery(uint16_t backoff_ms, uint8_t options = 0);
/** get_config_node_discovery - reads the configuration of the node discovery
* settings
*
- * @param timeout_ms pointer where the node discovery time out value will be stored
+ * @param backoff_ms pointer where the configured node discovery back-off time value will be stored
* @param options pointer whre the node discovery options (flags) will be saved
* @returns
* Success if the operation was successful,
* Failure otherwise
*/
- RadioStatus get_config_node_discovery(uint16_t * const timeout_ms, uint8_t * const options);
+ RadioStatus get_config_node_discovery(uint16_t * const backoff_ms, uint8_t * const options);
/** set_timeout - sets the timeout in ms, used by sync methods
*
@@ -638,6 +629,19 @@
*/
int get_AI(void);
+ /** get_node_discovery_timeout - gets the node discovery timeout
+ *
+ * @param timeout_ms pointer where the node discovery timeout value will be stored
+ * @param wait_for_complete_timeout pointer where the function will store if the operator
+ * has to wait for the complete nd timeout after issuing
+ * a directed nd request
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ virtual RadioStatus get_node_discovery_timeout(uint16_t * const timeout_ms) = 0;
+ virtual RadioStatus get_node_discovery_timeout(uint16_t * const timeout_ms, bool * const wait_for_complete_timeout) = 0;
+
/** serial hardware flow control selected by the user (RTSCTS, RTS,CTS) */
SerialBase::Flow _serial_flow_type;
--- a/XBee802/XBee802.cpp Thu Mar 31 11:39:30 2016 +0200
+++ b/XBee802/XBee802.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -58,16 +58,8 @@
{
AtCmdFrame::AtCmdResp cmdresp;
- if (is_PRO()) {
- if (channel < 0x0C || channel > 0x17) {
- return Failure;
- }
- } else {
- if (channel < 0x0B || channel > 0x1A) {
- return Failure;
- }
- }
-
+ /* Pro and Non-Pro modules have different channels available. The at
+ command will return an error if the selected channel is not available */
cmdresp = set_param("CH", channel);
if (cmdresp != AtCmdFrame::AtCmdRespOk) {
return Failure;
@@ -118,6 +110,22 @@
return Success;
}
+RadioStatus XBee802::get_network_address(uint16_t * const addr16)
+{
+ if (addr16 == NULL) {
+ return Failure;
+ }
+ AtCmdFrame::AtCmdResp cmdresp;
+
+ uint32_t var32;
+ cmdresp = get_param("MY", &var32);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ *addr16 = var32;
+ return Success;
+}
+
RadioStatus XBee802::set_network_address(uint16_t addr16)
{
AtCmdFrame::AtCmdResp cmdresp;
@@ -129,6 +137,34 @@
return Success;
}
+RadioStatus XBee802::get_node_discovery_timeout(uint16_t * const timeout_ms)
+{
+ AtCmdFrame::AtCmdResp cmdresp;
+ uint32_t var32;
+
+ cmdresp = get_param("NT", &var32);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ *timeout_ms = (uint16_t)var32;
+
+ /* No N? command available for this protocol. Add a fix 1s guard time */
+ *timeout_ms += 1000;
+
+ return Success;
+}
+
+RadioStatus XBee802::get_node_discovery_timeout(uint16_t * const timeout_ms, bool * const wait_for_complete_timeout)
+{
+ const RadioStatus status = get_node_discovery_timeout(timeout_ms);
+
+ /* This protocol requires to wait for the complete timeout before attempting
+ to execute other commands */
+ *wait_for_complete_timeout = true;
+
+ return status;
+}
+
void XBee802::radio_status_update(AtCmdFrame::ModemStatus modem_status)
{
/* Update the radio status variables */
--- a/XBee802/XBee802.h Thu Mar 31 11:39:30 2016 +0200
+++ b/XBee802/XBee802.h Thu Jul 28 10:17:20 2016 +0200
@@ -123,6 +123,15 @@
*/
RadioStatus get_channel(uint8_t * const channel);
+ /** get_network_address - gets the 16bit network address of the device
+ *
+ * @param addr pointer where the device 16bit network address will be stored
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus get_network_address(uint16_t * const addr);
+
/** set_network_address - sets the 16 bit network address of the device
*
* @param addr the device 16bit network address (0x0 - 0xFFFF)
@@ -346,10 +355,6 @@
#endif
protected:
- inline bool is_PRO()
- {
- return (_hw_version & 0xFF00U) == 0x1800U;
- }
/** Frame handler used for the node discovery. Registered when a callback function
* is registered */
@@ -378,6 +383,19 @@
/* Allow using XBee::send_data() methods from this class */
using XBee::send_data;
+ /** get_node_discovery_timeout - gets the node discovery timeout
+ *
+ * @param timeout_ms pointer where the node discovery timeout value will be stored
+ * @param wait_for_complete_timeout pointer where the function will store if the operator
+ * has to wait for the complete nd timeout after issuing
+ * a directed nd request
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ virtual RadioStatus get_node_discovery_timeout(uint16_t * const timeout_ms);
+ virtual RadioStatus get_node_discovery_timeout(uint16_t * const timeout_ms, bool * const wait_for_complete_timeout);
+
private:
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/XBeeDM/XBeeDM.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -0,0 +1,550 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#include "XBeeDM.h"
+#include "IO/IOSampleDM.h"
+#include "Frames/DigiMeshFrames.h"
+
+using namespace XBeeLib;
+
+#define BROADCAST_RADIUS_USE_NH 0x00
+
+/* Class constructor */
+XBeeDM::XBeeDM(PinName tx, PinName rx, PinName reset, PinName rts, PinName cts, int baud) :
+ XBee(tx, rx, reset, rts, cts, baud), _nd_handler(NULL), _rx_pkt_handler(NULL), _io_data_handler(NULL)
+{
+}
+
+RadioStatus XBeeDM::init()
+{
+ RadioStatus retval = XBee::init();
+
+ const RadioProtocol radioProtocol = get_radio_protocol();
+ if (radioProtocol != DigiMesh) {
+ digi_log(LogLevelError, "Radio protocol does not match, needed a %d got a %d\r\n", DigiMesh, radioProtocol);
+ retval = Failure;
+ }
+ assert(radioProtocol == DigiMesh);
+
+ return retval;
+}
+
+/* Class destructor */
+XBeeDM::~XBeeDM()
+{
+ unregister_node_discovery_cb();
+ unregister_receive_cb();
+ unregister_io_sample_cb();
+}
+
+RadioStatus XBeeDM::set_channel(uint8_t channel)
+{
+ AtCmdFrame::AtCmdResp cmdresp;
+
+ /* Pro and Non-Pro modules have different channels available. The at
+ command will return an error if the selected channel is not available */
+ cmdresp = set_param("CH", channel);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ return Success;
+}
+
+RadioStatus XBeeDM::get_channel(uint8_t * const channel)
+{
+ if (channel == NULL) {
+ return Failure;
+ }
+ AtCmdFrame::AtCmdResp cmdresp;
+
+ uint32_t var32;
+ cmdresp = get_param("CH", &var32);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ *channel = var32;
+ return Success;
+}
+
+RadioStatus XBeeDM::set_network_id(uint16_t network_id)
+{
+ AtCmdFrame::AtCmdResp cmdresp;
+
+ cmdresp = set_param("ID", network_id);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ return Success;
+}
+
+RadioStatus XBeeDM::get_network_id(uint16_t * const network_id)
+{
+ if (network_id == NULL) {
+ return Failure;
+ }
+ AtCmdFrame::AtCmdResp cmdresp;
+
+ uint32_t var32;
+ cmdresp = get_param("ID", &var32);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ *network_id = var32;
+ return Success;
+}
+
+RadioStatus XBeeDM::get_node_discovery_timeout(uint16_t * const timeout_ms)
+{
+ AtCmdFrame::AtCmdResp cmdresp;
+ uint32_t var32;
+
+ cmdresp = get_param("N?", &var32);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ *timeout_ms = (uint16_t)var32;
+
+ return Success;
+}
+
+RadioStatus XBeeDM::get_node_discovery_timeout(uint16_t * const timeout_ms, bool * const wait_for_complete_timeout)
+{
+ const RadioStatus status = get_node_discovery_timeout(timeout_ms);
+
+ *wait_for_complete_timeout = false;
+
+ return status;
+}
+
+RadioStatus XBeeDM::set_network_security_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("NK", key, length);
+ return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
+}
+
+RadioStatus XBeeDM::set_encryption_options(const uint8_t options)
+{
+ AtCmdFrame::AtCmdResp cmdresp;
+
+ cmdresp = set_param("EO", options);
+ return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
+}
+
+void XBeeDM::radio_status_update(AtCmdFrame::ModemStatus modem_status)
+{
+ /* Update the radio status variables */
+ if (modem_status == AtCmdFrame::HwReset) {
+ _hw_reset_cnt++;
+ } else if (modem_status == AtCmdFrame::WdReset) {
+ _wd_reset_cnt++;
+ }
+
+ _modem_status = modem_status;
+
+ digi_log(LogLevelDebug, "\r\nUpdating radio status: %02x\r\n", modem_status);
+}
+
+TxStatus XBeeDM::send_data(const RemoteXBee& remote, const uint8_t *const data, uint16_t len, bool syncr)
+{
+ if (!remote.is_valid_addr64b()) {
+ return TxStatusInvalidAddr;
+ }
+
+ const uint64_t remote64 = remote.get_addr64();
+ const uint16_t remote16 = remote.get_addr16();
+
+ TxFrameDM frame = TxFrameDM(remote64, remote16, BROADCAST_RADIUS_USE_NH,
+ _tx_options, data, len);
+ if (syncr) {
+ return send_data(&frame);
+ } else {
+ frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
+ send_api_frame(&frame);
+ return TxStatusSuccess;
+ }
+}
+
+TxStatus XBeeDM::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()) {
+ return TxStatusInvalidAddr;
+ }
+
+ const uint64_t remote64 = remote.get_addr64();
+ const uint16_t remote16 = remote.get_addr16();
+
+ TxFrameDM frame = TxFrameDM(remote64, remote16, source_ep, dest_ep,
+ cluster_id, profile_id, BROADCAST_RADIUS_USE_NH,
+ _tx_options, data, len);
+ if (syncr) {
+ return send_data(&frame);
+ } else {
+ frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
+ send_api_frame(&frame);
+ return TxStatusSuccess;
+ }
+}
+
+TxStatus XBeeDM::send_data_to_coordinator(const uint8_t *const data, uint16_t len, bool syncr)
+{
+ const uint64_t remaddr = ADDR64_COORDINATOR;
+
+ TxFrameDM frame = TxFrameDM(remaddr, ADDR16_UNKNOWN, BROADCAST_RADIUS_USE_NH, _tx_options, data, len);
+ if (syncr) {
+ return send_data(&frame);
+ } else {
+ frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
+ send_api_frame(&frame);
+ return TxStatusSuccess;
+ }
+}
+
+RemoteXBeeDM XBeeDM::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 RemoteXBeeDM(addr64);
+}
+
+XBeeDM::AssocStatus XBeeDM::get_assoc_status(void)
+{
+ return (AssocStatus)get_AI();
+}
+
+void XBeeDM::register_node_discovery_cb(node_discovery_dm_cb_t function)
+{
+ if (_nd_handler == NULL) {
+ _nd_handler = new FH_NodeDiscoveryDM();
+ register_frame_handler(_nd_handler);
+ }
+ _nd_handler->register_node_discovery_cb(function);
+}
+
+void XBeeDM::unregister_node_discovery_cb()
+{
+ if (_nd_handler != NULL) {
+ _nd_handler->unregister_node_discovery_cb();
+ unregister_frame_handler(_nd_handler);
+ delete _nd_handler;
+ _nd_handler = NULL; /* as delete does not set to NULL */
+ }
+}
+
+void XBeeDM::register_receive_cb(receive_dm_cb_t function)
+{
+ if (_rx_pkt_handler == NULL) {
+ _rx_pkt_handler = new FH_RxPacketDM();
+ register_frame_handler(_rx_pkt_handler);
+ }
+ _rx_pkt_handler->register_receive_cb(function);
+}
+
+void XBeeDM::unregister_receive_cb()
+{
+ if (_rx_pkt_handler != NULL) {
+ _rx_pkt_handler->unregister_receive_cb();
+ unregister_frame_handler(_rx_pkt_handler);
+ delete _rx_pkt_handler;
+ _rx_pkt_handler = NULL; /* as delete does not set to NULL */
+ }
+}
+
+void XBeeDM::register_io_sample_cb(io_data_cb_dm_t function)
+{
+ if (_io_data_handler == NULL) {
+ _io_data_handler = new FH_IoDataSampeDM();
+ register_frame_handler(_io_data_handler);
+ }
+ _io_data_handler->register_io_data_cb(function);
+}
+
+void XBeeDM::unregister_io_sample_cb()
+{
+ if (_io_data_handler != NULL) {
+ _io_data_handler->unregister_io_data_cb();
+ unregister_frame_handler(_io_data_handler);
+ delete _io_data_handler;
+ _io_data_handler = NULL; /* as delete does not set to NULL */
+ }
+}
+
+AtCmdFrame::AtCmdResp XBeeDM::get_param(const RemoteXBee& remote, const char * const param, uint32_t * const data)
+{
+ if (!remote.is_valid_addr64b()) {
+ return AtCmdFrame::AtCmdRespInvalidAddr;
+ }
+
+ const uint64_t remote64 = remote.get_addr64();
+ const uint16_t remote16 = remote.get_addr16();
+ uint16_t len = sizeof *data;
+ AtCmdFrame::AtCmdResp atCmdResponse;
+
+ 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) {
+ atCmdResponse = AtCmdFrame::AtCmdRespLenMismatch;
+ }
+
+ return atCmdResponse;
+}
+
+AtCmdFrame::AtCmdResp XBeeDM::set_param(const RemoteXBee& remote, const char * const param, uint32_t data)
+{
+ if (!remote.is_valid_addr64b()) {
+ return AtCmdFrame::AtCmdRespInvalidAddr;
+ }
+
+ const uint64_t remote64 = remote.get_addr64();
+ const uint16_t remote16 = remote.get_addr16();
+
+ AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param, data);
+ return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
+}
+
+AtCmdFrame::AtCmdResp XBeeDM::set_param(const RemoteXBee& remote, const char * const param, const uint8_t * data, uint16_t len)
+{
+ if (!remote.is_valid_addr64b()) {
+ return AtCmdFrame::AtCmdRespInvalidAddr;
+ }
+
+ const uint64_t remote64 = remote.get_addr64();
+ const uint16_t remote16 = remote.get_addr16();
+
+ AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param, data, len);
+ return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
+}
+
+AtCmdFrame::AtCmdResp XBeeDM::get_param(const RemoteXBee& remote, const char * const param, uint8_t * const data, uint16_t * const len)
+{
+
+ if (!remote.is_valid_addr64b()) {
+ return AtCmdFrame::AtCmdRespInvalidAddr;
+ }
+
+ const uint64_t remote64 = remote.get_addr64();
+ const uint16_t remote16 = remote.get_addr16();
+
+ AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param);
+ return send_at_cmd(&cmd_frame, data, len, RadioRemote, false);
+}
+
+static void get_dio_cmd(XBeeDM::IoLine line, char * const iocmd)
+{
+ if (line >= XBeeDM::DIO10_PWM0) {
+ iocmd[0] = 'P';
+ iocmd[1] = '0' + line - XBeeDM::DIO10_PWM0;
+ } else {
+ iocmd[0] = 'D';
+ iocmd[1] = '0' + line;
+ }
+ iocmd[2] = '\0';
+}
+
+RadioStatus XBeeDM::set_pin_config(const RemoteXBee& remote, IoLine line, IoMode mode)
+{
+ AtCmdFrame::AtCmdResp cmdresp;
+ char iocmd[3];
+
+ get_dio_cmd(line, iocmd);
+
+ cmdresp = set_param(remote, iocmd, (uint8_t)mode);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ digi_log(LogLevelError, "set_pin_config: set_param returned %d\r\n", cmdresp);
+ return Failure;
+ }
+
+ return Success;
+}
+
+RadioStatus XBeeDM::get_pin_config(const RemoteXBee& remote, IoLine line, IoMode * const mode)
+{
+ AtCmdFrame::AtCmdResp cmdresp;
+ char iocmd[3];
+
+ get_dio_cmd(line, iocmd);
+
+ uint32_t var32;
+ cmdresp = get_param(remote, iocmd, &var32);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ *mode = (IoMode)var32;
+
+ return Success;
+}
+
+RadioStatus XBeeDM::set_dio(const RemoteXBee& remote, IoLine line, DioVal val)
+{
+ return set_pin_config(remote, line, val == Low ? DigitalOutLow : DigitalOutHigh);
+}
+
+RadioStatus XBeeDM::get_dio(const RemoteXBee& remote, IoLine line, DioVal * const val)
+{
+ return get_iosample(remote).get_dio(line, val);
+}
+
+RadioStatus XBeeDM::get_adc(const RemoteXBee& remote, IoLine line, uint16_t * const val)
+{
+ return get_iosample(remote).get_adc(line, val);
+}
+
+RadioStatus XBeeDM::set_pwm(const RemoteXBee& remote, IoLine line, float duty_cycle)
+{
+ AtCmdFrame::AtCmdResp cmdresp;
+ char iocmd[3] = { 'M', '0', '\0' };
+
+ if (line != DIO10_PWM0 && line != DIO11_PWM1) {
+ return Failure;
+ }
+ if (line == DIO11_PWM1) {
+ iocmd[1] = '1';
+ }
+
+ uint16_t pwm_val = (uint16_t)(duty_cycle * DR_PWM_MAX_VAL / 100);
+
+ cmdresp = set_param(remote, iocmd, pwm_val);
+ return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
+}
+
+IOSampleDM XBeeDM::get_iosample(const RemoteXBee& remote)
+{
+ uint8_t io_sample[MAX_IO_SAMPLE_DM_LEN];
+ uint16_t len = sizeof io_sample;
+
+ RadioStatus resp = _get_iosample(remote, io_sample, &len);
+ if (resp != Success) {
+ digi_log(LogLevelError, "XBeeDM::get_iosample failed to get an IOSample\r\n");
+ len = 0;
+ }
+
+ return IOSampleDM(io_sample, len);
+}
+
+static uint16_t get_dio_pr_mask(XBeeDM::IoLine line)
+{
+ switch (line) {
+ case XBeeDM::DIO4:
+ return (1 << 0);
+ case XBeeDM::DIO3_AD3:
+ return (1 << 1);
+ case XBeeDM::DIO2_AD2:
+ return (1 << 2);
+ case XBeeDM::DIO1_AD1:
+ return (1 << 3);
+ case XBeeDM::DIO0_AD0:
+ return (1 << 4);
+ case XBeeDM::DIO6:
+ return (1 << 5);
+ case XBeeDM::DIO8:
+ return (1 << 6);
+ case XBeeDM::DIO5:
+ return (1 << 8);
+ case XBeeDM::DIO9:
+ return (1 << 9);
+ case XBeeDM::DIO12:
+ return (1 << 10);
+ case XBeeDM::DIO10_PWM0:
+ return (1 << 11);
+ case XBeeDM::DIO11_PWM1:
+ return (1 << 12);
+ case XBeeDM::DIO7:
+ return (1 << 13);
+ default:
+ return 0;
+ }
+}
+
+RadioStatus XBeeDM::set_pin_pull_up(const RemoteXBee& remote, IoLine line, bool enable)
+{
+ AtCmdFrame::AtCmdResp cmdresp;
+ uint32_t var32;
+ uint16_t pr;
+
+ cmdresp = get_param(remote, "PR", &var32);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ pr = var32;
+
+ const uint16_t dio_mask = get_dio_pr_mask(line);
+ if (dio_mask == 0) {
+ digi_log(LogLevelError, "XBeeDM::set_pin_pull_up: invalid pin %d\r\n", line);
+ return Failure;
+ }
+
+ if (enable) {
+ pr |= dio_mask;
+ } else {
+ pr &= ~dio_mask;
+ }
+
+ cmdresp = set_param(remote, "PR", pr);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+
+ return Success;
+}
+
+static uint16_t get_dio_ic_mask(XBeeDM::IoLine line)
+{
+ if (line <= XBeeDM::DIO12) {
+ return (1 << line);
+ }
+ return 0;
+}
+
+RadioStatus XBeeDM::enable_dio_change_detection(const RemoteXBee& remote, IoLine line, bool enable)
+{
+ if (line > DIO12) {
+ digi_log(LogLevelError, "XBeeDM::enable_dio_change_detection: pin not supported (%d)\r\n", line);
+ return Failure;
+ }
+
+ AtCmdFrame::AtCmdResp cmdresp;
+ uint32_t var32;
+ uint16_t ic;
+
+ cmdresp = get_param(remote, "IC", &var32);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ ic = var32;
+
+ const uint16_t dio_mask = get_dio_ic_mask(line);
+ if (dio_mask == 0) {
+ digi_log(LogLevelError, "XBeeDM::enable_dio_change_detection: invalid pin %d\r\n", line);
+ return Failure;
+ }
+
+ if (enable) {
+ ic |= dio_mask;
+ } else {
+ ic &= ~dio_mask;
+ }
+
+ cmdresp = set_param(remote, "IC", ic);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+
+ return Success;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/XBeeDM/XBeeDM.h Thu Jul 28 10:17:20 2016 +0200
@@ -0,0 +1,414 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#if !defined(__XBEE_DM_H_)
+#define __XBEE_DM_H_
+
+#include "XBee/XBee.h"
+#include "FrameHandlers/FH_AtCmdResp.h"
+#include "FrameHandlers/FH_RxPacketDM.h"
+#include "FrameHandlers/FH_IoDataSampleDM.h"
+#include "RemoteXBee/RemoteXBee.h"
+
+namespace XBeeLib {
+
+/** Class for XBee ZigBee modules, derived from XBee */
+class XBeeDM : public XBee
+{
+ public:
+
+ /**
+ * IoLine for XBeeDM Modules
+ */
+ enum IoLine {
+ DIO0_AD0 = 0, /**< DIO0_AD0 pin */
+ DIO1_AD1 = 1, /**< DIO1_AD1 pin */
+ DIO2_AD2 = 2, /**< DIO2_AD2 pin */
+ DIO3_AD3 = 3, /**< DIO3_AD3 pin */
+ DIO4 = 4, /**< DIO4 pin */
+ DIO5 = 5, /**< DIO5 pin */
+ DIO6 = 6, /**< DIO6 pin */
+ DIO7 = 7, /**< DIO7 pin */
+ DIO8 = 8, /**< DIO8 pin */
+ DIO9 = 9, /**< DIO9 pin */
+ DIO10_PWM0 = 10, /**< DIO10_PWM0 pin */
+ DIO11_PWM1 = 11, /**< DIO11_PWM1 pin */
+ DIO12 = 12 /**< DIO12 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
+ * @param reset the pin to which the XBee's reset line is attached to, use NC if not available
+ * @param rts the RTS pin for the UART that will interface the XBee module, use NC if not available
+ * @param cts the CTS pin for the UART that will interface the XBee module, use NC if not available
+ * @param baud the baudrate for the UART that will interface the XBee module. Note that the module has to be already configured
+ * to this baud rate (ATBD parameter). By default it is configured to 9600 bps
+ */
+ XBeeDM(PinName tx, PinName rx, PinName reset = NC, PinName rts = NC, PinName cts = NC, int baud = 9600);
+
+ /** Class destructor */
+ virtual ~XBeeDM();
+
+ /** init- initializes object
+ * This function must be called just after creating the object so it initializes internal data.
+ * @returns
+ * Success if the module has been properly initialized and is ready to process data.
+ * Failure otherwise.
+ */
+ RadioStatus init();
+
+ /** set_channel - sets the channel number
+ *
+ * @param channel the channel in which the radio operates. Range is 0x0B - 0x1A for XBee and 0x0C - 0x17 for XBee-PRO.
+ * The Center Frequency = 2.405 + (CH - 11) * 5 MHz
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus set_channel(uint8_t channel);
+
+ /** get_channel - gets the channel number
+ *
+ * @param channel pointer where the channel value will be stored.
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus get_channel(uint8_t * const channel);
+
+ /** set_network_id - sets the Network ID.
+ *
+ * @param network_id the Network ID value that will be set on the radio
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus set_network_id(uint16_t network_id);
+
+ /** get_network_id - gets the Network ID, as it was set by @ref set_network_id().
+ *
+ * @param network_id pointer where the Network ID will be stored
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus get_network_id(uint16_t * const network_id);
+
+ /** 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'
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus set_network_security_key(const uint8_t * const key, const uint16_t length);
+
+#define XBEE_DM_ENC_OPT_SEND_KEY_ON_JOIN 0x01
+#define XBEE_DM_ENC_OPT_USE_TRUST_CENTER 0x02
+ /** set_encryption_options - Configure options for encryption. Unused option bits should be set to 0. Options include:
+ * - XBEE_DM_ENC_OPT_SEND_KEY_ON_JOIN - Send the security key unsecured over-the-air during joins
+ * - XBEE_DM_ENC_OPT_USE_TRUST_CENTER - Use trust center (coordinator only)
+ * @param options bit mask with the encryption options
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus set_encryption_options(const uint8_t options);
+
+ /** register_node_discovery_cb - registers the callback function that will be called
+ * when the responses to the node discovery command arrive
+ *
+ * @param function function pointer with the callback function
+ */
+ void register_node_discovery_cb(node_discovery_dm_cb_t function);
+
+ /** unregister_node_discovery_cb - removes the node discovery callback */
+ void unregister_node_discovery_cb();
+
+ /** register_receive_cb - registers the callback function that will be called
+ * when a data packet is received
+ *
+ * @param function function pointer with the callback function
+ */
+ void register_receive_cb(receive_dm_cb_t function);
+
+ /** 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
+ *
+ * @param function function pointer with the callback function
+ */
+ void register_io_sample_cb(io_data_cb_dm_t function);
+
+ /** unregister_io_sample_cb - removes the IO Sample Data reception callback */
+ void unregister_io_sample_cb();
+
+ /*********************** send_data member methods ************************/
+ /** send_data - sends data to a remote device
+ *
+ * @param remote remote device
+ * @param data pointer to the data that will be sent
+ * @param len number of bytes that will be transmitted
+ * @param syncr if true, method waits for the packet answer with the result of the operation
+ * @returns the result of the data transfer
+ * 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);
+
+ /** send_data - sends data to a remote device. This method uses
+ * the explicit addressing frame, allowing to use source and
+ * destination end points and cluster and profile IDs
+ *
+ * @param remote remote device
+ * @param source_ep source end point
+ * @param dest_ep destination end point
+ * @param cluster_id cluster ID
+ * @param profile_id profile ID
+ * @param data pointer to the data that will be sent
+ * @param len number of bytes that will be transmitted
+ * @param syncr if true, method waits for the packet answer with the result of the operation
+ * @returns the result of the data transfer
+ * TxStatusSuccess if the operation was successful,
+ * the error code otherwise
+ */
+ 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);
+
+ /** send_data_to_coordinator - sends data to the ZigBee coordinator
+ *
+ * @param data pointer to the data that will be sent
+ * @param len number of bytes that will be transmitted
+ * @param syncr if true, method waits for the packet answer with the result of the operation
+ * @returns the result of the data transfer
+ * TxStatusSuccess if the operation was successful,
+ * the error code otherwise
+ */
+ 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);
+
+ /** 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
+ * @returns a RemoteXBeeDM with the 16-bit and 64-bit address of the remote device whose node id matches with the parameter.
+ * If node is not found, the returned object will have invalid addresses (RemoteXBeeDM::is_valid() will return false).
+ */
+ RemoteXBeeDM get_remote_node_by_id(const char * const node_id);
+
+ /* Allow using XBee::set_param() methods for local radio from this class */
+ using XBee::set_param;
+
+ /** 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 (4 bytes) to be set.
+ * @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 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;
+
+ /** 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.
+ * @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.
+ * @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);
+
+ /************************* IO member methods **************************/
+ /** set_pin_config - configures a radio IO line
+ *
+ * @param remote remote device
+ * @param line IO line being configured
+ * @param mode configuration mode for the selected line
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus set_pin_config(const RemoteXBee& remote, IoLine line, IoMode mode);
+
+ /** get_pin_config - gets the configuration of a radio IO line
+ *
+ * @param remote remote device
+ * @param line IO line being read to get its configuration
+ * @param mode pointer where the configuration will be stored
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus get_pin_config(const RemoteXBee& remote, IoLine line, IoMode * const mode);
+
+ /** set_dio - sets to low/high a DIO line
+ *
+ * @param remote remote device
+ * @param line DIO line being set
+ * @param val value that will be set in the DIO line
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus set_dio(const RemoteXBee& remote, IoLine line, DioVal val);
+
+ /** get_dio - read the value of a DIO configured as digital input
+ *
+ * @param remote remote device
+ * @param line DIO line being read
+ * @param val pointer where the DIO value read will be stored
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus get_dio(const RemoteXBee& remote, IoLine line, DioVal * const val);
+
+ /** get_adc - read the value of the espcified ADC line
+ *
+ * @param remote remote device
+ * @param line ADC line being read
+ * @param val pointer where the value read from hte ADC will be stored
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus get_adc(const RemoteXBee& remote, IoLine line, uint16_t * const val);
+
+ /** get_iosample - retrieves an @ref IOSampleDM from a remote node. This object can be used to get the remote node's ADC and DIO values.
+ *
+ * @param remote remote device
+ * @returns IOSampleDM object with the remote node's DIO and ADC values.
+ */
+ IOSampleDM get_iosample(const RemoteXBee& remote);
+
+ /** set_pwm - sets the duty cycle of a PWM line
+ *
+ * @param remote remote device
+ * @param line PWM line being set
+ * @param duty_cycle duty cycle that will be set in the PWM line
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus set_pwm(const RemoteXBee& remote, IoLine line, float duty_cycle);
+
+ /** set_pin_pull_up - enables or disables the internal pull-up resistor of a line
+ *
+ * @param remote remote device
+ * @param line line being configured for pull-up
+ * @param enable whether to enable the internal pull-up resistor.
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus set_pin_pull_up(const RemoteXBee& remote, IoLine line, bool enable);
+
+ /** enable_dio_change_detection - enables or disables the notification when a change is detected in a digital input line.
+ * In other words, it will force an IO Sample transmission when the DIO state changes. Only for DIO0 to DIO11.
+ *
+ * @param remote remote device
+ * @param line line being configured for pull-up
+ * @param enable whether to enable the internal pull-up resistor.
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus enable_dio_change_detection(const RemoteXBee& remote, IoLine line, bool enable);
+
+ protected:
+
+ /** Frame handler used for the node discovery. Registered when a callback function
+ * is registered */
+ FH_NodeDiscoveryDM *_nd_handler;
+
+ /** Frame handler used for the rx packets. Automatically registered when a callback
+ * function is registered */
+ FH_RxPacketDM *_rx_pkt_handler;
+
+ /** Frame handler used for the IO Data Sample packets. Automatically registered when a callback
+ * function is registered */
+ FH_IoDataSampeDM *_io_data_handler;
+
+ /** 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;
+
+ /** get_node_discovery_timeout - gets the node discovery timeout
+ *
+ * @param timeout_ms pointer where the node discovery timeout value will be stored
+ * @param wait_for_complete_timeout pointer where the function will store if the operator
+ * has to wait for the complete nd timeout after issuing
+ * a directed nd request
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ virtual RadioStatus get_node_discovery_timeout(uint16_t * const timeout_ms);
+ virtual RadioStatus get_node_discovery_timeout(uint16_t * const timeout_ms, bool * const wait_for_complete_timeout);
+};
+
+} /* namespace XBeeLib */
+
+#endif /* __XBEE_DM_H_ */
--- a/XBeeLib.h Thu Mar 31 11:39:30 2016 +0200 +++ b/XBeeLib.h Thu Jul 28 10:17:20 2016 +0200 @@ -30,6 +30,8 @@ #include "IO/IOSampleZB.h" #include "XBee802/XBee802.h" #include "IO/IOSample802.h" +#include "XBeeDM/XBeeDM.h" +#include "IO/IOSampleDM.h" #include "XBee/Addresses.h" #include "RemoteXBee/RemoteXBee.h"
--- a/XBeeZB/XBeeZB.cpp Thu Mar 31 11:39:30 2016 +0200
+++ b/XBeeZB/XBeeZB.cpp Thu Jul 28 10:17:20 2016 +0200
@@ -27,6 +27,13 @@
RadioStatus XBeeZB::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 != ZigBee) {
@@ -185,6 +192,48 @@
return Success;
}
+RadioStatus XBeeZB::get_network_address(uint16_t * const addr16)
+{
+ if (addr16 == NULL) {
+ return Failure;
+ }
+ AtCmdFrame::AtCmdResp cmdresp;
+
+ uint32_t var32;
+ cmdresp = get_param("MY", &var32);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ *addr16 = var32;
+ return Success;
+}
+
+RadioStatus XBeeZB::get_node_discovery_timeout(uint16_t * const timeout_ms)
+{
+ AtCmdFrame::AtCmdResp cmdresp;
+ uint32_t var32;
+
+ cmdresp = get_param("NT", &var32);
+ if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+ return Failure;
+ }
+ *timeout_ms = (uint16_t)var32;
+
+ /* No N? command available for this protocol. Add a fix 1s guard time */
+ *timeout_ms += 1000;
+
+ return Success;
+}
+
+RadioStatus XBeeZB::get_node_discovery_timeout(uint16_t * const timeout_ms, bool * const wait_for_complete_timeout)
+{
+ const RadioStatus status = get_node_discovery_timeout(timeout_ms);
+
+ *wait_for_complete_timeout = false;
+
+ return status;
+}
+
RadioStatus XBeeZB::check_for_coordinator_at_start(bool enable)
{
AtCmdFrame::AtCmdResp cmdresp;
--- a/XBeeZB/XBeeZB.h Thu Mar 31 11:39:30 2016 +0200
+++ b/XBeeZB/XBeeZB.h Thu Jul 28 10:17:20 2016 +0200
@@ -170,6 +170,15 @@
*/
RadioStatus get_channel_mask(uint16_t * const chmask);
+ /** get_network_address - gets the 16bit network address of the device
+ *
+ * @param addr pointer where the device 16bit network address will be stored
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ RadioStatus get_network_address(uint16_t * const addr);
+
/** check_for_coordinator_at_start - (Routers only) If enabled, a router will verify the coordinator is on its operating channel when joining or coming up from a power cycle.
* If a coordinator is not detected, the router will leave its current channel and attempt to join a new PAN. If JV=0, the router will continue operating on its current channel even if a coordinator is not detected.
*
@@ -445,6 +454,19 @@
/* Allow using XBee::send_data() methods from this class */
using XBee::send_data;
+
+ /** get_node_discovery_timeout - gets the node discovery timeout
+ *
+ * @param timeout_ms pointer where the node discovery timeout value will be stored
+ * @param wait_for_complete_timeout pointer where the function will store if the operator
+ * has to wait for the complete nd timeout after issuing
+ * a directed nd request
+ * @returns
+ * Success if the operation was successful,
+ * Failure otherwise
+ */
+ virtual RadioStatus get_node_discovery_timeout(uint16_t * const timeout_ms);
+ virtual RadioStatus get_node_discovery_timeout(uint16_t * const timeout_ms, bool * const wait_for_complete_timeout);
};
} /* namespace XBeeLib */
