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 #include "XBee802.h"
vpcola 0:f1d3878b8dd9 13 #include "IO/IOSample802.h"
vpcola 0:f1d3878b8dd9 14 #include "Frames/802_Frames.h"
vpcola 0:f1d3878b8dd9 15 #include "FrameHandlers/FH_ModemStatus.h"
vpcola 0:f1d3878b8dd9 16
vpcola 0:f1d3878b8dd9 17 using namespace XBeeLib;
vpcola 0:f1d3878b8dd9 18
vpcola 0:f1d3878b8dd9 19 /* Class constructor */
vpcola 0:f1d3878b8dd9 20 XBee802::XBee802(PinName tx, PinName rx, PinName reset, PinName rts, PinName cts, int baud) :
vpcola 0:f1d3878b8dd9 21 XBee(tx, rx, reset, rts, cts, baud),
vpcola 0:f1d3878b8dd9 22 _nd_handler(NULL), _rx_64b_handler(NULL), _rx_16b_handler(NULL),
vpcola 0:f1d3878b8dd9 23 _io_data_64b_handler(NULL), _io_data_16b_handler(NULL)
vpcola 0:f1d3878b8dd9 24 {
vpcola 0:f1d3878b8dd9 25
vpcola 0:f1d3878b8dd9 26 }
vpcola 0:f1d3878b8dd9 27
vpcola 0:f1d3878b8dd9 28 /* Class destructor */
vpcola 0:f1d3878b8dd9 29 XBee802::~XBee802()
vpcola 0:f1d3878b8dd9 30 {
vpcola 0:f1d3878b8dd9 31 unregister_node_discovery_cb();
vpcola 0:f1d3878b8dd9 32 unregister_receive_cb();
vpcola 0:f1d3878b8dd9 33 unregister_io_sample_cb();
vpcola 0:f1d3878b8dd9 34 }
vpcola 0:f1d3878b8dd9 35
vpcola 0:f1d3878b8dd9 36 RadioStatus XBee802::init()
vpcola 0:f1d3878b8dd9 37 {
vpcola 0:f1d3878b8dd9 38 RadioStatus retval = XBee::init();
vpcola 0:f1d3878b8dd9 39 uint16_t addr16;
vpcola 0:f1d3878b8dd9 40 RadioStatus error = get_network_address(&addr16);
vpcola 0:f1d3878b8dd9 41 if (error == Success) {
vpcola 0:f1d3878b8dd9 42 digi_log(LogLevelInfo, "ADDR16: %04x\r\n", addr16);
vpcola 0:f1d3878b8dd9 43 } else {
vpcola 0:f1d3878b8dd9 44 digi_log(LogLevelInfo, "ADDR16: UNKNOWN\r\n");
vpcola 0:f1d3878b8dd9 45 }
vpcola 0:f1d3878b8dd9 46
vpcola 0:f1d3878b8dd9 47 const RadioProtocol radioProtocol = get_radio_protocol();
vpcola 0:f1d3878b8dd9 48 if (radioProtocol != Raw_802_15_4) {
vpcola 0:f1d3878b8dd9 49 digi_log(LogLevelError, "Radio protocol does not match, needed a %d got a %d\r\n", Raw_802_15_4, radioProtocol);
vpcola 0:f1d3878b8dd9 50 retval = Failure;
vpcola 0:f1d3878b8dd9 51 }
vpcola 0:f1d3878b8dd9 52 assert(radioProtocol == Raw_802_15_4);
vpcola 0:f1d3878b8dd9 53
vpcola 0:f1d3878b8dd9 54 return retval;
vpcola 0:f1d3878b8dd9 55 }
vpcola 0:f1d3878b8dd9 56
vpcola 0:f1d3878b8dd9 57 RadioStatus XBee802::set_channel(uint8_t channel)
vpcola 0:f1d3878b8dd9 58 {
vpcola 0:f1d3878b8dd9 59 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 60
vpcola 0:f1d3878b8dd9 61 /* Pro and Non-Pro modules have different channels available. The at
vpcola 0:f1d3878b8dd9 62 command will return an error if the selected channel is not available */
vpcola 0:f1d3878b8dd9 63 cmdresp = set_param("CH", channel);
vpcola 0:f1d3878b8dd9 64 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 65 return Failure;
vpcola 0:f1d3878b8dd9 66 }
vpcola 0:f1d3878b8dd9 67 return Success;
vpcola 0:f1d3878b8dd9 68 }
vpcola 0:f1d3878b8dd9 69
vpcola 0:f1d3878b8dd9 70 RadioStatus XBee802::get_channel(uint8_t * const channel)
vpcola 0:f1d3878b8dd9 71 {
vpcola 0:f1d3878b8dd9 72 if (channel == NULL) {
vpcola 0:f1d3878b8dd9 73 return Failure;
vpcola 0:f1d3878b8dd9 74 }
vpcola 0:f1d3878b8dd9 75 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 76
vpcola 0:f1d3878b8dd9 77 uint32_t var32;
vpcola 0:f1d3878b8dd9 78 cmdresp = get_param("CH", &var32);
vpcola 0:f1d3878b8dd9 79 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 80 return Failure;
vpcola 0:f1d3878b8dd9 81 }
vpcola 0:f1d3878b8dd9 82 *channel = var32;
vpcola 0:f1d3878b8dd9 83 return Success;
vpcola 0:f1d3878b8dd9 84 }
vpcola 0:f1d3878b8dd9 85
vpcola 0:f1d3878b8dd9 86 RadioStatus XBee802::set_panid(uint16_t panid)
vpcola 0:f1d3878b8dd9 87 {
vpcola 0:f1d3878b8dd9 88 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 89
vpcola 0:f1d3878b8dd9 90 cmdresp = set_param("ID", panid);
vpcola 0:f1d3878b8dd9 91 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 92 return Failure;
vpcola 0:f1d3878b8dd9 93 }
vpcola 0:f1d3878b8dd9 94 return Success;
vpcola 0:f1d3878b8dd9 95 }
vpcola 0:f1d3878b8dd9 96
vpcola 0:f1d3878b8dd9 97 RadioStatus XBee802::get_panid(uint16_t * const panid)
vpcola 0:f1d3878b8dd9 98 {
vpcola 0:f1d3878b8dd9 99 if (panid == NULL) {
vpcola 0:f1d3878b8dd9 100 return Failure;
vpcola 0:f1d3878b8dd9 101 }
vpcola 0:f1d3878b8dd9 102 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 103
vpcola 0:f1d3878b8dd9 104 uint32_t var32;
vpcola 0:f1d3878b8dd9 105 cmdresp = get_param("ID", &var32);
vpcola 0:f1d3878b8dd9 106 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 107 return Failure;
vpcola 0:f1d3878b8dd9 108 }
vpcola 0:f1d3878b8dd9 109 *panid = var32;
vpcola 0:f1d3878b8dd9 110 return Success;
vpcola 0:f1d3878b8dd9 111 }
vpcola 0:f1d3878b8dd9 112
vpcola 0:f1d3878b8dd9 113 RadioStatus XBee802::get_network_address(uint16_t * const addr16)
vpcola 0:f1d3878b8dd9 114 {
vpcola 0:f1d3878b8dd9 115 if (addr16 == NULL) {
vpcola 0:f1d3878b8dd9 116 return Failure;
vpcola 0:f1d3878b8dd9 117 }
vpcola 0:f1d3878b8dd9 118 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 119
vpcola 0:f1d3878b8dd9 120 uint32_t var32;
vpcola 0:f1d3878b8dd9 121 cmdresp = get_param("MY", &var32);
vpcola 0:f1d3878b8dd9 122 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 123 return Failure;
vpcola 0:f1d3878b8dd9 124 }
vpcola 0:f1d3878b8dd9 125 *addr16 = var32;
vpcola 0:f1d3878b8dd9 126 return Success;
vpcola 0:f1d3878b8dd9 127 }
vpcola 0:f1d3878b8dd9 128
vpcola 0:f1d3878b8dd9 129 RadioStatus XBee802::set_network_address(uint16_t addr16)
vpcola 0:f1d3878b8dd9 130 {
vpcola 0:f1d3878b8dd9 131 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 132
vpcola 0:f1d3878b8dd9 133 cmdresp = set_param("MY", addr16);
vpcola 0:f1d3878b8dd9 134 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 135 return Failure;
vpcola 0:f1d3878b8dd9 136 }
vpcola 0:f1d3878b8dd9 137 return Success;
vpcola 0:f1d3878b8dd9 138 }
vpcola 0:f1d3878b8dd9 139
vpcola 0:f1d3878b8dd9 140 RadioStatus XBee802::get_node_discovery_timeout(uint16_t * const timeout_ms)
vpcola 0:f1d3878b8dd9 141 {
vpcola 0:f1d3878b8dd9 142 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 143 uint32_t var32;
vpcola 0:f1d3878b8dd9 144
vpcola 0:f1d3878b8dd9 145 cmdresp = get_param("NT", &var32);
vpcola 0:f1d3878b8dd9 146 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 147 return Failure;
vpcola 0:f1d3878b8dd9 148 }
vpcola 0:f1d3878b8dd9 149 *timeout_ms = (uint16_t)var32;
vpcola 0:f1d3878b8dd9 150
vpcola 0:f1d3878b8dd9 151 /* No N? command available for this protocol. Add a fix 1s guard time */
vpcola 0:f1d3878b8dd9 152 *timeout_ms += 1000;
vpcola 0:f1d3878b8dd9 153
vpcola 0:f1d3878b8dd9 154 return Success;
vpcola 0:f1d3878b8dd9 155 }
vpcola 0:f1d3878b8dd9 156
vpcola 0:f1d3878b8dd9 157 RadioStatus XBee802::get_node_discovery_timeout(uint16_t * const timeout_ms, bool * const wait_for_complete_timeout)
vpcola 0:f1d3878b8dd9 158 {
vpcola 0:f1d3878b8dd9 159 const RadioStatus status = get_node_discovery_timeout(timeout_ms);
vpcola 0:f1d3878b8dd9 160
vpcola 0:f1d3878b8dd9 161 /* This protocol requires to wait for the complete timeout before attempting
vpcola 0:f1d3878b8dd9 162 to execute other commands */
vpcola 0:f1d3878b8dd9 163 *wait_for_complete_timeout = true;
vpcola 0:f1d3878b8dd9 164
vpcola 0:f1d3878b8dd9 165 return status;
vpcola 0:f1d3878b8dd9 166 }
vpcola 0:f1d3878b8dd9 167
vpcola 0:f1d3878b8dd9 168 void XBee802::radio_status_update(AtCmdFrame::ModemStatus modem_status)
vpcola 0:f1d3878b8dd9 169 {
vpcola 0:f1d3878b8dd9 170 /* Update the radio status variables */
vpcola 0:f1d3878b8dd9 171 if (modem_status == AtCmdFrame::HwReset) {
vpcola 0:f1d3878b8dd9 172 _hw_reset_cnt++;
vpcola 0:f1d3878b8dd9 173 } else if (modem_status == AtCmdFrame::WdReset) {
vpcola 0:f1d3878b8dd9 174 _wd_reset_cnt++;
vpcola 0:f1d3878b8dd9 175 }
vpcola 0:f1d3878b8dd9 176
vpcola 0:f1d3878b8dd9 177 _modem_status = modem_status;
vpcola 0:f1d3878b8dd9 178
vpcola 0:f1d3878b8dd9 179 digi_log(LogLevelDebug, "\r\nUpdating radio status: %02x\r\n", modem_status);
vpcola 0:f1d3878b8dd9 180 }
vpcola 0:f1d3878b8dd9 181
vpcola 0:f1d3878b8dd9 182 TxStatus XBee802::send_data(const RemoteXBee& remote, const uint8_t *const data, uint16_t len, bool syncr)
vpcola 0:f1d3878b8dd9 183 {
vpcola 0:f1d3878b8dd9 184 if (remote.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 185 const uint64_t remote64 = remote.get_addr64();
vpcola 0:f1d3878b8dd9 186
vpcola 0:f1d3878b8dd9 187 digi_log(LogLevelDebug, "send_data ADDR64: %08x:%08x\r\n", UINT64_HI32(remote64), UINT64_LO32(remote64));
vpcola 0:f1d3878b8dd9 188
vpcola 0:f1d3878b8dd9 189 TxFrame802 frame = TxFrame802(remote64, _tx_options, data, len);
vpcola 0:f1d3878b8dd9 190
vpcola 0:f1d3878b8dd9 191 if (syncr) {
vpcola 0:f1d3878b8dd9 192 return send_data(&frame);
vpcola 0:f1d3878b8dd9 193 } else {
vpcola 0:f1d3878b8dd9 194 frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
vpcola 0:f1d3878b8dd9 195 send_api_frame(&frame);
vpcola 0:f1d3878b8dd9 196 return TxStatusSuccess;
vpcola 0:f1d3878b8dd9 197 }
vpcola 0:f1d3878b8dd9 198 }
vpcola 0:f1d3878b8dd9 199
vpcola 0:f1d3878b8dd9 200 if (remote.is_valid_addr16b()) {
vpcola 0:f1d3878b8dd9 201 const uint16_t remote16 = remote.get_addr16();
vpcola 0:f1d3878b8dd9 202
vpcola 0:f1d3878b8dd9 203 digi_log(LogLevelDebug, "send_data ADDR16: %04x\r\n", remote16);
vpcola 0:f1d3878b8dd9 204
vpcola 0:f1d3878b8dd9 205 TxFrame802 frame = TxFrame802(remote16, _tx_options, data, len);
vpcola 0:f1d3878b8dd9 206
vpcola 0:f1d3878b8dd9 207 if (syncr) {
vpcola 0:f1d3878b8dd9 208 return send_data(&frame);
vpcola 0:f1d3878b8dd9 209 } else {
vpcola 0:f1d3878b8dd9 210 frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
vpcola 0:f1d3878b8dd9 211 send_api_frame(&frame);
vpcola 0:f1d3878b8dd9 212 return TxStatusSuccess;
vpcola 0:f1d3878b8dd9 213 }
vpcola 0:f1d3878b8dd9 214 }
vpcola 0:f1d3878b8dd9 215
vpcola 0:f1d3878b8dd9 216 return TxStatusInvalidAddr;
vpcola 0:f1d3878b8dd9 217 }
vpcola 0:f1d3878b8dd9 218
vpcola 0:f1d3878b8dd9 219 XBee802::AssocStatus XBee802::get_assoc_status(void)
vpcola 0:f1d3878b8dd9 220 {
vpcola 0:f1d3878b8dd9 221 return (AssocStatus)get_AI();
vpcola 0:f1d3878b8dd9 222 }
vpcola 0:f1d3878b8dd9 223
vpcola 0:f1d3878b8dd9 224 RemoteXBee802 XBee802::get_remote_node_by_id(const char * const node_id)
vpcola 0:f1d3878b8dd9 225 {
vpcola 0:f1d3878b8dd9 226 uint64_t addr64;
vpcola 0:f1d3878b8dd9 227 uint16_t addr16;
vpcola 0:f1d3878b8dd9 228
vpcola 0:f1d3878b8dd9 229 _get_remote_node_by_id(node_id, &addr64, &addr16);
vpcola 0:f1d3878b8dd9 230 return RemoteXBee802(addr64, addr16);
vpcola 0:f1d3878b8dd9 231 }
vpcola 0:f1d3878b8dd9 232
vpcola 0:f1d3878b8dd9 233 void XBee802::register_node_discovery_cb(node_discovery_802_cb_t function)
vpcola 0:f1d3878b8dd9 234 {
vpcola 0:f1d3878b8dd9 235 if (_nd_handler == NULL) {
vpcola 0:f1d3878b8dd9 236 _nd_handler = new FH_NodeDiscovery802();
vpcola 0:f1d3878b8dd9 237 register_frame_handler(_nd_handler);
vpcola 0:f1d3878b8dd9 238 }
vpcola 0:f1d3878b8dd9 239 _nd_handler->register_node_discovery_cb(function);
vpcola 0:f1d3878b8dd9 240 }
vpcola 0:f1d3878b8dd9 241
vpcola 0:f1d3878b8dd9 242 void XBee802::unregister_node_discovery_cb()
vpcola 0:f1d3878b8dd9 243 {
vpcola 0:f1d3878b8dd9 244 if (_nd_handler != NULL) {
vpcola 0:f1d3878b8dd9 245 _nd_handler->unregister_node_discovery_cb();
vpcola 0:f1d3878b8dd9 246 unregister_frame_handler(_nd_handler);
vpcola 0:f1d3878b8dd9 247 delete _nd_handler;
vpcola 0:f1d3878b8dd9 248 _nd_handler = NULL; /* as delete does not set to NULL */
vpcola 0:f1d3878b8dd9 249 }
vpcola 0:f1d3878b8dd9 250 }
vpcola 0:f1d3878b8dd9 251
vpcola 0:f1d3878b8dd9 252 void XBee802::register_receive_cb(receive_802_cb_t function)
vpcola 0:f1d3878b8dd9 253 {
vpcola 0:f1d3878b8dd9 254 if (_rx_64b_handler == NULL) {
vpcola 0:f1d3878b8dd9 255 _rx_64b_handler = new FH_RxPacket64b802();
vpcola 0:f1d3878b8dd9 256 register_frame_handler(_rx_64b_handler);
vpcola 0:f1d3878b8dd9 257 }
vpcola 0:f1d3878b8dd9 258 _rx_64b_handler->register_receive_cb(function);
vpcola 0:f1d3878b8dd9 259
vpcola 0:f1d3878b8dd9 260 if (_rx_16b_handler == NULL) {
vpcola 0:f1d3878b8dd9 261 _rx_16b_handler = new FH_RxPacket16b802();
vpcola 0:f1d3878b8dd9 262 register_frame_handler(_rx_16b_handler);
vpcola 0:f1d3878b8dd9 263 }
vpcola 0:f1d3878b8dd9 264 _rx_16b_handler->register_receive_cb(function);
vpcola 0:f1d3878b8dd9 265 }
vpcola 0:f1d3878b8dd9 266
vpcola 0:f1d3878b8dd9 267 void XBee802::unregister_receive_cb()
vpcola 0:f1d3878b8dd9 268 {
vpcola 0:f1d3878b8dd9 269 if (_rx_64b_handler != NULL) {
vpcola 0:f1d3878b8dd9 270 _rx_64b_handler->unregister_receive_cb();
vpcola 0:f1d3878b8dd9 271 unregister_frame_handler(_rx_64b_handler);
vpcola 0:f1d3878b8dd9 272 delete _rx_64b_handler;
vpcola 0:f1d3878b8dd9 273 _rx_64b_handler = NULL; /* as delete does not set to NULL */
vpcola 0:f1d3878b8dd9 274 }
vpcola 0:f1d3878b8dd9 275
vpcola 0:f1d3878b8dd9 276 if (_rx_16b_handler != NULL) {
vpcola 0:f1d3878b8dd9 277 _rx_16b_handler->unregister_receive_cb();
vpcola 0:f1d3878b8dd9 278 unregister_frame_handler(_rx_16b_handler);
vpcola 0:f1d3878b8dd9 279 delete _rx_16b_handler;
vpcola 0:f1d3878b8dd9 280 _rx_16b_handler = NULL; /* as delete does not set to NULL */
vpcola 0:f1d3878b8dd9 281 }
vpcola 0:f1d3878b8dd9 282 }
vpcola 0:f1d3878b8dd9 283
vpcola 0:f1d3878b8dd9 284 void XBee802::register_io_sample_cb(io_data_cb_802_t function)
vpcola 0:f1d3878b8dd9 285 {
vpcola 0:f1d3878b8dd9 286 if (_io_data_64b_handler == NULL) {
vpcola 0:f1d3878b8dd9 287 _io_data_64b_handler = new FH_IoDataSampe64b802();
vpcola 0:f1d3878b8dd9 288 register_frame_handler(_io_data_64b_handler);
vpcola 0:f1d3878b8dd9 289 }
vpcola 0:f1d3878b8dd9 290 _io_data_64b_handler->register_io_data_cb(function);
vpcola 0:f1d3878b8dd9 291
vpcola 0:f1d3878b8dd9 292 if (_io_data_16b_handler == NULL) {
vpcola 0:f1d3878b8dd9 293 _io_data_16b_handler = new FH_IoDataSampe16b802();
vpcola 0:f1d3878b8dd9 294 register_frame_handler(_io_data_16b_handler);
vpcola 0:f1d3878b8dd9 295 }
vpcola 0:f1d3878b8dd9 296 _io_data_16b_handler->register_io_data_cb(function);
vpcola 0:f1d3878b8dd9 297 }
vpcola 0:f1d3878b8dd9 298
vpcola 0:f1d3878b8dd9 299 void XBee802::unregister_io_sample_cb()
vpcola 0:f1d3878b8dd9 300 {
vpcola 0:f1d3878b8dd9 301 if (_io_data_64b_handler != NULL) {
vpcola 0:f1d3878b8dd9 302 _io_data_64b_handler->unregister_io_data_cb();
vpcola 0:f1d3878b8dd9 303 unregister_frame_handler(_io_data_64b_handler);
vpcola 0:f1d3878b8dd9 304 delete _io_data_64b_handler;
vpcola 0:f1d3878b8dd9 305 _io_data_64b_handler = NULL; /* as delete does not set to NULL */
vpcola 0:f1d3878b8dd9 306 }
vpcola 0:f1d3878b8dd9 307
vpcola 0:f1d3878b8dd9 308 if (_io_data_16b_handler != NULL) {
vpcola 0:f1d3878b8dd9 309 _io_data_16b_handler->unregister_io_data_cb();
vpcola 0:f1d3878b8dd9 310 unregister_frame_handler(_io_data_16b_handler);
vpcola 0:f1d3878b8dd9 311 delete _io_data_16b_handler;
vpcola 0:f1d3878b8dd9 312 _io_data_16b_handler = NULL; /* as delete does not set to NULL */
vpcola 0:f1d3878b8dd9 313 }
vpcola 0:f1d3878b8dd9 314 }
vpcola 0:f1d3878b8dd9 315
vpcola 0:f1d3878b8dd9 316 AtCmdFrame::AtCmdResp XBee802::get_param(const RemoteXBee& remote, const char * const param, uint32_t * const data)
vpcola 0:f1d3878b8dd9 317 {
vpcola 0:f1d3878b8dd9 318 uint16_t len = sizeof *data;
vpcola 0:f1d3878b8dd9 319 AtCmdFrame::AtCmdResp atCmdResponse;
vpcola 0:f1d3878b8dd9 320
vpcola 0:f1d3878b8dd9 321 if (remote.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 322 const uint64_t dev_addr64 = remote.get_addr64();
vpcola 0:f1d3878b8dd9 323
vpcola 0:f1d3878b8dd9 324 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr64, param);
vpcola 0:f1d3878b8dd9 325 atCmdResponse = send_at_cmd(&cmd_frame, (uint8_t *)data, &len, RadioRemote);
vpcola 0:f1d3878b8dd9 326 } else if (remote.is_valid_addr16b()) {
vpcola 0:f1d3878b8dd9 327 const uint16_t dev_addr16 = remote.get_addr16();
vpcola 0:f1d3878b8dd9 328
vpcola 0:f1d3878b8dd9 329 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr16, param);
vpcola 0:f1d3878b8dd9 330 atCmdResponse = send_at_cmd(&cmd_frame, (uint8_t *)data, &len, RadioRemote);
vpcola 0:f1d3878b8dd9 331 } else {
vpcola 0:f1d3878b8dd9 332 return AtCmdFrame::AtCmdRespInvalidAddr;
vpcola 0:f1d3878b8dd9 333 }
vpcola 0:f1d3878b8dd9 334
vpcola 0:f1d3878b8dd9 335 if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len > sizeof *data) {
vpcola 0:f1d3878b8dd9 336 atCmdResponse = AtCmdFrame::AtCmdRespLenMismatch;
vpcola 0:f1d3878b8dd9 337 }
vpcola 0:f1d3878b8dd9 338
vpcola 0:f1d3878b8dd9 339 return atCmdResponse;
vpcola 0:f1d3878b8dd9 340 }
vpcola 0:f1d3878b8dd9 341
vpcola 0:f1d3878b8dd9 342 AtCmdFrame::AtCmdResp XBee802::set_param(const RemoteXBee& remote, const char * const param, uint32_t data)
vpcola 0:f1d3878b8dd9 343 {
vpcola 0:f1d3878b8dd9 344 if (remote.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 345 const uint64_t dev_addr64 = remote.get_addr64();
vpcola 0:f1d3878b8dd9 346
vpcola 0:f1d3878b8dd9 347 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr64, param, data);
vpcola 0:f1d3878b8dd9 348 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
vpcola 0:f1d3878b8dd9 349 }
vpcola 0:f1d3878b8dd9 350
vpcola 0:f1d3878b8dd9 351 if (remote.is_valid_addr16b()) {
vpcola 0:f1d3878b8dd9 352 const uint16_t dev_addr16 = remote.get_addr16();
vpcola 0:f1d3878b8dd9 353
vpcola 0:f1d3878b8dd9 354 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr16, param, data);
vpcola 0:f1d3878b8dd9 355 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
vpcola 0:f1d3878b8dd9 356 }
vpcola 0:f1d3878b8dd9 357
vpcola 0:f1d3878b8dd9 358 return AtCmdFrame::AtCmdRespInvalidAddr;
vpcola 0:f1d3878b8dd9 359 }
vpcola 0:f1d3878b8dd9 360
vpcola 0:f1d3878b8dd9 361 AtCmdFrame::AtCmdResp XBee802::set_param(const RemoteXBee& remote, const char * const param, const uint8_t * data, uint16_t len)
vpcola 0:f1d3878b8dd9 362 {
vpcola 0:f1d3878b8dd9 363 if (remote.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 364 const uint64_t dev_addr64 = remote.get_addr64();
vpcola 0:f1d3878b8dd9 365
vpcola 0:f1d3878b8dd9 366 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr64, param, data, len);
vpcola 0:f1d3878b8dd9 367 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
vpcola 0:f1d3878b8dd9 368 }
vpcola 0:f1d3878b8dd9 369
vpcola 0:f1d3878b8dd9 370 if (remote.is_valid_addr16b()) {
vpcola 0:f1d3878b8dd9 371 const uint16_t dev_addr16 = remote.get_addr16();
vpcola 0:f1d3878b8dd9 372
vpcola 0:f1d3878b8dd9 373 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr16, param, data, len);
vpcola 0:f1d3878b8dd9 374 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
vpcola 0:f1d3878b8dd9 375 }
vpcola 0:f1d3878b8dd9 376
vpcola 0:f1d3878b8dd9 377 return AtCmdFrame::AtCmdRespInvalidAddr;
vpcola 0:f1d3878b8dd9 378 }
vpcola 0:f1d3878b8dd9 379
vpcola 0:f1d3878b8dd9 380 AtCmdFrame::AtCmdResp XBee802::get_param(const RemoteXBee& remote, const char * const param, uint8_t * const data, uint16_t * const len)
vpcola 0:f1d3878b8dd9 381 {
vpcola 0:f1d3878b8dd9 382 if (remote.is_valid_addr64b()) {
vpcola 0:f1d3878b8dd9 383 uint64_t dev_addr64 = remote.get_addr64();
vpcola 0:f1d3878b8dd9 384
vpcola 0:f1d3878b8dd9 385 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr64, param);
vpcola 0:f1d3878b8dd9 386 return send_at_cmd(&cmd_frame, data, len, RadioRemote, false);
vpcola 0:f1d3878b8dd9 387 }
vpcola 0:f1d3878b8dd9 388
vpcola 0:f1d3878b8dd9 389 if (remote.is_valid_addr16b()) {
vpcola 0:f1d3878b8dd9 390 uint16_t dev_addr16 = remote.get_addr16();
vpcola 0:f1d3878b8dd9 391
vpcola 0:f1d3878b8dd9 392 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr16, param);
vpcola 0:f1d3878b8dd9 393 return send_at_cmd(&cmd_frame, data, len, RadioRemote, false);
vpcola 0:f1d3878b8dd9 394 }
vpcola 0:f1d3878b8dd9 395
vpcola 0:f1d3878b8dd9 396 return AtCmdFrame::AtCmdRespInvalidAddr;
vpcola 0:f1d3878b8dd9 397 }
vpcola 0:f1d3878b8dd9 398
vpcola 0:f1d3878b8dd9 399 static void get_dio_cmd(XBee802::IoLine line, char * const iocmd)
vpcola 0:f1d3878b8dd9 400 {
vpcola 0:f1d3878b8dd9 401 if (line >= XBee802::PWM0) {
vpcola 0:f1d3878b8dd9 402 iocmd[0] = 'P';
vpcola 0:f1d3878b8dd9 403 iocmd[1] = '0' + line - XBee802::PWM0;
vpcola 0:f1d3878b8dd9 404 } else {
vpcola 0:f1d3878b8dd9 405 iocmd[0] = 'D';
vpcola 0:f1d3878b8dd9 406 iocmd[1] = '0' + line;
vpcola 0:f1d3878b8dd9 407 }
vpcola 0:f1d3878b8dd9 408 iocmd[2] = '\0';
vpcola 0:f1d3878b8dd9 409 }
vpcola 0:f1d3878b8dd9 410
vpcola 0:f1d3878b8dd9 411 RadioStatus XBee802::set_pin_config(const RemoteXBee& remote, IoLine line, IoMode mode)
vpcola 0:f1d3878b8dd9 412 {
vpcola 0:f1d3878b8dd9 413 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 414 char iocmd[3];
vpcola 0:f1d3878b8dd9 415
vpcola 0:f1d3878b8dd9 416 get_dio_cmd(line, iocmd);
vpcola 0:f1d3878b8dd9 417
vpcola 0:f1d3878b8dd9 418 cmdresp = set_param(remote, iocmd, (uint8_t)mode);
vpcola 0:f1d3878b8dd9 419 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 420 digi_log(LogLevelError, "set_pin_config: set_param returned %d\r\n", cmdresp);
vpcola 0:f1d3878b8dd9 421 return Failure;
vpcola 0:f1d3878b8dd9 422 }
vpcola 0:f1d3878b8dd9 423
vpcola 0:f1d3878b8dd9 424 return Success;
vpcola 0:f1d3878b8dd9 425 }
vpcola 0:f1d3878b8dd9 426
vpcola 0:f1d3878b8dd9 427 RadioStatus XBee802::get_pin_config(const RemoteXBee& remote, IoLine line, IoMode * const mode)
vpcola 0:f1d3878b8dd9 428 {
vpcola 0:f1d3878b8dd9 429 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 430 char iocmd[3];
vpcola 0:f1d3878b8dd9 431
vpcola 0:f1d3878b8dd9 432 get_dio_cmd(line, iocmd);
vpcola 0:f1d3878b8dd9 433
vpcola 0:f1d3878b8dd9 434 uint32_t var32;
vpcola 0:f1d3878b8dd9 435 cmdresp = get_param(remote, iocmd, &var32);
vpcola 0:f1d3878b8dd9 436 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 437 return Failure;
vpcola 0:f1d3878b8dd9 438 }
vpcola 0:f1d3878b8dd9 439 *mode = (IoMode)var32;
vpcola 0:f1d3878b8dd9 440
vpcola 0:f1d3878b8dd9 441 return Success;
vpcola 0:f1d3878b8dd9 442 }
vpcola 0:f1d3878b8dd9 443
vpcola 0:f1d3878b8dd9 444 RadioStatus XBee802::set_dio(const RemoteXBee& remote, IoLine line, DioVal val)
vpcola 0:f1d3878b8dd9 445 {
vpcola 0:f1d3878b8dd9 446 if (line > DI8) {
vpcola 0:f1d3878b8dd9 447 digi_log(LogLevelError, "set_dio: Pin %d not supported as IO\r\n", line);
vpcola 0:f1d3878b8dd9 448 return Failure;
vpcola 0:f1d3878b8dd9 449 }
vpcola 0:f1d3878b8dd9 450
vpcola 0:f1d3878b8dd9 451 if (val == Low) {
vpcola 0:f1d3878b8dd9 452 return set_pin_config(remote, line, DigitalOutLow);
vpcola 0:f1d3878b8dd9 453 } else {
vpcola 0:f1d3878b8dd9 454 return set_pin_config(remote, line, DigitalOutHigh);
vpcola 0:f1d3878b8dd9 455 }
vpcola 0:f1d3878b8dd9 456 }
vpcola 0:f1d3878b8dd9 457
vpcola 0:f1d3878b8dd9 458 RadioStatus XBee802::get_dio(const RemoteXBee& remote, IoLine line, DioVal * const val)
vpcola 0:f1d3878b8dd9 459 {
vpcola 0:f1d3878b8dd9 460 return get_iosample(remote).get_dio(line, val);
vpcola 0:f1d3878b8dd9 461 }
vpcola 0:f1d3878b8dd9 462
vpcola 0:f1d3878b8dd9 463 RadioStatus XBee802::get_adc(const RemoteXBee& remote, IoLine line, uint16_t * const val)
vpcola 0:f1d3878b8dd9 464 {
vpcola 0:f1d3878b8dd9 465 return get_iosample(remote).get_adc(line, val);
vpcola 0:f1d3878b8dd9 466 }
vpcola 0:f1d3878b8dd9 467
vpcola 0:f1d3878b8dd9 468 RadioStatus XBee802::set_pwm(const RemoteXBee& remote, IoLine line, float duty_cycle)
vpcola 0:f1d3878b8dd9 469 {
vpcola 0:f1d3878b8dd9 470 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 471 char iocmd[3] = { 'M', '0', '\0' };
vpcola 0:f1d3878b8dd9 472
vpcola 0:f1d3878b8dd9 473 if (line != PWM0 && line != PWM1) {
vpcola 0:f1d3878b8dd9 474 return Failure;
vpcola 0:f1d3878b8dd9 475 }
vpcola 0:f1d3878b8dd9 476 if (line == PWM1) {
vpcola 0:f1d3878b8dd9 477 iocmd[1] = '1';
vpcola 0:f1d3878b8dd9 478 }
vpcola 0:f1d3878b8dd9 479
vpcola 0:f1d3878b8dd9 480 uint16_t pwm_val = (uint16_t)(duty_cycle * DR_PWM_MAX_VAL / 100);
vpcola 0:f1d3878b8dd9 481
vpcola 0:f1d3878b8dd9 482 cmdresp = set_param(remote, iocmd, pwm_val);
vpcola 0:f1d3878b8dd9 483 return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
vpcola 0:f1d3878b8dd9 484 }
vpcola 0:f1d3878b8dd9 485
vpcola 0:f1d3878b8dd9 486 IOSample802 XBee802::get_iosample(const RemoteXBee& remote)
vpcola 0:f1d3878b8dd9 487 {
vpcola 0:f1d3878b8dd9 488 uint8_t io_sample[MAX_IO_SAMPLE_802_LEN];
vpcola 0:f1d3878b8dd9 489 uint16_t len = sizeof io_sample;
vpcola 0:f1d3878b8dd9 490
vpcola 0:f1d3878b8dd9 491 RadioStatus resp = _get_iosample(remote, io_sample, &len);
vpcola 0:f1d3878b8dd9 492 if (resp != Success) {
vpcola 0:f1d3878b8dd9 493 digi_log(LogLevelError, "XBee802::get_iosample failed to get an IOSample\r\n");
vpcola 0:f1d3878b8dd9 494 len = 0;
vpcola 0:f1d3878b8dd9 495 }
vpcola 0:f1d3878b8dd9 496 return IOSample802(io_sample, len);
vpcola 0:f1d3878b8dd9 497 }
vpcola 0:f1d3878b8dd9 498
vpcola 0:f1d3878b8dd9 499 static uint8_t get_dio_mask(XBee802::IoLine line)
vpcola 0:f1d3878b8dd9 500 {
vpcola 0:f1d3878b8dd9 501 switch (line) {
vpcola 0:f1d3878b8dd9 502 case XBee802::DIO4_AD4:
vpcola 0:f1d3878b8dd9 503 return (1 << 0);
vpcola 0:f1d3878b8dd9 504 case XBee802::DIO3_AD3:
vpcola 0:f1d3878b8dd9 505 return (1 << 1);
vpcola 0:f1d3878b8dd9 506 case XBee802::DIO2_AD2:
vpcola 0:f1d3878b8dd9 507 return (1 << 2);
vpcola 0:f1d3878b8dd9 508 case XBee802::DIO1_AD1:
vpcola 0:f1d3878b8dd9 509 return (1 << 3);
vpcola 0:f1d3878b8dd9 510 case XBee802::DIO0_AD0:
vpcola 0:f1d3878b8dd9 511 return (1 << 4);
vpcola 0:f1d3878b8dd9 512 case XBee802::DIO6:
vpcola 0:f1d3878b8dd9 513 return (1 << 5);
vpcola 0:f1d3878b8dd9 514 case XBee802::DI8:
vpcola 0:f1d3878b8dd9 515 return (1 << 6);
vpcola 0:f1d3878b8dd9 516 default:
vpcola 0:f1d3878b8dd9 517 return 0;
vpcola 0:f1d3878b8dd9 518 }
vpcola 0:f1d3878b8dd9 519 }
vpcola 0:f1d3878b8dd9 520
vpcola 0:f1d3878b8dd9 521 RadioStatus XBee802::set_pin_pull_up(const RemoteXBee& remote, IoLine line, bool enable)
vpcola 0:f1d3878b8dd9 522 {
vpcola 0:f1d3878b8dd9 523 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 524 uint32_t var32;
vpcola 0:f1d3878b8dd9 525 uint8_t pr;
vpcola 0:f1d3878b8dd9 526
vpcola 0:f1d3878b8dd9 527 cmdresp = get_param(remote, "PR", &var32);
vpcola 0:f1d3878b8dd9 528 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 529 return Failure;
vpcola 0:f1d3878b8dd9 530 }
vpcola 0:f1d3878b8dd9 531 pr = var32;
vpcola 0:f1d3878b8dd9 532
vpcola 0:f1d3878b8dd9 533 const uint8_t dio_mask = get_dio_mask(line);
vpcola 0:f1d3878b8dd9 534 if (dio_mask == 0) {
vpcola 0:f1d3878b8dd9 535 digi_log(LogLevelError, "XBee802::set_pin_pull_up: invalid pin %d\r\n", line);
vpcola 0:f1d3878b8dd9 536 return Failure;
vpcola 0:f1d3878b8dd9 537 }
vpcola 0:f1d3878b8dd9 538
vpcola 0:f1d3878b8dd9 539 if (enable) {
vpcola 0:f1d3878b8dd9 540 pr |= dio_mask;
vpcola 0:f1d3878b8dd9 541 } else {
vpcola 0:f1d3878b8dd9 542 pr &= ~dio_mask;
vpcola 0:f1d3878b8dd9 543 }
vpcola 0:f1d3878b8dd9 544
vpcola 0:f1d3878b8dd9 545 cmdresp = set_param(remote, "PR", pr);
vpcola 0:f1d3878b8dd9 546 return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
vpcola 0:f1d3878b8dd9 547 }
vpcola 0:f1d3878b8dd9 548
vpcola 0:f1d3878b8dd9 549 static uint8_t get_dio_ic_mask(XBee802::IoLine line)
vpcola 0:f1d3878b8dd9 550 {
vpcola 0:f1d3878b8dd9 551 if (line < XBee802::DI8) {
vpcola 0:f1d3878b8dd9 552 return (1 << line);
vpcola 0:f1d3878b8dd9 553 }
vpcola 0:f1d3878b8dd9 554 return 0;
vpcola 0:f1d3878b8dd9 555 }
vpcola 0:f1d3878b8dd9 556
vpcola 0:f1d3878b8dd9 557 RadioStatus XBee802::enable_dio_change_detection(const RemoteXBee& remote, IoLine line, bool enable)
vpcola 0:f1d3878b8dd9 558 {
vpcola 0:f1d3878b8dd9 559 if (line > DIO7) {
vpcola 0:f1d3878b8dd9 560 digi_log(LogLevelError, "XBee802::enable_dio_change_detection: pin not supported (%d)\r\n", line);
vpcola 0:f1d3878b8dd9 561 return Failure;
vpcola 0:f1d3878b8dd9 562 }
vpcola 0:f1d3878b8dd9 563
vpcola 0:f1d3878b8dd9 564 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 565 uint32_t var32;
vpcola 0:f1d3878b8dd9 566 uint8_t ic;
vpcola 0:f1d3878b8dd9 567
vpcola 0:f1d3878b8dd9 568 cmdresp = get_param(remote, "IC", &var32);
vpcola 0:f1d3878b8dd9 569 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 570 return Failure;
vpcola 0:f1d3878b8dd9 571 }
vpcola 0:f1d3878b8dd9 572 ic = var32;
vpcola 0:f1d3878b8dd9 573
vpcola 0:f1d3878b8dd9 574 const uint8_t dio_mask = get_dio_ic_mask(line);
vpcola 0:f1d3878b8dd9 575 if (dio_mask == 0) {
vpcola 0:f1d3878b8dd9 576 digi_log(LogLevelError, "XBeeZB::enable_dio_change_detection: invalid pin %d\r\n", line);
vpcola 0:f1d3878b8dd9 577 return Failure;
vpcola 0:f1d3878b8dd9 578 }
vpcola 0:f1d3878b8dd9 579
vpcola 0:f1d3878b8dd9 580 if (enable) {
vpcola 0:f1d3878b8dd9 581 ic |= dio_mask;
vpcola 0:f1d3878b8dd9 582 } else {
vpcola 0:f1d3878b8dd9 583 ic &= ~dio_mask;
vpcola 0:f1d3878b8dd9 584 }
vpcola 0:f1d3878b8dd9 585
vpcola 0:f1d3878b8dd9 586 cmdresp = set_param(remote, "IC", ic);
vpcola 0:f1d3878b8dd9 587 return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
vpcola 0:f1d3878b8dd9 588 }
vpcola 0:f1d3878b8dd9 589
vpcola 0:f1d3878b8dd9 590 #ifdef GET_PWM_AVAILABLE
vpcola 0:f1d3878b8dd9 591 RadioStatus XBee802::get_pwm(const RemoteXBee& remote, IoLine line, float * const duty_cycle)
vpcola 0:f1d3878b8dd9 592 {
vpcola 0:f1d3878b8dd9 593 AtCmdFrame::AtCmdResp cmdresp;
vpcola 0:f1d3878b8dd9 594 char iocmd[3] = { 'M', '0', '\0' };
vpcola 0:f1d3878b8dd9 595
vpcola 0:f1d3878b8dd9 596 if (line != PWM0 && line != PWM1) {
vpcola 0:f1d3878b8dd9 597 return Failure;
vpcola 0:f1d3878b8dd9 598 }
vpcola 0:f1d3878b8dd9 599
vpcola 0:f1d3878b8dd9 600 if (line == PWM1) {
vpcola 0:f1d3878b8dd9 601 iocmd[1] = '1';
vpcola 0:f1d3878b8dd9 602 }
vpcola 0:f1d3878b8dd9 603
vpcola 0:f1d3878b8dd9 604 uint16_t pwm_val;
vpcola 0:f1d3878b8dd9 605
vpcola 0:f1d3878b8dd9 606 cmdresp = get_param(remote, iocmd, &pwm_val);
vpcola 0:f1d3878b8dd9 607 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
vpcola 0:f1d3878b8dd9 608 return Failure;
vpcola 0:f1d3878b8dd9 609 }
vpcola 0:f1d3878b8dd9 610
vpcola 0:f1d3878b8dd9 611 *duty_cycle = (float)(pwm_val * 100 / DR_PWM_MAX_VAL);
vpcola 0:f1d3878b8dd9 612
vpcola 0:f1d3878b8dd9 613 return Success;
vpcola 0:f1d3878b8dd9 614 }
vpcola 0:f1d3878b8dd9 615 #endif