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.
Fork of XBeeLib 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 */
