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