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