Fork of my MQTTGateway

Dependencies:   mbed-http

Committer:
vpcola
Date:
Sat Apr 08 14:45:51 2017 +0000
Revision:
0:f1d3878b8dd9
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vpcola 0:f1d3878b8dd9 1 /**
vpcola 0:f1d3878b8dd9 2 * Copyright (c) 2015 Digi International Inc.,
vpcola 0:f1d3878b8dd9 3 * All rights not expressly granted are reserved.
vpcola 0:f1d3878b8dd9 4 *
vpcola 0:f1d3878b8dd9 5 * This Source Code Form is subject to the terms of the Mozilla Public
vpcola 0:f1d3878b8dd9 6 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
vpcola 0:f1d3878b8dd9 7 * You can obtain one at http://mozilla.org/MPL/2.0/.
vpcola 0:f1d3878b8dd9 8 *
vpcola 0:f1d3878b8dd9 9 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
vpcola 0:f1d3878b8dd9 10 * =======================================================================
vpcola 0:f1d3878b8dd9 11 */
vpcola 0:f1d3878b8dd9 12
vpcola 0:f1d3878b8dd9 13 #include "XBeeDM.h"
vpcola 0:f1d3878b8dd9 14 #include "IO/IOSampleDM.h"
vpcola 0:f1d3878b8dd9 15 #include "Frames/DigiMeshFrames.h"
vpcola 0:f1d3878b8dd9 16
vpcola 0:f1d3878b8dd9 17 using namespace XBeeLib;
vpcola 0:f1d3878b8dd9 18
vpcola 0:f1d3878b8dd9 19 #define BROADCAST_RADIUS_USE_NH 0x00
vpcola 0:f1d3878b8dd9 20
vpcola 0:f1d3878b8dd9 21 /* Class constructor */
vpcola 0:f1d3878b8dd9 22 XBeeDM::XBeeDM(PinName tx, PinName rx, PinName reset, PinName rts, PinName cts, int baud) :
vpcola 0:f1d3878b8dd9 23 XBee(tx, rx, reset, rts, cts, baud), _nd_handler(NULL), _rx_pkt_handler(NULL), _io_data_handler(NULL)
vpcola 0:f1d3878b8dd9 24 {
vpcola 0:f1d3878b8dd9 25 }
vpcola 0:f1d3878b8dd9 26
vpcola 0:f1d3878b8dd9 27 RadioStatus XBeeDM::init()
vpcola 0:f1d3878b8dd9 28 {
vpcola 0:f1d3878b8dd9 29 RadioStatus retval = XBee::init();
vpcola 0:f1d3878b8dd9 30
vpcola 0:f1d3878b8dd9 31 const RadioProtocol radioProtocol = get_radio_protocol();
vpcola 0:f1d3878b8dd9 32 if (radioProtocol != DigiMesh) {
vpcola 0:f1d3878b8dd9 33 digi_log(LogLevelError, "Radio protocol does not match, needed a %d got a %d\r\n", DigiMesh, radioProtocol);
vpcola 0:f1d3878b8dd9 34 retval = Failure;
vpcola 0:f1d3878b8dd9 35 }
vpcola 0:f1d3878b8dd9 36 assert(radioProtocol == DigiMesh);
vpcola 0:f1d3878b8dd9 37
vpcola 0:f1d3878b8dd9 38 return retval;
vpcola 0:f1d3878b8dd9 39 }
vpcola 0:f1d3878b8dd9 40
vpcola 0:f1d3878b8dd9 41 /* Class destructor */
vpcola 0:f1d3878b8dd9 42 XBeeDM::~XBeeDM()
vpcola 0:f1d3878b8dd9 43 {
vpcola 0:f1d3878b8dd9 44 unregister_node_discovery_cb();
vpcola 0:f1d3878b8dd9 45 unregister_receive_cb();
vpcola 0:f1d3878b8dd9 46 unregister_io_sample_cb();
vpcola 0:f1d3878b8dd9 47 }
vpcola 0:f1d3878b8dd9 48
vpcola 0:f1d3878b8dd9 49 RadioStatus XBeeDM::set_channel(uint8_t channel)
vpcola 0:f1d3878b8dd9 50 {
vpcola 0:f1d3878b8dd9 51 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 52
vpcola 0:f1d3878b8dd9 53 /* Pro and Non-Pro modules have different channels available. The at
vpcola 0:f1d3878b8dd9 54 command will return an error if the selected channel is not available */
vpcola 0:f1d3878b8dd9 55 cmdresp = set_param("CH", channel);
vpcola 0:f1d3878b8dd9 56 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 57 return Failure;
vpcola 0:f1d3878b8dd9 58 }
vpcola 0:f1d3878b8dd9 59 return Success;
vpcola 0:f1d3878b8dd9 60 }
vpcola 0:f1d3878b8dd9 61
vpcola 0:f1d3878b8dd9 62 RadioStatus XBeeDM::get_channel(uint8_t * const channel)
vpcola 0:f1d3878b8dd9 63 {
vpcola 0:f1d3878b8dd9 64 if (channel == NULL) {
vpcola 0:f1d3878b8dd9 65 return Failure;
vpcola 0:f1d3878b8dd9 66 }
vpcola 0:f1d3878b8dd9 67 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 68
vpcola 0:f1d3878b8dd9 69 uint32_t var32;
vpcola 0:f1d3878b8dd9 70 cmdresp = get_param("CH", &var32);
vpcola 0:f1d3878b8dd9 71 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 72 return Failure;
vpcola 0:f1d3878b8dd9 73 }
vpcola 0:f1d3878b8dd9 74 *channel = var32;
vpcola 0:f1d3878b8dd9 75 return Success;
vpcola 0:f1d3878b8dd9 76 }
vpcola 0:f1d3878b8dd9 77
vpcola 0:f1d3878b8dd9 78 RadioStatus XBeeDM::set_network_id(uint16_t network_id)
vpcola 0:f1d3878b8dd9 79 {
vpcola 0:f1d3878b8dd9 80 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 81
vpcola 0:f1d3878b8dd9 82 cmdresp = set_param("ID", network_id);
vpcola 0:f1d3878b8dd9 83 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 84 return Failure;
vpcola 0:f1d3878b8dd9 85 }
vpcola 0:f1d3878b8dd9 86 return Success;
vpcola 0:f1d3878b8dd9 87 }
vpcola 0:f1d3878b8dd9 88
vpcola 0:f1d3878b8dd9 89 RadioStatus XBeeDM::get_network_id(uint16_t * const network_id)
vpcola 0:f1d3878b8dd9 90 {
vpcola 0:f1d3878b8dd9 91 if (network_id == NULL) {
vpcola 0:f1d3878b8dd9 92 return Failure;
vpcola 0:f1d3878b8dd9 93 }
vpcola 0:f1d3878b8dd9 94 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 95
vpcola 0:f1d3878b8dd9 96 uint32_t var32;
vpcola 0:f1d3878b8dd9 97 cmdresp = get_param("ID", &var32);
vpcola 0:f1d3878b8dd9 98 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 99 return Failure;
vpcola 0:f1d3878b8dd9 100 }
vpcola 0:f1d3878b8dd9 101 *network_id = var32;
vpcola 0:f1d3878b8dd9 102 return Success;
vpcola 0:f1d3878b8dd9 103 }
vpcola 0:f1d3878b8dd9 104
vpcola 0:f1d3878b8dd9 105 RadioStatus XBeeDM::get_node_discovery_timeout(uint16_t * const timeout_ms)
vpcola 0:f1d3878b8dd9 106 {
vpcola 0:f1d3878b8dd9 107 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 108 uint32_t var32;
vpcola 0:f1d3878b8dd9 109
vpcola 0:f1d3878b8dd9 110 cmdresp = get_param("N?", &var32);
vpcola 0:f1d3878b8dd9 111 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 112 return Failure;
vpcola 0:f1d3878b8dd9 113 }
vpcola 0:f1d3878b8dd9 114 *timeout_ms = (uint16_t)var32;
vpcola 0:f1d3878b8dd9 115
vpcola 0:f1d3878b8dd9 116 return Success;
vpcola 0:f1d3878b8dd9 117 }
vpcola 0:f1d3878b8dd9 118
vpcola 0:f1d3878b8dd9 119 RadioStatus XBeeDM::get_node_discovery_timeout(uint16_t * const timeout_ms, bool * const wait_for_complete_timeout)
vpcola 0:f1d3878b8dd9 120 {
vpcola 0:f1d3878b8dd9 121 const RadioStatus status = get_node_discovery_timeout(timeout_ms);
vpcola 0:f1d3878b8dd9 122
vpcola 0:f1d3878b8dd9 123 *wait_for_complete_timeout = false;
vpcola 0:f1d3878b8dd9 124
vpcola 0:f1d3878b8dd9 125 return status;
vpcola 0:f1d3878b8dd9 126 }
vpcola 0:f1d3878b8dd9 127
vpcola 0:f1d3878b8dd9 128 void XBeeDM::radio_status_update(AtCmdFrame::ModemStatus modem_status)
vpcola 0:f1d3878b8dd9 129 {
vpcola 0:f1d3878b8dd9 130 /* Update the radio status variables */
vpcola 0:f1d3878b8dd9 131 if (modem_status == AtCmdFrame::HwReset) {
vpcola 0:f1d3878b8dd9 132 _hw_reset_cnt++;
vpcola 0:f1d3878b8dd9 133 } else if (modem_status == AtCmdFrame::WdReset) {
vpcola 0:f1d3878b8dd9 134 _wd_reset_cnt++;
vpcola 0:f1d3878b8dd9 135 }
vpcola 0:f1d3878b8dd9 136
vpcola 0:f1d3878b8dd9 137 _modem_status = modem_status;
vpcola 0:f1d3878b8dd9 138
vpcola 0:f1d3878b8dd9 139 digi_log(LogLevelDebug, "\r\nUpdating radio status: %02x\r\n", modem_status);
vpcola 0:f1d3878b8dd9 140 }
vpcola 0:f1d3878b8dd9 141
vpcola 0:f1d3878b8dd9 142 TxStatus XBeeDM::send_data(const RemoteXBee& remote, const uint8_t *const data, uint16_t len, bool syncr)
vpcola 0:f1d3878b8dd9 143 {
vpcola 0:f1d3878b8dd9 144 if (!remote.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 145 return TxStatusInvalidAddr;
vpcola 0:f1d3878b8dd9 146 }
vpcola 0:f1d3878b8dd9 147
vpcola 0:f1d3878b8dd9 148 const uint64_t remote64 = remote.get_addr64();
vpcola 0:f1d3878b8dd9 149 const uint16_t remote16 = remote.get_addr16();
vpcola 0:f1d3878b8dd9 150
vpcola 0:f1d3878b8dd9 151 TxFrameDM frame = TxFrameDM(remote64, remote16, BROADCAST_RADIUS_USE_NH,
vpcola 0:f1d3878b8dd9 152 _tx_options, data, len);
vpcola 0:f1d3878b8dd9 153 if (syncr) {
vpcola 0:f1d3878b8dd9 154 return send_data(&frame);
vpcola 0:f1d3878b8dd9 155 } else {
vpcola 0:f1d3878b8dd9 156 frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
vpcola 0:f1d3878b8dd9 157 send_api_frame(&frame);
vpcola 0:f1d3878b8dd9 158 return TxStatusSuccess;
vpcola 0:f1d3878b8dd9 159 }
vpcola 0:f1d3878b8dd9 160 }
vpcola 0:f1d3878b8dd9 161
vpcola 0:f1d3878b8dd9 162 TxStatus XBeeDM::send_data(const RemoteXBee& remote, uint8_t source_ep,
vpcola 0:f1d3878b8dd9 163 uint8_t dest_ep, uint16_t cluster_id, uint16_t profile_id,
vpcola 0:f1d3878b8dd9 164 const uint8_t *const data, uint16_t len, bool syncr)
vpcola 0:f1d3878b8dd9 165 {
vpcola 0:f1d3878b8dd9 166 if (!remote.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 167 return TxStatusInvalidAddr;
vpcola 0:f1d3878b8dd9 168 }
vpcola 0:f1d3878b8dd9 169
vpcola 0:f1d3878b8dd9 170 const uint64_t remote64 = remote.get_addr64();
vpcola 0:f1d3878b8dd9 171 const uint16_t remote16 = remote.get_addr16();
vpcola 0:f1d3878b8dd9 172
vpcola 0:f1d3878b8dd9 173 TxFrameDM frame = TxFrameDM(remote64, remote16, source_ep, dest_ep,
vpcola 0:f1d3878b8dd9 174 cluster_id, profile_id, BROADCAST_RADIUS_USE_NH,
vpcola 0:f1d3878b8dd9 175 _tx_options, data, len);
vpcola 0:f1d3878b8dd9 176 if (syncr) {
vpcola 0:f1d3878b8dd9 177 return send_data(&frame);
vpcola 0:f1d3878b8dd9 178 } else {
vpcola 0:f1d3878b8dd9 179 frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
vpcola 0:f1d3878b8dd9 180 send_api_frame(&frame);
vpcola 0:f1d3878b8dd9 181 return TxStatusSuccess;
vpcola 0:f1d3878b8dd9 182 }
vpcola 0:f1d3878b8dd9 183 }
vpcola 0:f1d3878b8dd9 184
vpcola 0:f1d3878b8dd9 185 TxStatus XBeeDM::send_data_to_coordinator(const uint8_t *const data, uint16_t len, bool syncr)
vpcola 0:f1d3878b8dd9 186 {
vpcola 0:f1d3878b8dd9 187 const uint64_t remaddr = ADDR64_COORDINATOR;
vpcola 0:f1d3878b8dd9 188
vpcola 0:f1d3878b8dd9 189 TxFrameDM frame = TxFrameDM(remaddr, ADDR16_UNKNOWN, BROADCAST_RADIUS_USE_NH, _tx_options, data, len);
vpcola 0:f1d3878b8dd9 190 if (syncr) {
vpcola 0:f1d3878b8dd9 191 return send_data(&frame);
vpcola 0:f1d3878b8dd9 192 } else {
vpcola 0:f1d3878b8dd9 193 frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
vpcola 0:f1d3878b8dd9 194 send_api_frame(&frame);
vpcola 0:f1d3878b8dd9 195 return TxStatusSuccess;
vpcola 0:f1d3878b8dd9 196 }
vpcola 0:f1d3878b8dd9 197 }
vpcola 0:f1d3878b8dd9 198
vpcola 0:f1d3878b8dd9 199 RemoteXBeeDM XBeeDM::get_remote_node_by_id(const char * const node_id)
vpcola 0:f1d3878b8dd9 200 {
vpcola 0:f1d3878b8dd9 201 uint64_t addr64;
vpcola 0:f1d3878b8dd9 202 uint16_t addr16;
vpcola 0:f1d3878b8dd9 203 _get_remote_node_by_id(node_id, &addr64, &addr16);
vpcola 0:f1d3878b8dd9 204 return RemoteXBeeDM(addr64);
vpcola 0:f1d3878b8dd9 205 }
vpcola 0:f1d3878b8dd9 206
vpcola 0:f1d3878b8dd9 207 void XBeeDM::register_node_discovery_cb(node_discovery_dm_cb_t function)
vpcola 0:f1d3878b8dd9 208 {
vpcola 0:f1d3878b8dd9 209 if (_nd_handler == NULL) {
vpcola 0:f1d3878b8dd9 210 _nd_handler = new FH_NodeDiscoveryDM();
vpcola 0:f1d3878b8dd9 211 register_frame_handler(_nd_handler);
vpcola 0:f1d3878b8dd9 212 }
vpcola 0:f1d3878b8dd9 213 _nd_handler->register_node_discovery_cb(function);
vpcola 0:f1d3878b8dd9 214 }
vpcola 0:f1d3878b8dd9 215
vpcola 0:f1d3878b8dd9 216 void XBeeDM::unregister_node_discovery_cb()
vpcola 0:f1d3878b8dd9 217 {
vpcola 0:f1d3878b8dd9 218 if (_nd_handler != NULL) {
vpcola 0:f1d3878b8dd9 219 _nd_handler->unregister_node_discovery_cb();
vpcola 0:f1d3878b8dd9 220 unregister_frame_handler(_nd_handler);
vpcola 0:f1d3878b8dd9 221 delete _nd_handler;
vpcola 0:f1d3878b8dd9 222 _nd_handler = NULL; /* as delete does not set to NULL */
vpcola 0:f1d3878b8dd9 223 }
vpcola 0:f1d3878b8dd9 224 }
vpcola 0:f1d3878b8dd9 225
vpcola 0:f1d3878b8dd9 226 void XBeeDM::register_receive_cb(receive_dm_cb_t function)
vpcola 0:f1d3878b8dd9 227 {
vpcola 0:f1d3878b8dd9 228 if (_rx_pkt_handler == NULL) {
vpcola 0:f1d3878b8dd9 229 _rx_pkt_handler = new FH_RxPacketDM();
vpcola 0:f1d3878b8dd9 230 register_frame_handler(_rx_pkt_handler);
vpcola 0:f1d3878b8dd9 231 }
vpcola 0:f1d3878b8dd9 232 _rx_pkt_handler->register_receive_cb(function);
vpcola 0:f1d3878b8dd9 233 }
vpcola 0:f1d3878b8dd9 234
vpcola 0:f1d3878b8dd9 235 void XBeeDM::unregister_receive_cb()
vpcola 0:f1d3878b8dd9 236 {
vpcola 0:f1d3878b8dd9 237 if (_rx_pkt_handler != NULL) {
vpcola 0:f1d3878b8dd9 238 _rx_pkt_handler->unregister_receive_cb();
vpcola 0:f1d3878b8dd9 239 unregister_frame_handler(_rx_pkt_handler);
vpcola 0:f1d3878b8dd9 240 delete _rx_pkt_handler;
vpcola 0:f1d3878b8dd9 241 _rx_pkt_handler = NULL; /* as delete does not set to NULL */
vpcola 0:f1d3878b8dd9 242 }
vpcola 0:f1d3878b8dd9 243 }
vpcola 0:f1d3878b8dd9 244
vpcola 0:f1d3878b8dd9 245 void XBeeDM::register_io_sample_cb(io_data_cb_dm_t function)
vpcola 0:f1d3878b8dd9 246 {
vpcola 0:f1d3878b8dd9 247 if (_io_data_handler == NULL) {
vpcola 0:f1d3878b8dd9 248 _io_data_handler = new FH_IoDataSampeDM();
vpcola 0:f1d3878b8dd9 249 register_frame_handler(_io_data_handler);
vpcola 0:f1d3878b8dd9 250 }
vpcola 0:f1d3878b8dd9 251 _io_data_handler->register_io_data_cb(function);
vpcola 0:f1d3878b8dd9 252 }
vpcola 0:f1d3878b8dd9 253
vpcola 0:f1d3878b8dd9 254 void XBeeDM::unregister_io_sample_cb()
vpcola 0:f1d3878b8dd9 255 {
vpcola 0:f1d3878b8dd9 256 if (_io_data_handler != NULL) {
vpcola 0:f1d3878b8dd9 257 _io_data_handler->unregister_io_data_cb();
vpcola 0:f1d3878b8dd9 258 unregister_frame_handler(_io_data_handler);
vpcola 0:f1d3878b8dd9 259 delete _io_data_handler;
vpcola 0:f1d3878b8dd9 260 _io_data_handler = NULL; /* as delete does not set to NULL */
vpcola 0:f1d3878b8dd9 261 }
vpcola 0:f1d3878b8dd9 262 }
vpcola 0:f1d3878b8dd9 263
vpcola 0:f1d3878b8dd9 264 AtCmdFrame::AtCmdResp XBeeDM::get_param(const RemoteXBee& remote, const char * const param, uint32_t * const data)
vpcola 0:f1d3878b8dd9 265 {
vpcola 0:f1d3878b8dd9 266 if (!remote.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 267 return AtCmdFrame::AtCmdRespInvalidAddr;
vpcola 0:f1d3878b8dd9 268 }
vpcola 0:f1d3878b8dd9 269
vpcola 0:f1d3878b8dd9 270 const uint64_t remote64 = remote.get_addr64();
vpcola 0:f1d3878b8dd9 271 const uint16_t remote16 = remote.get_addr16();
vpcola 0:f1d3878b8dd9 272 uint16_t len = sizeof *data;
vpcola 0:f1d3878b8dd9 273 AtCmdFrame::AtCmdResp atCmdResponse;
vpcola 0:f1d3878b8dd9 274
vpcola 0:f1d3878b8dd9 275 AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param);
vpcola 0:f1d3878b8dd9 276 atCmdResponse = send_at_cmd(&cmd_frame, (uint8_t *)data, &len, RadioRemote);
vpcola 0:f1d3878b8dd9 277
vpcola 0:f1d3878b8dd9 278 if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len > sizeof *data) {
vpcola 0:f1d3878b8dd9 279 atCmdResponse = AtCmdFrame::AtCmdRespLenMismatch;
vpcola 0:f1d3878b8dd9 280 }
vpcola 0:f1d3878b8dd9 281
vpcola 0:f1d3878b8dd9 282 return atCmdResponse;
vpcola 0:f1d3878b8dd9 283 }
vpcola 0:f1d3878b8dd9 284
vpcola 0:f1d3878b8dd9 285 AtCmdFrame::AtCmdResp XBeeDM::set_param(const RemoteXBee& remote, const char * const param, uint32_t data)
vpcola 0:f1d3878b8dd9 286 {
vpcola 0:f1d3878b8dd9 287 if (!remote.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 288 return AtCmdFrame::AtCmdRespInvalidAddr;
vpcola 0:f1d3878b8dd9 289 }
vpcola 0:f1d3878b8dd9 290
vpcola 0:f1d3878b8dd9 291 const uint64_t remote64 = remote.get_addr64();
vpcola 0:f1d3878b8dd9 292 const uint16_t remote16 = remote.get_addr16();
vpcola 0:f1d3878b8dd9 293
vpcola 0:f1d3878b8dd9 294 AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param, data);
vpcola 0:f1d3878b8dd9 295 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
vpcola 0:f1d3878b8dd9 296 }
vpcola 0:f1d3878b8dd9 297
vpcola 0:f1d3878b8dd9 298 AtCmdFrame::AtCmdResp XBeeDM::set_param(const RemoteXBee& remote, const char * const param, const uint8_t * data, uint16_t len)
vpcola 0:f1d3878b8dd9 299 {
vpcola 0:f1d3878b8dd9 300 if (!remote.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 301 return AtCmdFrame::AtCmdRespInvalidAddr;
vpcola 0:f1d3878b8dd9 302 }
vpcola 0:f1d3878b8dd9 303
vpcola 0:f1d3878b8dd9 304 const uint64_t remote64 = remote.get_addr64();
vpcola 0:f1d3878b8dd9 305 const uint16_t remote16 = remote.get_addr16();
vpcola 0:f1d3878b8dd9 306
vpcola 0:f1d3878b8dd9 307 AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param, data, len);
vpcola 0:f1d3878b8dd9 308 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
vpcola 0:f1d3878b8dd9 309 }
vpcola 0:f1d3878b8dd9 310
vpcola 0:f1d3878b8dd9 311 AtCmdFrame::AtCmdResp XBeeDM::get_param(const RemoteXBee& remote, const char * const param, uint8_t * const data, uint16_t * const len)
vpcola 0:f1d3878b8dd9 312 {
vpcola 0:f1d3878b8dd9 313
vpcola 0:f1d3878b8dd9 314 if (!remote.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 315 return AtCmdFrame::AtCmdRespInvalidAddr;
vpcola 0:f1d3878b8dd9 316 }
vpcola 0:f1d3878b8dd9 317
vpcola 0:f1d3878b8dd9 318 const uint64_t remote64 = remote.get_addr64();
vpcola 0:f1d3878b8dd9 319 const uint16_t remote16 = remote.get_addr16();
vpcola 0:f1d3878b8dd9 320
vpcola 0:f1d3878b8dd9 321 AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param);
vpcola 0:f1d3878b8dd9 322 return send_at_cmd(&cmd_frame, data, len, RadioRemote, false);
vpcola 0:f1d3878b8dd9 323 }
vpcola 0:f1d3878b8dd9 324
vpcola 0:f1d3878b8dd9 325 static void get_dio_cmd(XBeeDM::IoLine line, char * const iocmd)
vpcola 0:f1d3878b8dd9 326 {
vpcola 0:f1d3878b8dd9 327 if (line >= XBeeDM::DIO10_PWM0) {
vpcola 0:f1d3878b8dd9 328 iocmd[0] = 'P';
vpcola 0:f1d3878b8dd9 329 iocmd[1] = '0' + line - XBeeDM::DIO10_PWM0;
vpcola 0:f1d3878b8dd9 330 } else {
vpcola 0:f1d3878b8dd9 331 iocmd[0] = 'D';
vpcola 0:f1d3878b8dd9 332 iocmd[1] = '0' + line;
vpcola 0:f1d3878b8dd9 333 }
vpcola 0:f1d3878b8dd9 334 iocmd[2] = '\0';
vpcola 0:f1d3878b8dd9 335 }
vpcola 0:f1d3878b8dd9 336
vpcola 0:f1d3878b8dd9 337 RadioStatus XBeeDM::set_pin_config(const RemoteXBee& remote, IoLine line, IoMode mode)
vpcola 0:f1d3878b8dd9 338 {
vpcola 0:f1d3878b8dd9 339 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 340 char iocmd[3];
vpcola 0:f1d3878b8dd9 341
vpcola 0:f1d3878b8dd9 342 get_dio_cmd(line, iocmd);
vpcola 0:f1d3878b8dd9 343
vpcola 0:f1d3878b8dd9 344 cmdresp = set_param(remote, iocmd, (uint8_t)mode);
vpcola 0:f1d3878b8dd9 345 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 346 digi_log(LogLevelError, "set_pin_config: set_param returned %d\r\n", cmdresp);
vpcola 0:f1d3878b8dd9 347 return Failure;
vpcola 0:f1d3878b8dd9 348 }
vpcola 0:f1d3878b8dd9 349
vpcola 0:f1d3878b8dd9 350 return Success;
vpcola 0:f1d3878b8dd9 351 }
vpcola 0:f1d3878b8dd9 352
vpcola 0:f1d3878b8dd9 353 RadioStatus XBeeDM::get_pin_config(const RemoteXBee& remote, IoLine line, IoMode * const mode)
vpcola 0:f1d3878b8dd9 354 {
vpcola 0:f1d3878b8dd9 355 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 356 char iocmd[3];
vpcola 0:f1d3878b8dd9 357
vpcola 0:f1d3878b8dd9 358 get_dio_cmd(line, iocmd);
vpcola 0:f1d3878b8dd9 359
vpcola 0:f1d3878b8dd9 360 uint32_t var32;
vpcola 0:f1d3878b8dd9 361 cmdresp = get_param(remote, iocmd, &var32);
vpcola 0:f1d3878b8dd9 362 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 363 return Failure;
vpcola 0:f1d3878b8dd9 364 }
vpcola 0:f1d3878b8dd9 365 *mode = (IoMode)var32;
vpcola 0:f1d3878b8dd9 366
vpcola 0:f1d3878b8dd9 367 return Success;
vpcola 0:f1d3878b8dd9 368 }
vpcola 0:f1d3878b8dd9 369
vpcola 0:f1d3878b8dd9 370 RadioStatus XBeeDM::set_dio(const RemoteXBee& remote, IoLine line, DioVal val)
vpcola 0:f1d3878b8dd9 371 {
vpcola 0:f1d3878b8dd9 372 return set_pin_config(remote, line, val == Low ? DigitalOutLow : DigitalOutHigh);
vpcola 0:f1d3878b8dd9 373 }
vpcola 0:f1d3878b8dd9 374
vpcola 0:f1d3878b8dd9 375 RadioStatus XBeeDM::get_dio(const RemoteXBee& remote, IoLine line, DioVal * const val)
vpcola 0:f1d3878b8dd9 376 {
vpcola 0:f1d3878b8dd9 377 return get_iosample(remote).get_dio(line, val);
vpcola 0:f1d3878b8dd9 378 }
vpcola 0:f1d3878b8dd9 379
vpcola 0:f1d3878b8dd9 380 RadioStatus XBeeDM::get_adc(const RemoteXBee& remote, IoLine line, uint16_t * const val)
vpcola 0:f1d3878b8dd9 381 {
vpcola 0:f1d3878b8dd9 382 return get_iosample(remote).get_adc(line, val);
vpcola 0:f1d3878b8dd9 383 }
vpcola 0:f1d3878b8dd9 384
vpcola 0:f1d3878b8dd9 385 RadioStatus XBeeDM::set_pwm(const RemoteXBee& remote, IoLine line, float duty_cycle)
vpcola 0:f1d3878b8dd9 386 {
vpcola 0:f1d3878b8dd9 387 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 388 char iocmd[3] = { 'M', '0', '\0' };
vpcola 0:f1d3878b8dd9 389
vpcola 0:f1d3878b8dd9 390 if (line != DIO10_PWM0 && line != DIO11_PWM1) {
vpcola 0:f1d3878b8dd9 391 return Failure;
vpcola 0:f1d3878b8dd9 392 }
vpcola 0:f1d3878b8dd9 393 if (line == DIO11_PWM1) {
vpcola 0:f1d3878b8dd9 394 iocmd[1] = '1';
vpcola 0:f1d3878b8dd9 395 }
vpcola 0:f1d3878b8dd9 396
vpcola 0:f1d3878b8dd9 397 uint16_t pwm_val = (uint16_t)(duty_cycle * DR_PWM_MAX_VAL / 100);
vpcola 0:f1d3878b8dd9 398
vpcola 0:f1d3878b8dd9 399 cmdresp = set_param(remote, iocmd, pwm_val);
vpcola 0:f1d3878b8dd9 400 return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
vpcola 0:f1d3878b8dd9 401 }
vpcola 0:f1d3878b8dd9 402
vpcola 0:f1d3878b8dd9 403 IOSampleDM XBeeDM::get_iosample(const RemoteXBee& remote)
vpcola 0:f1d3878b8dd9 404 {
vpcola 0:f1d3878b8dd9 405 uint8_t io_sample[MAX_IO_SAMPLE_DM_LEN];
vpcola 0:f1d3878b8dd9 406 uint16_t len = sizeof io_sample;
vpcola 0:f1d3878b8dd9 407
vpcola 0:f1d3878b8dd9 408 RadioStatus resp = _get_iosample(remote, io_sample, &len);
vpcola 0:f1d3878b8dd9 409 if (resp != Success) {
vpcola 0:f1d3878b8dd9 410 digi_log(LogLevelError, "XBeeDM::get_iosample failed to get an IOSample\r\n");
vpcola 0:f1d3878b8dd9 411 len = 0;
vpcola 0:f1d3878b8dd9 412 }
vpcola 0:f1d3878b8dd9 413
vpcola 0:f1d3878b8dd9 414 return IOSampleDM(io_sample, len);
vpcola 0:f1d3878b8dd9 415 }
vpcola 0:f1d3878b8dd9 416
vpcola 0:f1d3878b8dd9 417 static uint16_t get_dio_pr_mask(XBeeDM::IoLine line)
vpcola 0:f1d3878b8dd9 418 {
vpcola 0:f1d3878b8dd9 419 switch (line) {
vpcola 0:f1d3878b8dd9 420 case XBeeDM::DIO4:
vpcola 0:f1d3878b8dd9 421 return (1 << 0);
vpcola 0:f1d3878b8dd9 422 case XBeeDM::DIO3_AD3:
vpcola 0:f1d3878b8dd9 423 return (1 << 1);
vpcola 0:f1d3878b8dd9 424 case XBeeDM::DIO2_AD2:
vpcola 0:f1d3878b8dd9 425 return (1 << 2);
vpcola 0:f1d3878b8dd9 426 case XBeeDM::DIO1_AD1:
vpcola 0:f1d3878b8dd9 427 return (1 << 3);
vpcola 0:f1d3878b8dd9 428 case XBeeDM::DIO0_AD0:
vpcola 0:f1d3878b8dd9 429 return (1 << 4);
vpcola 0:f1d3878b8dd9 430 case XBeeDM::DIO6:
vpcola 0:f1d3878b8dd9 431 return (1 << 5);
vpcola 0:f1d3878b8dd9 432 case XBeeDM::DIO8:
vpcola 0:f1d3878b8dd9 433 return (1 << 6);
vpcola 0:f1d3878b8dd9 434 case XBeeDM::DIO5:
vpcola 0:f1d3878b8dd9 435 return (1 << 8);
vpcola 0:f1d3878b8dd9 436 case XBeeDM::DIO9:
vpcola 0:f1d3878b8dd9 437 return (1 << 9);
vpcola 0:f1d3878b8dd9 438 case XBeeDM::DIO12:
vpcola 0:f1d3878b8dd9 439 return (1 << 10);
vpcola 0:f1d3878b8dd9 440 case XBeeDM::DIO10_PWM0:
vpcola 0:f1d3878b8dd9 441 return (1 << 11);
vpcola 0:f1d3878b8dd9 442 case XBeeDM::DIO11_PWM1:
vpcola 0:f1d3878b8dd9 443 return (1 << 12);
vpcola 0:f1d3878b8dd9 444 case XBeeDM::DIO7:
vpcola 0:f1d3878b8dd9 445 return (1 << 13);
vpcola 0:f1d3878b8dd9 446 default:
vpcola 0:f1d3878b8dd9 447 return 0;
vpcola 0:f1d3878b8dd9 448 }
vpcola 0:f1d3878b8dd9 449 }
vpcola 0:f1d3878b8dd9 450
vpcola 0:f1d3878b8dd9 451 RadioStatus XBeeDM::set_pin_pull_up(const RemoteXBee& remote, IoLine line, bool enable)
vpcola 0:f1d3878b8dd9 452 {
vpcola 0:f1d3878b8dd9 453 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 454 uint32_t var32;
vpcola 0:f1d3878b8dd9 455 uint16_t pr;
vpcola 0:f1d3878b8dd9 456
vpcola 0:f1d3878b8dd9 457 cmdresp = get_param(remote, "PR", &var32);
vpcola 0:f1d3878b8dd9 458 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 459 return Failure;
vpcola 0:f1d3878b8dd9 460 }
vpcola 0:f1d3878b8dd9 461 pr = var32;
vpcola 0:f1d3878b8dd9 462
vpcola 0:f1d3878b8dd9 463 const uint16_t dio_mask = get_dio_pr_mask(line);
vpcola 0:f1d3878b8dd9 464 if (dio_mask == 0) {
vpcola 0:f1d3878b8dd9 465 digi_log(LogLevelError, "XBeeDM::set_pin_pull_up: invalid pin %d\r\n", line);
vpcola 0:f1d3878b8dd9 466 return Failure;
vpcola 0:f1d3878b8dd9 467 }
vpcola 0:f1d3878b8dd9 468
vpcola 0:f1d3878b8dd9 469 if (enable) {
vpcola 0:f1d3878b8dd9 470 pr |= dio_mask;
vpcola 0:f1d3878b8dd9 471 } else {
vpcola 0:f1d3878b8dd9 472 pr &= ~dio_mask;
vpcola 0:f1d3878b8dd9 473 }
vpcola 0:f1d3878b8dd9 474
vpcola 0:f1d3878b8dd9 475 cmdresp = set_param(remote, "PR", pr);
vpcola 0:f1d3878b8dd9 476 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 477 return Failure;
vpcola 0:f1d3878b8dd9 478 }
vpcola 0:f1d3878b8dd9 479
vpcola 0:f1d3878b8dd9 480 return Success;
vpcola 0:f1d3878b8dd9 481 }
vpcola 0:f1d3878b8dd9 482
vpcola 0:f1d3878b8dd9 483 static uint16_t get_dio_ic_mask(XBeeDM::IoLine line)
vpcola 0:f1d3878b8dd9 484 {
vpcola 0:f1d3878b8dd9 485 if (line <= XBeeDM::DIO12) {
vpcola 0:f1d3878b8dd9 486 return (1 << line);
vpcola 0:f1d3878b8dd9 487 }
vpcola 0:f1d3878b8dd9 488 return 0;
vpcola 0:f1d3878b8dd9 489 }
vpcola 0:f1d3878b8dd9 490
vpcola 0:f1d3878b8dd9 491 RadioStatus XBeeDM::enable_dio_change_detection(const RemoteXBee& remote, IoLine line, bool enable)
vpcola 0:f1d3878b8dd9 492 {
vpcola 0:f1d3878b8dd9 493 if (line > DIO12) {
vpcola 0:f1d3878b8dd9 494 digi_log(LogLevelError, "XBeeDM::enable_dio_change_detection: pin not supported (%d)\r\n", line);
vpcola 0:f1d3878b8dd9 495 return Failure;
vpcola 0:f1d3878b8dd9 496 }
vpcola 0:f1d3878b8dd9 497
vpcola 0:f1d3878b8dd9 498 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 499 uint32_t var32;
vpcola 0:f1d3878b8dd9 500 uint16_t ic;
vpcola 0:f1d3878b8dd9 501
vpcola 0:f1d3878b8dd9 502 cmdresp = get_param(remote, "IC", &var32);
vpcola 0:f1d3878b8dd9 503 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 504 return Failure;
vpcola 0:f1d3878b8dd9 505 }
vpcola 0:f1d3878b8dd9 506 ic = var32;
vpcola 0:f1d3878b8dd9 507
vpcola 0:f1d3878b8dd9 508 const uint16_t dio_mask = get_dio_ic_mask(line);
vpcola 0:f1d3878b8dd9 509 if (dio_mask == 0) {
vpcola 0:f1d3878b8dd9 510 digi_log(LogLevelError, "XBeeDM::enable_dio_change_detection: invalid pin %d\r\n", line);
vpcola 0:f1d3878b8dd9 511 return Failure;
vpcola 0:f1d3878b8dd9 512 }
vpcola 0:f1d3878b8dd9 513
vpcola 0:f1d3878b8dd9 514 if (enable) {
vpcola 0:f1d3878b8dd9 515 ic |= dio_mask;
vpcola 0:f1d3878b8dd9 516 } else {
vpcola 0:f1d3878b8dd9 517 ic &= ~dio_mask;
vpcola 0:f1d3878b8dd9 518 }
vpcola 0:f1d3878b8dd9 519
vpcola 0:f1d3878b8dd9 520 cmdresp = set_param(remote, "IC", ic);
vpcola 0:f1d3878b8dd9 521 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 522 return Failure;
vpcola 0:f1d3878b8dd9 523 }
vpcola 0:f1d3878b8dd9 524
vpcola 0:f1d3878b8dd9 525 return Success;
vpcola 0:f1d3878b8dd9 526 }
vpcola 0:f1d3878b8dd9 527
vpcola 0:f1d3878b8dd9 528 RadioStatus XBeeDM::config_poll_destination(const RemoteXBee& destination)
vpcola 0:f1d3878b8dd9 529 {
vpcola 0:f1d3878b8dd9 530 uint32_t dh;
vpcola 0:f1d3878b8dd9 531 uint32_t dl;
vpcola 0:f1d3878b8dd9 532
vpcola 0:f1d3878b8dd9 533 if (destination.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 534 const uint64_t dest64 = destination.get_addr64();
vpcola 0:f1d3878b8dd9 535 dh = (uint32_t)((dest64 >> 32) & 0xFFFFFFFF);
vpcola 0:f1d3878b8dd9 536 dl = (uint32_t)((dest64 & 0xFFFFFFFF));
vpcola 0:f1d3878b8dd9 537 } else {
vpcola 0:f1d3878b8dd9 538 digi_log(LogLevelError, "config_poll_destination: Invalid destination");
vpcola 0:f1d3878b8dd9 539 return Failure;
vpcola 0:f1d3878b8dd9 540 }
vpcola 0:f1d3878b8dd9 541
vpcola 0:f1d3878b8dd9 542 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 543
vpcola 0:f1d3878b8dd9 544 cmdresp = set_param("DH", dh);
vpcola 0:f1d3878b8dd9 545 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 546 digi_log(LogLevelError, "config_poll_destination: error %d:\r\n", cmdresp);
vpcola 0:f1d3878b8dd9 547 return Failure;
vpcola 0:f1d3878b8dd9 548 }
vpcola 0:f1d3878b8dd9 549
vpcola 0:f1d3878b8dd9 550 cmdresp = set_param("DL", dl);
vpcola 0:f1d3878b8dd9 551 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 552 digi_log(LogLevelError, "config_poll_destination: error %d:\r\n", cmdresp);
vpcola 0:f1d3878b8dd9 553 return Failure;
vpcola 0:f1d3878b8dd9 554 }
vpcola 0:f1d3878b8dd9 555
vpcola 0:f1d3878b8dd9 556 return Success;
vpcola 0:f1d3878b8dd9 557 }