Library to easily communicate with XBee modules.

Fork of XBeeLib by Digi International Inc.

Committer:
spastor
Date:
Mon Jun 01 18:59:43 2015 +0200
Revision:
4:629712865107
Parent:
3:8662ebe83570
Child:
6:06522f3a6642
Automatic upload

Who changed what in which revision?

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