Fork of my original MQTTGateway

Dependencies:   mbed-http

Committer:
vpcola
Date:
Sat Apr 08 14:43:14 2017 +0000
Revision:
0:a1734fe1ec4b
Initial commit

Who changed what in which revision?

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