portado para MBED OS 6

Dependents:   Navitec-Firmware

Committer:
renanbmx123
Date:
Sun Apr 04 14:38:34 2021 +0000
Revision:
11:49f6346e02d7
Parent:
6:06522f3a6642
Refatorado

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 "XBeeLib.h"
spastor 0:fcaad0dfa051 14 #include "FrameHandlers/FH_ModemStatus.h"
spastor 0:fcaad0dfa051 15
spastor 0:fcaad0dfa051 16 /* States for the state machine that processes incoming data on the serial port */
spastor 0:fcaad0dfa051 17 #define WAITING_FOR_START_FRAME (0)
spastor 0:fcaad0dfa051 18 #define WAITING_FOR_LENGTH_MSB (1)
spastor 0:fcaad0dfa051 19 #define WAITING_FOR_LENGTH_LSB (2)
spastor 0:fcaad0dfa051 20 #define WAITING_FOR_PAYLOAD (3)
spastor 0:fcaad0dfa051 21 #define WAITING_FOR_CHECKSUM (4)
spastor 0:fcaad0dfa051 22
spastor 0:fcaad0dfa051 23 #define IS_API2() (_mode == ModeAPI2)
spastor 0:fcaad0dfa051 24 #define IS_API_MODE() (_mode == ModeAPI1 || _mode == ModeAPI2)
spastor 0:fcaad0dfa051 25
spastor 0:fcaad0dfa051 26 using namespace XBeeLib;
spastor 0:fcaad0dfa051 27
spastor 4:629712865107 28 #if defined(FRAME_BUFFER_SIZE_SYNCR)
spastor 4:629712865107 29 #if FRAME_BUFFER_SIZE_SYNCR < 2
spastor 4:629712865107 30 #error "FRAME_BUFFER_SIZE_SYNCR must be at least 2"
spastor 4:629712865107 31 #endif
spastor 4:629712865107 32 #else
spastor 4:629712865107 33 #define FRAME_BUFFER_SIZE_SYNCR 1
spastor 4:629712865107 34 #endif
spastor 4:629712865107 35
spastor 4:629712865107 36 #define MAX_FRAME_PAYLOAD_LEN_SYNCR (1 /* type */ + 1 /* id */ + 2 /* at cmd*/ + 1 /* status */ + 2 /* MY sender */ + \
spastor 4:629712865107 37 8 /* 64b sender */ + 20 /* max id */ + 1 /* null ter */ + 2 /* MY parent */ + 1 /* dev type */ + \
spastor 4:629712865107 38 1 /* source event */ + 2 /* prof. id */ + 2 /* man. id */)
spastor 4:629712865107 39
spastor 4:629712865107 40 FrameBuffer XBee::_framebuf_app(FRAME_BUFFER_SIZE, MAX_FRAME_PAYLOAD_LEN);
spastor 4:629712865107 41 FrameBuffer XBee::_framebuf_syncr(FRAME_BUFFER_SIZE_SYNCR, MAX_FRAME_PAYLOAD_LEN_SYNCR);
spastor 0:fcaad0dfa051 42
hbujanda 2:2ee1b6d51df2 43 #if defined(DEVICE_SERIAL_FC)
hbujanda 2:2ee1b6d51df2 44 bool XBee::check_radio_flow_control()
hbujanda 2:2ee1b6d51df2 45 {
hbujanda 2:2ee1b6d51df2 46 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 2:2ee1b6d51df2 47 uint32_t value;
hbujanda 2:2ee1b6d51df2 48
hbujanda 2:2ee1b6d51df2 49 if (_serial_flow_type == SerialBase::RTSCTS || _serial_flow_type == SerialBase::CTS) {
hbujanda 2:2ee1b6d51df2 50 cmdresp = get_param("D7", &value);
hbujanda 2:2ee1b6d51df2 51 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 2:2ee1b6d51df2 52 digi_log(LogLevelError, "Could not read CTS configuration. Error %d\r\n", cmdresp);
hbujanda 2:2ee1b6d51df2 53 return false;
spastor 4:629712865107 54 } else if (value != 1) {
hbujanda 2:2ee1b6d51df2 55 digi_log(LogLevelError, "Bad CTS configuration. Radio 'D7' param is %d and should be 1\r\n", value);
hbujanda 2:2ee1b6d51df2 56 return false;
hbujanda 2:2ee1b6d51df2 57 }
hbujanda 2:2ee1b6d51df2 58 }
hbujanda 2:2ee1b6d51df2 59
hbujanda 2:2ee1b6d51df2 60 if (_serial_flow_type == SerialBase::RTSCTS || _serial_flow_type == SerialBase::RTS) {
hbujanda 2:2ee1b6d51df2 61 cmdresp = get_param("D6", &value);
hbujanda 2:2ee1b6d51df2 62 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 2:2ee1b6d51df2 63 digi_log(LogLevelError, "Could not read RTS configuration. Error %d\r\n", cmdresp);
hbujanda 2:2ee1b6d51df2 64 return false;
spastor 4:629712865107 65 } else if (value != 1) {
hbujanda 2:2ee1b6d51df2 66 digi_log(LogLevelError, "Bad RTS configuration. Radio 'D6' param is %d and should be 1\r\n", value);
hbujanda 2:2ee1b6d51df2 67 return false;
hbujanda 2:2ee1b6d51df2 68 }
hbujanda 2:2ee1b6d51df2 69 }
hbujanda 2:2ee1b6d51df2 70
hbujanda 2:2ee1b6d51df2 71 return true;
hbujanda 2:2ee1b6d51df2 72 }
hbujanda 2:2ee1b6d51df2 73 #endif
hbujanda 2:2ee1b6d51df2 74
spastor 0:fcaad0dfa051 75 /* Class constructor */
spastor 0:fcaad0dfa051 76 XBee::XBee(PinName tx, PinName rx, PinName reset, PinName rts, PinName cts, int baud) :
spastor 4:629712865107 77 _mode(ModeUnknown), _hw_version(0), _fw_version(0), _timeout_ms(SYNC_OPS_TIMEOUT_MS), _dev_addr64(ADDR64_UNASSIGNED),
spastor 4:629712865107 78 _reset(NULL), _tx_options(0), _hw_reset_cnt(0), _wd_reset_cnt(0), _modem_status_handler(NULL), _modem_status(AtCmdFrame::HwReset), _initializing(true), _node_by_ni_frame_id(0)
spastor 0:fcaad0dfa051 79 {
spastor 0:fcaad0dfa051 80
spastor 0:fcaad0dfa051 81 if (reset != NC) {
hbujanda 1:794d1d3e4a08 82 _reset = new DigitalOut(reset, 1);
spastor 0:fcaad0dfa051 83 }
spastor 0:fcaad0dfa051 84
renanbmx123 11:49f6346e02d7 85 _uart = new UnbufferedSerial(tx, rx);
spastor 0:fcaad0dfa051 86 _uart->baud(baud);
hbujanda 1:794d1d3e4a08 87
hbujanda 1:794d1d3e4a08 88 _serial_flow_type = SerialBase::Disabled;
spastor 0:fcaad0dfa051 89 #if defined(DEVICE_SERIAL_FC)
spastor 0:fcaad0dfa051 90 if (rts != NC && cts != NC) {
hbujanda 1:794d1d3e4a08 91 _serial_flow_type = SerialBase::RTSCTS;
spastor 4:629712865107 92 _uart->set_flow_control(_serial_flow_type, rts, cts);
spastor 4:629712865107 93 } else if (rts != NC && cts == NC) {
hbujanda 1:794d1d3e4a08 94 _serial_flow_type = SerialBase::RTS;
hbujanda 1:794d1d3e4a08 95 _uart->set_flow_control(_serial_flow_type, rts);
spastor 4:629712865107 96 } else if (rts == NC && cts != NC) {
hbujanda 1:794d1d3e4a08 97 _serial_flow_type = SerialBase::CTS;
hbujanda 1:794d1d3e4a08 98 _uart->set_flow_control(_serial_flow_type, cts);
spastor 0:fcaad0dfa051 99 }
spastor 0:fcaad0dfa051 100 #endif
spastor 0:fcaad0dfa051 101 /* Enable the reception of bytes on the serial interface by providing a cb */
renanbmx123 11:49f6346e02d7 102 //_uart->attach(this, &XBee::uart_read_cb, Serial::RxIrq);
renanbmx123 11:49f6346e02d7 103 _uart->attach(callback(this,&XBee::uart_read_cb), SerialBase::RxIrq);
spastor 0:fcaad0dfa051 104
spastor 0:fcaad0dfa051 105 for (int i = 0; i < MAX_FRAME_HANDLERS; i++) {
spastor 0:fcaad0dfa051 106 _fhandlers[i] = NULL;
spastor 0:fcaad0dfa051 107 }
spastor 0:fcaad0dfa051 108 }
spastor 0:fcaad0dfa051 109
spastor 0:fcaad0dfa051 110 /* Class destructor */
spastor 0:fcaad0dfa051 111 XBee::~XBee()
spastor 0:fcaad0dfa051 112 {
spastor 0:fcaad0dfa051 113 unregister_modem_status_cb();
spastor 0:fcaad0dfa051 114
spastor 0:fcaad0dfa051 115 if (_uart != NULL) {
spastor 0:fcaad0dfa051 116 delete _uart;
spastor 0:fcaad0dfa051 117 }
spastor 0:fcaad0dfa051 118 if (_reset != NULL) {
spastor 0:fcaad0dfa051 119 delete _reset;
spastor 0:fcaad0dfa051 120 }
spastor 0:fcaad0dfa051 121 }
spastor 0:fcaad0dfa051 122
spastor 0:fcaad0dfa051 123 #include <inttypes.h>
spastor 0:fcaad0dfa051 124
spastor 0:fcaad0dfa051 125 RadioStatus XBee::init(void)
spastor 0:fcaad0dfa051 126 {
spastor 0:fcaad0dfa051 127 AtCmdFrame::AtCmdResp cmd_resp;
spastor 0:fcaad0dfa051 128 uint32_t var32;
spastor 0:fcaad0dfa051 129
spastor 0:fcaad0dfa051 130 _initializing = true;
spastor 0:fcaad0dfa051 131
spastor 4:629712865107 132 const unsigned int max_reset_retries = 3;
spastor 4:629712865107 133 RadioStatus reset_status;
spastor 4:629712865107 134 for (unsigned int i = 0; i < max_reset_retries; i++) {
spastor 4:629712865107 135 reset_status = device_reset();
spastor 4:629712865107 136 if (reset_status == Success) {
spastor 4:629712865107 137 break;
spastor 4:629712865107 138 }
spastor 4:629712865107 139 }
spastor 4:629712865107 140 if (reset_status != Success) {
spastor 4:629712865107 141 return reset_status;
spastor 4:629712865107 142 }
spastor 0:fcaad0dfa051 143
spastor 0:fcaad0dfa051 144 /* Check if radio is in API1 or API2 _mode */
spastor 0:fcaad0dfa051 145 cmd_resp = get_param("AP", &var32);
spastor 4:629712865107 146 if (cmd_resp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 147 return Failure;
spastor 4:629712865107 148 }
spastor 0:fcaad0dfa051 149 _mode = (RadioMode)var32;
spastor 0:fcaad0dfa051 150
spastor 0:fcaad0dfa051 151 /* Read the device unique 64b address */
spastor 0:fcaad0dfa051 152 uint32_t serialn_high, serialn_low;
spastor 0:fcaad0dfa051 153 cmd_resp = get_param("SH", &serialn_high);
spastor 4:629712865107 154 if (cmd_resp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 155 return Failure;
spastor 4:629712865107 156 }
spastor 4:629712865107 157
spastor 0:fcaad0dfa051 158 cmd_resp = get_param("SL", &serialn_low);
spastor 4:629712865107 159 if (cmd_resp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 160 return Failure;
spastor 4:629712865107 161 }
spastor 0:fcaad0dfa051 162
spastor 0:fcaad0dfa051 163 _dev_addr64 = ((uint64_t)serialn_high << 32) | serialn_low;
spastor 0:fcaad0dfa051 164
spastor 0:fcaad0dfa051 165 /* Read some important parameters */
spastor 0:fcaad0dfa051 166 cmd_resp = get_param("HV", &var32);
spastor 4:629712865107 167 if (cmd_resp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 168 return Failure;
spastor 4:629712865107 169 }
spastor 0:fcaad0dfa051 170 _hw_version = var32;
spastor 0:fcaad0dfa051 171
spastor 0:fcaad0dfa051 172 cmd_resp = get_param("VR", &var32);
spastor 4:629712865107 173 if (cmd_resp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 174 return Failure;
spastor 4:629712865107 175 }
spastor 0:fcaad0dfa051 176 _fw_version = var32;
spastor 0:fcaad0dfa051 177
spastor 0:fcaad0dfa051 178 digi_log(LogLevelInfo, "mode: %02x\r\n", (uint8_t)_mode);
spastor 0:fcaad0dfa051 179 digi_log(LogLevelInfo, "HV: %04x\r\n", _hw_version);
spastor 0:fcaad0dfa051 180 digi_log(LogLevelInfo, "VR: %04x\r\n", _fw_version);
spastor 0:fcaad0dfa051 181 digi_log(LogLevelInfo, "ADDR64: %08x:%08x\r\n", UINT64_HI32(_dev_addr64), UINT64_LO32(_dev_addr64));
spastor 0:fcaad0dfa051 182
hbujanda 2:2ee1b6d51df2 183 #if defined(DEVICE_SERIAL_FC)
hbujanda 2:2ee1b6d51df2 184 bool valid_radio_fc = check_radio_flow_control();
hbujanda 2:2ee1b6d51df2 185 assert(valid_radio_fc == true);
hbujanda 2:2ee1b6d51df2 186 #endif
hbujanda 2:2ee1b6d51df2 187
spastor 0:fcaad0dfa051 188 _initializing = false;
spastor 0:fcaad0dfa051 189 if (_modem_status_handler != NULL) {
spastor 0:fcaad0dfa051 190 const ApiFrame frame = ApiFrame(ApiFrame::AtModemStatus, (uint8_t *)&_modem_status, sizeof(_modem_status));
spastor 0:fcaad0dfa051 191 _modem_status_handler->process_frame_data(&frame);
spastor 4:629712865107 192 }
spastor 0:fcaad0dfa051 193
spastor 0:fcaad0dfa051 194 return Success;
spastor 0:fcaad0dfa051 195 }
spastor 0:fcaad0dfa051 196
spastor 0:fcaad0dfa051 197 uint64_t XBee::get_addr64() const
spastor 0:fcaad0dfa051 198 {
spastor 0:fcaad0dfa051 199 return _dev_addr64;
spastor 0:fcaad0dfa051 200 }
spastor 0:fcaad0dfa051 201
spastor 0:fcaad0dfa051 202 RadioStatus XBee::hardware_reset()
spastor 0:fcaad0dfa051 203 {
spastor 0:fcaad0dfa051 204 if (_reset != NULL) {
spastor 0:fcaad0dfa051 205 volatile uint16_t * const rst_cnt_p = &_hw_reset_cnt;
spastor 0:fcaad0dfa051 206 const uint16_t init_rst_cnt = *rst_cnt_p;
spastor 0:fcaad0dfa051 207 *_reset = 0;
renanbmx123 11:49f6346e02d7 208 //wait_ms(10);
renanbmx123 11:49f6346e02d7 209 ThisThread::sleep_for(chrono::milliseconds(10));
spastor 0:fcaad0dfa051 210 *_reset = 1;
spastor 0:fcaad0dfa051 211 return wait_for_module_to_reset(rst_cnt_p, init_rst_cnt);
spastor 0:fcaad0dfa051 212 }
spastor 0:fcaad0dfa051 213
spastor 0:fcaad0dfa051 214 return Failure;
spastor 0:fcaad0dfa051 215 }
spastor 0:fcaad0dfa051 216
spastor 0:fcaad0dfa051 217 RadioStatus XBee::device_reset()
spastor 0:fcaad0dfa051 218 {
spastor 4:629712865107 219 if (hardware_reset() == Success) {
spastor 0:fcaad0dfa051 220 return Success;
spastor 4:629712865107 221 }
spastor 0:fcaad0dfa051 222
spastor 0:fcaad0dfa051 223 return software_reset();
spastor 0:fcaad0dfa051 224 }
spastor 0:fcaad0dfa051 225
spastor 0:fcaad0dfa051 226 RadioStatus XBee::wait_for_module_to_reset(volatile uint16_t *rst_cnt_p, uint16_t init_rst_cnt)
spastor 0:fcaad0dfa051 227 {
spastor 4:629712865107 228 Timer timer = Timer();
spastor 4:629712865107 229 timer.start();
spastor 4:629712865107 230
renanbmx123 11:49f6346e02d7 231 //while (*rst_cnt_p == init_rst_cnt && timer.read_ms() < RESET_TIMEOUT_MS) {
renanbmx123 11:49f6346e02d7 232 //wait_ms(100);
renanbmx123 11:49f6346e02d7 233 while (*rst_cnt_p == init_rst_cnt && timer.elapsed_time().count() < RESET_TIMEOUT_MS) {
renanbmx123 11:49f6346e02d7 234
renanbmx123 11:49f6346e02d7 235 ThisThread::sleep_for(chrono::milliseconds(100));
spastor 0:fcaad0dfa051 236 }
spastor 0:fcaad0dfa051 237
spastor 4:629712865107 238 if (*rst_cnt_p == init_rst_cnt) {
spastor 0:fcaad0dfa051 239 digi_log(LogLevelWarning, "Reset Timeout\r\n");
spastor 0:fcaad0dfa051 240 return Failure;
spastor 0:fcaad0dfa051 241 }
spastor 0:fcaad0dfa051 242 return Success;
spastor 0:fcaad0dfa051 243 }
spastor 0:fcaad0dfa051 244
spastor 0:fcaad0dfa051 245 /** Callback function called when data is received on the serial port */
spastor 0:fcaad0dfa051 246 void XBee::uart_read_cb(void)
spastor 0:fcaad0dfa051 247 {
spastor 0:fcaad0dfa051 248 static uint8_t rxstate = WAITING_FOR_START_FRAME;
spastor 0:fcaad0dfa051 249 static uint16_t framelen = 0;
spastor 0:fcaad0dfa051 250 static uint16_t bytes_read;
spastor 0:fcaad0dfa051 251 static uint8_t chksum;
spastor 0:fcaad0dfa051 252 static ApiFrame *frame = NULL;
spastor 0:fcaad0dfa051 253 static bool last_byte_escaped = false;
spastor 4:629712865107 254 static FrameBuffer * framebuf = NULL;
spastor 4:629712865107 255
spastor 0:fcaad0dfa051 256 while (_uart->readable()) {
renanbmx123 11:49f6346e02d7 257 //uint8_t data = _uart->getc();
renanbmx123 11:49f6346e02d7 258 uint8_t data;
renanbmx123 11:49f6346e02d7 259 _uart->read(&data, 1);
spastor 4:629712865107 260
spastor 0:fcaad0dfa051 261 if (IS_API2() && rxstate != WAITING_FOR_START_FRAME) {
spastor 0:fcaad0dfa051 262 if (last_byte_escaped) {
spastor 0:fcaad0dfa051 263 data = data ^ DR_ESCAPE_XOR_BYTE;
spastor 0:fcaad0dfa051 264 last_byte_escaped = false;
spastor 0:fcaad0dfa051 265 } else if (data == DR_ESCAPE_BYTE) {
spastor 0:fcaad0dfa051 266 last_byte_escaped = true;
spastor 0:fcaad0dfa051 267 continue;
spastor 0:fcaad0dfa051 268 }
spastor 0:fcaad0dfa051 269 }
spastor 4:629712865107 270
spastor 0:fcaad0dfa051 271 switch (rxstate) {
spastor 0:fcaad0dfa051 272 case WAITING_FOR_START_FRAME:
spastor 4:629712865107 273 if (data == DR_START_OF_FRAME) {
spastor 0:fcaad0dfa051 274 rxstate = WAITING_FOR_LENGTH_MSB;
spastor 4:629712865107 275 }
spastor 0:fcaad0dfa051 276 break;
spastor 4:629712865107 277
spastor 0:fcaad0dfa051 278 case WAITING_FOR_LENGTH_MSB:
spastor 0:fcaad0dfa051 279 framelen = data << 8;
spastor 0:fcaad0dfa051 280 rxstate = WAITING_FOR_LENGTH_LSB;
spastor 0:fcaad0dfa051 281 break;
spastor 0:fcaad0dfa051 282
spastor 0:fcaad0dfa051 283 case WAITING_FOR_LENGTH_LSB:
spastor 0:fcaad0dfa051 284 framelen |= data;
spastor 4:629712865107 285 rxstate = WAITING_FOR_PAYLOAD;
spastor 0:fcaad0dfa051 286 bytes_read = 0;
spastor 0:fcaad0dfa051 287 chksum = 0;
spastor 0:fcaad0dfa051 288 /* Sanity check that the frame is smaller than... */
spastor 0:fcaad0dfa051 289 if (framelen > MAX_FRAME_PAYLOAD_LEN) {
spastor 0:fcaad0dfa051 290 digi_log(LogLevelDebug, "framelen=%d too long\r\n", framelen);
spastor 0:fcaad0dfa051 291 digi_log(LogLevelWarning, "Frame dropped, frame too long. Increase MAX_FRAME_PAYLOAD_LEN define\r\n");
spastor 0:fcaad0dfa051 292 rxstate = WAITING_FOR_START_FRAME;
spastor 0:fcaad0dfa051 293 }
spastor 0:fcaad0dfa051 294 break;
spastor 0:fcaad0dfa051 295
spastor 0:fcaad0dfa051 296 case WAITING_FOR_PAYLOAD:
spastor 4:629712865107 297 #define CACHED_SIZE 3
spastor 4:629712865107 298 static uint8_t frame_cached[CACHED_SIZE];
spastor 4:629712865107 299
spastor 4:629712865107 300 if (framelen <= CACHED_SIZE) {
spastor 4:629712865107 301 if (!bytes_read) {
spastor 4:629712865107 302 const ApiFrame::ApiFrameType frame_type = (ApiFrame::ApiFrameType)data;
spastor 4:629712865107 303 switch (frame_type)
spastor 4:629712865107 304 {
hbujanda 6:06522f3a6642 305 case ApiFrame::AtCmdResp:
hbujanda 6:06522f3a6642 306 case ApiFrame::RemoteCmdResp:
hbujanda 6:06522f3a6642 307 case ApiFrame::TxStatusZBDM:
hbujanda 6:06522f3a6642 308 case ApiFrame::TxStatus:
spastor 4:629712865107 309 framebuf = &_framebuf_syncr;
spastor 4:629712865107 310 break;
spastor 4:629712865107 311
hbujanda 6:06522f3a6642 312 case ApiFrame::RxPacket64Bit:
hbujanda 6:06522f3a6642 313 case ApiFrame::RxPacket16Bit:
hbujanda 6:06522f3a6642 314 case ApiFrame::Io64Bit:
hbujanda 6:06522f3a6642 315 case ApiFrame::Io16Bit:
hbujanda 6:06522f3a6642 316 case ApiFrame::AtModemStatus:
hbujanda 6:06522f3a6642 317 case ApiFrame::RxPacketAO0:
hbujanda 6:06522f3a6642 318 case ApiFrame::IoSampleRxZBDM:
spastor 4:629712865107 319 framebuf = &_framebuf_app;
spastor 4:629712865107 320 break;
spastor 4:629712865107 321
hbujanda 6:06522f3a6642 322 case ApiFrame::RxPacketAO1:
hbujanda 6:06522f3a6642 323 case ApiFrame::SensorRxIndAO0:
hbujanda 6:06522f3a6642 324 case ApiFrame::NodeIdentIndAO0:
hbujanda 6:06522f3a6642 325 case ApiFrame::OtaFwUpStatus:
hbujanda 6:06522f3a6642 326 case ApiFrame::RouteRecInd:
hbujanda 6:06522f3a6642 327 case ApiFrame::Many2OneRRInd:
hbujanda 6:06522f3a6642 328 case ApiFrame::TxReq64Bit:
hbujanda 6:06522f3a6642 329 case ApiFrame::TxReq16Bit:
hbujanda 6:06522f3a6642 330 case ApiFrame::AtCmd:
hbujanda 6:06522f3a6642 331 case ApiFrame::AtCmdQueuePV:
hbujanda 6:06522f3a6642 332 case ApiFrame::TxReqZBDM:
hbujanda 6:06522f3a6642 333 case ApiFrame::ExpAddrCmd:
hbujanda 6:06522f3a6642 334 case ApiFrame::RemoteCmdReq:
hbujanda 6:06522f3a6642 335 case ApiFrame::CreateSrcRoute:
hbujanda 6:06522f3a6642 336 case ApiFrame::Invalid:
hbujanda 6:06522f3a6642 337 case ApiFrame::RouteInfo:
hbujanda 6:06522f3a6642 338 case ApiFrame::AggregateAddr:
spastor 4:629712865107 339 framebuf = NULL;
spastor 4:629712865107 340 break;
spastor 4:629712865107 341 }
spastor 4:629712865107 342
spastor 4:629712865107 343 if (framebuf == NULL) {
spastor 4:629712865107 344 digi_log(LogLevelWarning, "Discarding not supported frame type %02x\r\n", frame_type);
spastor 4:629712865107 345 rxstate = WAITING_FOR_START_FRAME;
spastor 4:629712865107 346 } else {
spastor 4:629712865107 347 frame = framebuf->get_next_free_frame();
spastor 4:629712865107 348 if (frame == NULL) {
spastor 4:629712865107 349 /* It's not possible to achive this condition as we discard older frames and only one frame can be used by syncr. commands */
spastor 4:629712865107 350 assert(frame != NULL);
spastor 4:629712865107 351 rxstate = WAITING_FOR_START_FRAME;
spastor 4:629712865107 352 } else {
spastor 4:629712865107 353 frame->set_data_len(framelen - 1);
spastor 4:629712865107 354 }
spastor 4:629712865107 355
spastor 4:629712865107 356 frame->set_frame_type(frame_type);
spastor 4:629712865107 357 }
spastor 4:629712865107 358 } else {
spastor 4:629712865107 359 frame->set_data(data, bytes_read - 1);
spastor 4:629712865107 360 }
spastor 4:629712865107 361 chksum += data;
spastor 4:629712865107 362 bytes_read++;
spastor 4:629712865107 363 if (bytes_read == framelen) {
spastor 4:629712865107 364 rxstate = WAITING_FOR_CHECKSUM;
spastor 4:629712865107 365 }
spastor 4:629712865107 366 break;
spastor 4:629712865107 367 }
spastor 4:629712865107 368
spastor 4:629712865107 369
spastor 4:629712865107 370 if (bytes_read < CACHED_SIZE) {
spastor 4:629712865107 371 frame_cached[bytes_read] = data;
spastor 4:629712865107 372 }
spastor 4:629712865107 373 else if (bytes_read == CACHED_SIZE) {
spastor 4:629712865107 374 const ApiFrame::ApiFrameType frame_type = (ApiFrame::ApiFrameType)frame_cached[0];
spastor 4:629712865107 375 switch (frame_type)
spastor 4:629712865107 376 {
hbujanda 6:06522f3a6642 377 case ApiFrame::RemoteCmdResp:
hbujanda 6:06522f3a6642 378 case ApiFrame::TxStatusZBDM:
hbujanda 6:06522f3a6642 379 case ApiFrame::TxStatus:
spastor 4:629712865107 380 framebuf = &_framebuf_syncr;
spastor 4:629712865107 381 break;
spastor 4:629712865107 382
hbujanda 6:06522f3a6642 383 case ApiFrame::AtCmdResp:
spastor 4:629712865107 384 if ((frame_cached[1] != _node_by_ni_frame_id ) && (frame_cached[2] == 'N') && (data == 'D'))
spastor 4:629712865107 385 {
spastor 4:629712865107 386 framebuf = &_framebuf_app;
spastor 4:629712865107 387 } else {
spastor 4:629712865107 388 framebuf = &_framebuf_syncr;
spastor 4:629712865107 389 }
spastor 4:629712865107 390 break;
spastor 4:629712865107 391
hbujanda 6:06522f3a6642 392 case ApiFrame::RxPacket64Bit:
hbujanda 6:06522f3a6642 393 case ApiFrame::RxPacket16Bit:
hbujanda 6:06522f3a6642 394 case ApiFrame::Io64Bit:
hbujanda 6:06522f3a6642 395 case ApiFrame::Io16Bit:
hbujanda 6:06522f3a6642 396 case ApiFrame::AtModemStatus:
hbujanda 6:06522f3a6642 397 case ApiFrame::RxPacketAO0:
hbujanda 6:06522f3a6642 398 case ApiFrame::IoSampleRxZBDM:
spastor 4:629712865107 399 framebuf = &_framebuf_app;
spastor 4:629712865107 400 break;
spastor 4:629712865107 401
hbujanda 6:06522f3a6642 402 case ApiFrame::RxPacketAO1:
hbujanda 6:06522f3a6642 403 case ApiFrame::SensorRxIndAO0:
hbujanda 6:06522f3a6642 404 case ApiFrame::NodeIdentIndAO0:
hbujanda 6:06522f3a6642 405 case ApiFrame::OtaFwUpStatus:
hbujanda 6:06522f3a6642 406 case ApiFrame::RouteRecInd:
hbujanda 6:06522f3a6642 407 case ApiFrame::Many2OneRRInd:
hbujanda 6:06522f3a6642 408 case ApiFrame::TxReq64Bit:
hbujanda 6:06522f3a6642 409 case ApiFrame::TxReq16Bit:
hbujanda 6:06522f3a6642 410 case ApiFrame::AtCmd:
hbujanda 6:06522f3a6642 411 case ApiFrame::AtCmdQueuePV:
hbujanda 6:06522f3a6642 412 case ApiFrame::TxReqZBDM:
hbujanda 6:06522f3a6642 413 case ApiFrame::ExpAddrCmd:
hbujanda 6:06522f3a6642 414 case ApiFrame::RemoteCmdReq:
hbujanda 6:06522f3a6642 415 case ApiFrame::CreateSrcRoute:
hbujanda 6:06522f3a6642 416 case ApiFrame::Invalid:
hbujanda 6:06522f3a6642 417 case ApiFrame::RouteInfo:
hbujanda 6:06522f3a6642 418 case ApiFrame::AggregateAddr:
spastor 4:629712865107 419 framebuf = NULL;
spastor 4:629712865107 420 break;
spastor 4:629712865107 421 }
spastor 4:629712865107 422
spastor 4:629712865107 423 if (framebuf == NULL) {
spastor 4:629712865107 424 digi_log(LogLevelWarning, "Discarding not supported frame type %02x\r\n", frame_type);
spastor 4:629712865107 425 rxstate = WAITING_FOR_START_FRAME;
spastor 4:629712865107 426 } else {
spastor 4:629712865107 427 frame = framebuf->get_next_free_frame();
spastor 4:629712865107 428 if (frame == NULL) {
spastor 4:629712865107 429 /* It's not possible to achive this condition as we discard older frames and only one frame can be used by syncr. commands */
spastor 4:629712865107 430 assert(frame != NULL);
spastor 4:629712865107 431 rxstate = WAITING_FOR_START_FRAME;
spastor 4:629712865107 432 } else {
spastor 4:629712865107 433 frame->set_data_len(framelen - 1);
spastor 4:629712865107 434 }
spastor 4:629712865107 435
spastor 4:629712865107 436 frame->set_frame_type(frame_type);
spastor 4:629712865107 437 frame->set_data(frame_cached[1], 0);
spastor 4:629712865107 438 frame->set_data(frame_cached[2], 1);
spastor 4:629712865107 439 frame->set_data(data, 2);
spastor 4:629712865107 440 }
spastor 4:629712865107 441 } else {
spastor 0:fcaad0dfa051 442 frame->set_data(data, bytes_read - 1);
spastor 0:fcaad0dfa051 443 }
spastor 0:fcaad0dfa051 444 chksum += data;
spastor 0:fcaad0dfa051 445 bytes_read++;
spastor 4:629712865107 446 if (bytes_read == framelen) {
spastor 0:fcaad0dfa051 447 rxstate = WAITING_FOR_CHECKSUM;
spastor 4:629712865107 448 }
spastor 0:fcaad0dfa051 449 break;
spastor 0:fcaad0dfa051 450
spastor 0:fcaad0dfa051 451 case WAITING_FOR_CHECKSUM:
spastor 0:fcaad0dfa051 452 chksum += data;
spastor 0:fcaad0dfa051 453 if (chksum == 0xFF) {
spastor 0:fcaad0dfa051 454 /* We got a valid frame!! */
spastor 0:fcaad0dfa051 455 frame->dump();
spastor 4:629712865107 456
spastor 0:fcaad0dfa051 457 /* If its a _modem status frame, process it to update the status info of the library.
spastor 0:fcaad0dfa051 458 * The frame is also queued to allow processing it other handlers registered.
spastor 0:fcaad0dfa051 459 * Note that radio_status_update() has to be fast to minimize the impact of processing
spastor 0:fcaad0dfa051 460 * the funcion here */
spastor 0:fcaad0dfa051 461 if (frame->get_frame_type() == ApiFrame::AtModemStatus) {
spastor 0:fcaad0dfa051 462 radio_status_update((AtCmdFrame::ModemStatus)frame->get_data_at(0));
spastor 4:629712865107 463 if (_initializing) {
spastor 4:629712865107 464 framebuf->free_frame(frame);
spastor 4:629712865107 465 } else {
spastor 4:629712865107 466 framebuf->complete_frame(frame);
spastor 4:629712865107 467 }
spastor 4:629712865107 468 } else {
spastor 4:629712865107 469 framebuf->complete_frame(frame);
spastor 0:fcaad0dfa051 470 /* Note, the frame will be released elsewhere, once it has been processed */
spastor 0:fcaad0dfa051 471 }
spastor 0:fcaad0dfa051 472 } else {
spastor 4:629712865107 473 framebuf->free_frame(frame);
spastor 0:fcaad0dfa051 474 digi_log(LogLevelWarning, "Checksum error, got %02x, %02x\r\n", data, chksum);
spastor 0:fcaad0dfa051 475 }
spastor 0:fcaad0dfa051 476 /* Intentional fall-through */
spastor 0:fcaad0dfa051 477 default:
spastor 0:fcaad0dfa051 478 rxstate = WAITING_FOR_START_FRAME;
spastor 0:fcaad0dfa051 479 break;
spastor 4:629712865107 480 }
spastor 0:fcaad0dfa051 481 }
spastor 0:fcaad0dfa051 482 /* TODO, signal the thread processing incoming frames */
spastor 0:fcaad0dfa051 483 }
spastor 0:fcaad0dfa051 484
spastor 0:fcaad0dfa051 485 /* This is a pure virtual function, but exists here because its called from this class to
spastor 4:629712865107 486 * to update the status of the object, and can be called before the construction of the
spastor 0:fcaad0dfa051 487 * object has been completed and the virtual functions filled */
spastor 0:fcaad0dfa051 488 void XBee::radio_status_update(AtCmdFrame::ModemStatus modem_status)
spastor 0:fcaad0dfa051 489 {
hbujanda 2:2ee1b6d51df2 490 UNUSED_PARAMETER(modem_status);
spastor 0:fcaad0dfa051 491 }
spastor 0:fcaad0dfa051 492
spastor 0:fcaad0dfa051 493 void XBee::set_timeout(uint16_t timeout_ms)
spastor 0:fcaad0dfa051 494 {
spastor 4:629712865107 495 this->_timeout_ms = timeout_ms;
spastor 0:fcaad0dfa051 496 }
spastor 0:fcaad0dfa051 497
spastor 0:fcaad0dfa051 498 uint16_t XBee::get_timeout(void) const
spastor 0:fcaad0dfa051 499 {
spastor 0:fcaad0dfa051 500 return _timeout_ms;
spastor 0:fcaad0dfa051 501 }
spastor 0:fcaad0dfa051 502
spastor 4:629712865107 503 ApiFrame * XBee::get_this_api_frame(uint8_t id, ApiFrame::ApiFrameType type,
spastor 0:fcaad0dfa051 504 ApiFrame::ApiFrameType type2)
spastor 0:fcaad0dfa051 505 {
spastor 4:629712865107 506 Timer timer = Timer();
spastor 4:629712865107 507 timer.start();
spastor 0:fcaad0dfa051 508
renanbmx123 11:49f6346e02d7 509 //while (timer.read_ms() < _timeout_ms) {
renanbmx123 11:49f6346e02d7 510 while (timer.elapsed_time().count() < _timeout_ms) {
renanbmx123 11:49f6346e02d7 511
spastor 4:629712865107 512 ApiFrame * frame = _framebuf_syncr.get_next_complete_frame();
spastor 0:fcaad0dfa051 513 if (frame == NULL) {
renanbmx123 11:49f6346e02d7 514 //wait_ms(10);
renanbmx123 11:49f6346e02d7 515 ThisThread::sleep_for(chrono::milliseconds(10));
spastor 0:fcaad0dfa051 516 continue;
spastor 0:fcaad0dfa051 517 }
spastor 0:fcaad0dfa051 518
spastor 0:fcaad0dfa051 519 if ((frame->get_frame_type() != type) &&
spastor 0:fcaad0dfa051 520 (frame->get_frame_type() != type2)) {
spastor 4:629712865107 521 _framebuf_syncr.complete_frame(frame);
renanbmx123 11:49f6346e02d7 522 //wait_ms(1);
renanbmx123 11:49f6346e02d7 523 ThisThread::sleep_for(chrono::milliseconds(1));
spastor 0:fcaad0dfa051 524 continue;
spastor 0:fcaad0dfa051 525 }
spastor 0:fcaad0dfa051 526
spastor 4:629712865107 527 if (frame->get_data_at(ATCMD_RESP_FRAME_ID_OFFSET) != id) {
spastor 4:629712865107 528 _framebuf_syncr.complete_frame(frame);
renanbmx123 11:49f6346e02d7 529 //wait_ms(1);
renanbmx123 11:49f6346e02d7 530 ThisThread::sleep_for(chrono::milliseconds(1));
spastor 4:629712865107 531 continue;
spastor 4:629712865107 532 }
spastor 4:629712865107 533
spastor 4:629712865107 534 /* frame found */
spastor 0:fcaad0dfa051 535 return frame;
spastor 0:fcaad0dfa051 536 }
spastor 4:629712865107 537
spastor 0:fcaad0dfa051 538 digi_log(LogLevelWarning, "Frame type: %02x, id: %02x, timeout\r\n", (uint8_t)type, id);
spastor 0:fcaad0dfa051 539
spastor 0:fcaad0dfa051 540 return NULL;
spastor 0:fcaad0dfa051 541 }
spastor 0:fcaad0dfa051 542
spastor 0:fcaad0dfa051 543 void XBee::send_byte_escaping_if(uint8_t data)
spastor 0:fcaad0dfa051 544 {
spastor 0:fcaad0dfa051 545 if (IS_API2()) {
spastor 0:fcaad0dfa051 546 switch (data) {
spastor 0:fcaad0dfa051 547 case DR_START_OF_FRAME:
spastor 0:fcaad0dfa051 548 case DR_ESCAPE_BYTE:
spastor 0:fcaad0dfa051 549 case DR_XON_BYTE:
spastor 0:fcaad0dfa051 550 case DR_XOFF_BYTE:
renanbmx123 11:49f6346e02d7 551 //_uart->putc(DR_ESCAPE_BYTE);
renanbmx123 11:49f6346e02d7 552 //_uart->putc(data ^ DR_ESCAPE_XOR_BYTE);
renanbmx123 11:49f6346e02d7 553 _uart->write((uint8_t *)DR_ESCAPE_BYTE, 1);
renanbmx123 11:49f6346e02d7 554 _uart->write((uint8_t *)(data ^ DR_ESCAPE_XOR_BYTE),1);
spastor 0:fcaad0dfa051 555 break;
spastor 0:fcaad0dfa051 556 default:
renanbmx123 11:49f6346e02d7 557 //_uart->putc(data);
renanbmx123 11:49f6346e02d7 558 _uart->write(&data,1);
spastor 0:fcaad0dfa051 559 }
spastor 0:fcaad0dfa051 560 } else {
renanbmx123 11:49f6346e02d7 561 //_uart->putc(data);
renanbmx123 11:49f6346e02d7 562 _uart->write(&data,1);
spastor 4:629712865107 563 }
spastor 0:fcaad0dfa051 564 }
spastor 0:fcaad0dfa051 565
spastor 0:fcaad0dfa051 566 void XBee::send_api_frame(ApiFrame *frame)
spastor 0:fcaad0dfa051 567 {
spastor 0:fcaad0dfa051 568 uint8_t chksum;
spastor 0:fcaad0dfa051 569 const uint8_t *data;
spastor 0:fcaad0dfa051 570 uint16_t bytes_sent = 0, frame_len;
spastor 4:629712865107 571
spastor 0:fcaad0dfa051 572 frame->dump();
spastor 4:629712865107 573
spastor 0:fcaad0dfa051 574 frame_len = 1 + frame->get_data_len(); /* frame type + frame payload */
spastor 0:fcaad0dfa051 575 data = frame->get_data();
spastor 4:629712865107 576
spastor 0:fcaad0dfa051 577 /* Send the start of frame delimiter */
renanbmx123 11:49f6346e02d7 578 //_uart->putc(DR_START_OF_FRAME);
renanbmx123 11:49f6346e02d7 579 _uart->write((uint8_t *)DR_START_OF_FRAME,1);
spastor 4:629712865107 580
spastor 0:fcaad0dfa051 581 /* Now the length */
spastor 0:fcaad0dfa051 582 send_byte_escaping_if((uint8_t)(frame_len >> 8));
spastor 0:fcaad0dfa051 583 send_byte_escaping_if((uint8_t)frame_len);
spastor 0:fcaad0dfa051 584
spastor 0:fcaad0dfa051 585 /* Send the Frame type and then the payload */
spastor 0:fcaad0dfa051 586 chksum = (uint8_t)frame->get_frame_type();
spastor 0:fcaad0dfa051 587 send_byte_escaping_if(chksum);
spastor 0:fcaad0dfa051 588 bytes_sent++;
spastor 0:fcaad0dfa051 589
spastor 0:fcaad0dfa051 590 /* And now, send the packet payload */
spastor 0:fcaad0dfa051 591 while (bytes_sent++ < frame_len) {
spastor 0:fcaad0dfa051 592 chksum += *data;
spastor 0:fcaad0dfa051 593 send_byte_escaping_if(*data++);
spastor 0:fcaad0dfa051 594 }
spastor 4:629712865107 595
spastor 0:fcaad0dfa051 596 /* And finally send the checksum */
spastor 0:fcaad0dfa051 597 send_byte_escaping_if(~chksum);
spastor 0:fcaad0dfa051 598 }
spastor 4:629712865107 599
spastor 0:fcaad0dfa051 600 RadioStatus XBee::register_frame_handler(FrameHandler *const handler)
spastor 0:fcaad0dfa051 601 {
spastor 0:fcaad0dfa051 602 if (handler != NULL) {
spastor 0:fcaad0dfa051 603 for (int i = 0; i < MAX_FRAME_HANDLERS; i++) {
spastor 4:629712865107 604 if (_fhandlers[i] != NULL) {
spastor 0:fcaad0dfa051 605 continue;
spastor 4:629712865107 606 }
spastor 0:fcaad0dfa051 607 _fhandlers[i] = handler;
spastor 0:fcaad0dfa051 608 return Success;
spastor 0:fcaad0dfa051 609 }
spastor 0:fcaad0dfa051 610 }
spastor 0:fcaad0dfa051 611
spastor 0:fcaad0dfa051 612 digi_log(LogLevelError, "No more Frame Handlers available. Increase MAX_FRAME_HANDLERS define\r\n");
spastor 4:629712865107 613
spastor 0:fcaad0dfa051 614 return Failure;
spastor 4:629712865107 615 }
spastor 0:fcaad0dfa051 616
spastor 0:fcaad0dfa051 617 RadioStatus XBee::unregister_frame_handler(FrameHandler *const handler)
spastor 0:fcaad0dfa051 618 {
spastor 0:fcaad0dfa051 619 int i;
spastor 0:fcaad0dfa051 620
spastor 0:fcaad0dfa051 621 if (handler != NULL) {
spastor 0:fcaad0dfa051 622 for (i = 0; i < MAX_FRAME_HANDLERS; i++) {
spastor 4:629712865107 623 if (_fhandlers[i] == handler) {
spastor 0:fcaad0dfa051 624 break;
spastor 4:629712865107 625 }
spastor 0:fcaad0dfa051 626 }
spastor 4:629712865107 627
spastor 4:629712865107 628 if (i == MAX_FRAME_HANDLERS) {
spastor 0:fcaad0dfa051 629 return Failure;
spastor 4:629712865107 630 }
spastor 4:629712865107 631
spastor 0:fcaad0dfa051 632 do {
spastor 4:629712865107 633 if (i == MAX_FRAME_HANDLERS - 1) {
spastor 0:fcaad0dfa051 634 _fhandlers[i] = NULL;
spastor 4:629712865107 635 } else {
spastor 0:fcaad0dfa051 636 _fhandlers[i] = _fhandlers[i + 1];
spastor 4:629712865107 637 }
spastor 0:fcaad0dfa051 638 } while (++i < MAX_FRAME_HANDLERS);
spastor 0:fcaad0dfa051 639 }
spastor 0:fcaad0dfa051 640
spastor 0:fcaad0dfa051 641 return Success;
spastor 0:fcaad0dfa051 642 }
spastor 0:fcaad0dfa051 643
spastor 0:fcaad0dfa051 644 XBee::RadioProtocol XBee::get_radio_protocol(void) const
spastor 0:fcaad0dfa051 645 {
spastor 0:fcaad0dfa051 646 enum HardwareVersion {
spastor 0:fcaad0dfa051 647 #ifdef EXTRA_XBEE_PROTOCOLS
spastor 0:fcaad0dfa051 648 X09_009 = 0x01,
spastor 0:fcaad0dfa051 649 X09_019 = 0x02,
spastor 0:fcaad0dfa051 650 XH9_009 = 0x03,
spastor 0:fcaad0dfa051 651 XH9_019 = 0x04,
spastor 0:fcaad0dfa051 652 X24_009 = 0x05,
spastor 0:fcaad0dfa051 653 X24_019 = 0x06,
spastor 0:fcaad0dfa051 654 X09_001 = 0x07,
spastor 0:fcaad0dfa051 655 XH9_001 = 0x08,
spastor 0:fcaad0dfa051 656 X08_004 = 0x09,
spastor 0:fcaad0dfa051 657 XC09_009 = 0x0A,
spastor 0:fcaad0dfa051 658 XC09_038 = 0x0B,
spastor 0:fcaad0dfa051 659 X24_038 = 0x0C,
spastor 0:fcaad0dfa051 660 X09_009_TX = 0x0D,
spastor 0:fcaad0dfa051 661 X09_019_TX = 0x0E,
spastor 0:fcaad0dfa051 662 XH9_009_TX = 0x0F,
spastor 0:fcaad0dfa051 663 XH9_019_TX = 0x10,
spastor 0:fcaad0dfa051 664 X09_001_TX = 0x11,
spastor 0:fcaad0dfa051 665 XH9_001_TX = 0x12,
spastor 0:fcaad0dfa051 666 XT09B_XXX = 0x13,
spastor 0:fcaad0dfa051 667 XT09_XXX = 0x14,
spastor 0:fcaad0dfa051 668 XC08_009 = 0x15,
spastor 0:fcaad0dfa051 669 XC08_038 = 0x16,
spastor 0:fcaad0dfa051 670 #endif
spastor 0:fcaad0dfa051 671 XB24_AXX_XX = 0x17,
spastor 0:fcaad0dfa051 672 XBP24_AXX_XX = 0x18,
spastor 0:fcaad0dfa051 673 XB24_BXIX_XXX = 0x19,
spastor 0:fcaad0dfa051 674 XBP24_BXIX_XXX = 0x1A,
spastor 0:fcaad0dfa051 675 #ifdef EXTRA_XBEE_PROTOCOLS
spastor 0:fcaad0dfa051 676 XBP09_DXIX_XXX = 0x1B,
spastor 0:fcaad0dfa051 677 XBP09_XCXX_XXX = 0x1C,
spastor 0:fcaad0dfa051 678 XBP08_DXXX_XXX = 0x1D,
spastor 0:fcaad0dfa051 679 #endif
spastor 0:fcaad0dfa051 680 XBP24B = 0x1E,
spastor 0:fcaad0dfa051 681 #ifdef EXTRA_XBEE_PROTOCOLS
spastor 0:fcaad0dfa051 682 XB24_WF = 0x1F,
spastor 0:fcaad0dfa051 683 AMBER_MBUS = 0x20,
spastor 0:fcaad0dfa051 684 #endif
spastor 0:fcaad0dfa051 685 XBP24C = 0x21,
spastor 0:fcaad0dfa051 686 XB24C = 0x22,
spastor 0:fcaad0dfa051 687 #ifdef EXTRA_XBEE_PROTOCOLS
spastor 0:fcaad0dfa051 688 XSC_GEN3 = 0x23,
spastor 0:fcaad0dfa051 689 SRD_868_GEN3 = 0x24,
spastor 0:fcaad0dfa051 690 ABANDONATED = 0x25,
spastor 0:fcaad0dfa051 691 SMT_900LP = 0x26,
spastor 0:fcaad0dfa051 692 WIFI_ATHEROS = 0x27,
spastor 0:fcaad0dfa051 693 SMT_WIFI_ATHEROS = 0x28,
spastor 0:fcaad0dfa051 694 SMT_475LP = 0x29,
spastor 0:fcaad0dfa051 695 XBEE_CELL_TH = 0x2A,
spastor 0:fcaad0dfa051 696 XLR_MODULE = 0x2B,
spastor 0:fcaad0dfa051 697 XB900HP_NZ = 0x2C,
spastor 0:fcaad0dfa051 698 XBP24C_TH_DIP = 0x2D,
spastor 0:fcaad0dfa051 699 XB24C_TH_DIP = 0x2E,
hbujanda 5:da2ea7a76243 700 XLR_BASEBOARD = 0x2F,
hbujanda 5:da2ea7a76243 701 XBP24C_S2C_SMT = 0x30
spastor 0:fcaad0dfa051 702 #endif
spastor 0:fcaad0dfa051 703 };
spastor 0:fcaad0dfa051 704 const bool fw_4_bytes_len = _fw_version > 0x0FFF && _fw_version < 0xFFFF;
spastor 0:fcaad0dfa051 705 const uint8_t fw_nibble_3 = (_fw_version >> (4 * 3)) & 0x000F;
spastor 0:fcaad0dfa051 706 const uint8_t fw_nibble_1 = (_fw_version >> (4 * 1)) & 0x000F;
spastor 0:fcaad0dfa051 707 const uint8_t fw_nibble_0 = (_fw_version >> (4 * 0)) & 0x000F;
spastor 0:fcaad0dfa051 708 const uint8_t hw_version_msb = _hw_version >> 8;
spastor 0:fcaad0dfa051 709
spastor 0:fcaad0dfa051 710 if (hw_version_msb == XB24_AXX_XX || hw_version_msb == XBP24_AXX_XX) {
spastor 0:fcaad0dfa051 711 #ifdef EXTRA_XBEE_PROTOCOLS
spastor 0:fcaad0dfa051 712 if (fw_4_bytes_len && fw_nibble_3 == 8) {
spastor 0:fcaad0dfa051 713 return DigiMesh;
spastor 0:fcaad0dfa051 714 }
spastor 0:fcaad0dfa051 715 return Raw_802_15_4;
spastor 0:fcaad0dfa051 716 #else
spastor 0:fcaad0dfa051 717 if (!(fw_4_bytes_len && fw_nibble_3 == 8)) {
spastor 0:fcaad0dfa051 718 return Raw_802_15_4;
spastor 0:fcaad0dfa051 719 }
spastor 0:fcaad0dfa051 720 #endif
spastor 0:fcaad0dfa051 721 } else if (hw_version_msb == XB24_BXIX_XXX || hw_version_msb == XBP24_BXIX_XXX) {
spastor 0:fcaad0dfa051 722 if (fw_4_bytes_len && ((fw_nibble_3 == 1 && fw_nibble_1 == 2 && fw_nibble_0 == 0) || fw_nibble_3 == 2)) {
spastor 0:fcaad0dfa051 723 return ZigBee;
spastor 0:fcaad0dfa051 724 }
spastor 0:fcaad0dfa051 725 #ifdef EXTRA_XBEE_PROTOCOLS
spastor 0:fcaad0dfa051 726 if (fw_4_bytes_len && fw_nibble_3 == 3) {
spastor 0:fcaad0dfa051 727 return SmartEnergy;
spastor 0:fcaad0dfa051 728 }
spastor 0:fcaad0dfa051 729 return ZNet;
spastor 0:fcaad0dfa051 730 } else if (hw_version_msb == XBP09_DXIX_XXX) {
spastor 0:fcaad0dfa051 731 if (fw_4_bytes_len && (fw_nibble_3 == 8 || fw_nibble_1 == 8)) {
spastor 0:fcaad0dfa051 732 return DigiMesh;
spastor 0:fcaad0dfa051 733 }
spastor 0:fcaad0dfa051 734 return DigiPoint;
spastor 0:fcaad0dfa051 735 } else if (hw_version_msb == XBP08_DXXX_XXX) {
spastor 0:fcaad0dfa051 736 return DigiPoint;
spastor 0:fcaad0dfa051 737 #endif
spastor 0:fcaad0dfa051 738 } else if (hw_version_msb == XBP24B) {
spastor 0:fcaad0dfa051 739 #ifdef EXTRA_XBEE_PROTOCOLS
spastor 0:fcaad0dfa051 740 if (fw_4_bytes_len && fw_nibble_3 == 3) {
spastor 0:fcaad0dfa051 741 return SmartEnergy;
spastor 0:fcaad0dfa051 742 }
spastor 0:fcaad0dfa051 743 return ZigBee;
spastor 0:fcaad0dfa051 744 #else
spastor 0:fcaad0dfa051 745 if (!(fw_4_bytes_len && fw_nibble_3 == 3)) {
spastor 0:fcaad0dfa051 746 return ZigBee;
spastor 0:fcaad0dfa051 747 }
spastor 0:fcaad0dfa051 748 #endif
spastor 0:fcaad0dfa051 749 #ifdef EXTRA_XBEE_PROTOCOLS
spastor 0:fcaad0dfa051 750 } else if (hw_version_msb == XB24_WF || hw_version_msb == WIFI_ATHEROS || hw_version_msb == SMT_WIFI_ATHEROS) {
spastor 0:fcaad0dfa051 751 return XBeeWiFi;
spastor 0:fcaad0dfa051 752 #endif
spastor 0:fcaad0dfa051 753 } else if (hw_version_msb == XBP24C || hw_version_msb == XB24C) {
hbujanda 5:da2ea7a76243 754 if (fw_4_bytes_len && fw_nibble_3 == 2) {
hbujanda 5:da2ea7a76243 755 return Raw_802_15_4;
hbujanda 5:da2ea7a76243 756 }
spastor 0:fcaad0dfa051 757 #ifdef EXTRA_XBEE_PROTOCOLS
spastor 0:fcaad0dfa051 758 if (fw_4_bytes_len && fw_nibble_3 == 5) {
spastor 0:fcaad0dfa051 759 return SmartEnergy;
spastor 0:fcaad0dfa051 760 }
spastor 0:fcaad0dfa051 761 return ZigBee;
spastor 0:fcaad0dfa051 762 #else
spastor 0:fcaad0dfa051 763 if (!(fw_4_bytes_len && fw_nibble_3 == 5)) {
spastor 0:fcaad0dfa051 764 return ZigBee;
spastor 0:fcaad0dfa051 765 }
spastor 0:fcaad0dfa051 766 #endif
spastor 0:fcaad0dfa051 767 #ifdef EXTRA_XBEE_PROTOCOLS
spastor 0:fcaad0dfa051 768 } else if (hw_version_msb == XSC_GEN3 || hw_version_msb == SRD_868_GEN3) {
spastor 0:fcaad0dfa051 769 if (fw_4_bytes_len && fw_nibble_3 == 8) {
spastor 0:fcaad0dfa051 770 return DigiMesh;
spastor 0:fcaad0dfa051 771 } else if (fw_4_bytes_len && fw_nibble_3 == 1) {
spastor 0:fcaad0dfa051 772 return DigiPoint;
spastor 0:fcaad0dfa051 773 }
spastor 0:fcaad0dfa051 774 return None;
spastor 0:fcaad0dfa051 775 } else if (hw_version_msb == XBEE_CELL_TH) {
spastor 0:fcaad0dfa051 776 return None;
spastor 0:fcaad0dfa051 777 } else if (hw_version_msb == XLR_MODULE) {
spastor 0:fcaad0dfa051 778 return None;
spastor 0:fcaad0dfa051 779 } else if (hw_version_msb == XLR_BASEBOARD) {
spastor 0:fcaad0dfa051 780 return None;
spastor 0:fcaad0dfa051 781 } else if (hw_version_msb == XB900HP_NZ) {
spastor 0:fcaad0dfa051 782 return DigiPoint;
hbujanda 5:da2ea7a76243 783 } else if (hw_version_msb == XBP24C_TH_DIP || hw_version_msb == XB24C_TH_DIP || hw_version_msb == XBP24C_S2C_SMT) {
hbujanda 6:06522f3a6642 784 if (fw_4_bytes_len && fw_nibble_3 == 9) {
hbujanda 6:06522f3a6642 785 return DigiMesh;
hbujanda 6:06522f3a6642 786 }
hbujanda 5:da2ea7a76243 787 if (fw_4_bytes_len && fw_nibble_3 == 5) {
hbujanda 5:da2ea7a76243 788 return SmartEnergy;
hbujanda 5:da2ea7a76243 789 }
hbujanda 5:da2ea7a76243 790 if (fw_4_bytes_len && fw_nibble_3 == 2) {
hbujanda 5:da2ea7a76243 791 return Raw_802_15_4;
hbujanda 5:da2ea7a76243 792 }
hbujanda 5:da2ea7a76243 793 return ZigBee;
spastor 0:fcaad0dfa051 794 }
spastor 0:fcaad0dfa051 795 #else
spastor 0:fcaad0dfa051 796 }
spastor 0:fcaad0dfa051 797 #endif
spastor 0:fcaad0dfa051 798
spastor 0:fcaad0dfa051 799 return None;
spastor 0:fcaad0dfa051 800 }
spastor 0:fcaad0dfa051 801
spastor 0:fcaad0dfa051 802 #define TX_STATUS_OFFSET_ZB 4
spastor 0:fcaad0dfa051 803 #define TX_STATUS_OFFSET_802 1
spastor 0:fcaad0dfa051 804
spastor 0:fcaad0dfa051 805 TxStatus XBee::send_data(ApiFrame *frame)
spastor 0:fcaad0dfa051 806 {
spastor 0:fcaad0dfa051 807 TxStatus resp = TxStatusTimeout;
spastor 0:fcaad0dfa051 808 ApiFrame *resp_frame;
spastor 0:fcaad0dfa051 809
spastor 0:fcaad0dfa051 810 send_api_frame(frame);
spastor 0:fcaad0dfa051 811
spastor 4:629712865107 812 /* Wait for the transmit status response packet */
spastor 4:629712865107 813 resp_frame = get_this_api_frame(frame->get_frame_id(),
hbujanda 6:06522f3a6642 814 ApiFrame::TxStatusZBDM, ApiFrame::TxStatus);
spastor 4:629712865107 815 if (resp_frame == NULL) {
spastor 0:fcaad0dfa051 816 return resp;
spastor 4:629712865107 817 }
spastor 4:629712865107 818
hbujanda 6:06522f3a6642 819 uint8_t index = resp_frame->get_frame_type() == ApiFrame::TxStatusZBDM ?
spastor 0:fcaad0dfa051 820 TX_STATUS_OFFSET_ZB : TX_STATUS_OFFSET_802;
spastor 4:629712865107 821
spastor 0:fcaad0dfa051 822 resp = (TxStatus)resp_frame->get_data_at(index);
spastor 4:629712865107 823
spastor 0:fcaad0dfa051 824 /* Once processed, remove the frame from the buffer */
spastor 4:629712865107 825 _framebuf_syncr.free_frame(resp_frame);
spastor 4:629712865107 826
spastor 0:fcaad0dfa051 827 return resp;
spastor 0:fcaad0dfa051 828 }
spastor 0:fcaad0dfa051 829
spastor 3:8662ebe83570 830 TxStatus XBee::send_data_broadcast(const uint8_t *const data, uint16_t len, bool syncr)
spastor 0:fcaad0dfa051 831 {
spastor 0:fcaad0dfa051 832 const RemoteXBee remoteDevice = RemoteXBee(ADDR64_BROADCAST);
spastor 3:8662ebe83570 833 return send_data(remoteDevice, data, len, syncr);
spastor 0:fcaad0dfa051 834 }
spastor 0:fcaad0dfa051 835
spastor 4:629712865107 836 uint32_t XBee::process_rx_frames()
spastor 0:fcaad0dfa051 837 {
spastor 0:fcaad0dfa051 838 ApiFrame *frame = NULL;
spastor 0:fcaad0dfa051 839
spastor 4:629712865107 840 while ((frame = _framebuf_app.get_next_complete_frame()) != NULL) {
spastor 0:fcaad0dfa051 841 for (int i = 0; i < MAX_FRAME_HANDLERS; i++) {
spastor 0:fcaad0dfa051 842
spastor 0:fcaad0dfa051 843 if (_fhandlers[i] == NULL) {
spastor 0:fcaad0dfa051 844 /* No more handlers, break here */
spastor 0:fcaad0dfa051 845 break;
spastor 0:fcaad0dfa051 846 }
spastor 0:fcaad0dfa051 847
spastor 0:fcaad0dfa051 848 /* Check if frame and handler match, if not... go for the next one */
spastor 0:fcaad0dfa051 849 if (frame->get_frame_type() != _fhandlers[i]->get_type()) {
spastor 0:fcaad0dfa051 850 continue;
spastor 0:fcaad0dfa051 851 }
spastor 0:fcaad0dfa051 852
spastor 0:fcaad0dfa051 853 _fhandlers[i]->process_frame_data(frame);
spastor 0:fcaad0dfa051 854 }
spastor 4:629712865107 855
spastor 0:fcaad0dfa051 856 /* Once processed, remove the frame from the buffer */
spastor 4:629712865107 857 _framebuf_app.free_frame(frame);
spastor 4:629712865107 858 }
spastor 0:fcaad0dfa051 859
spastor 4:629712865107 860 const uint32_t dropped_frames = _framebuf_app.get_dropped_frames_count();
spastor 4:629712865107 861 if (dropped_frames != 0) {
spastor 4:629712865107 862 digi_log(LogLevelWarning, "process_rx_frames: %d frames dropped!!!\r\n", dropped_frames);
spastor 4:629712865107 863 }
spastor 4:629712865107 864
spastor 4:629712865107 865 return dropped_frames;
spastor 0:fcaad0dfa051 866 }
spastor 0:fcaad0dfa051 867
spastor 0:fcaad0dfa051 868 void XBee::register_modem_status_cb(modem_status_cb_t function)
spastor 0:fcaad0dfa051 869 {
spastor 0:fcaad0dfa051 870 if (_modem_status_handler == NULL) {
spastor 0:fcaad0dfa051 871 _modem_status_handler = new FH_ModemStatus();
spastor 0:fcaad0dfa051 872 register_frame_handler(_modem_status_handler);
spastor 0:fcaad0dfa051 873 }
spastor 0:fcaad0dfa051 874 _modem_status_handler->register_modem_status_cb(function);
spastor 0:fcaad0dfa051 875 }
spastor 0:fcaad0dfa051 876
spastor 0:fcaad0dfa051 877 void XBee::unregister_modem_status_cb()
spastor 0:fcaad0dfa051 878 {
spastor 0:fcaad0dfa051 879 if (_modem_status_handler != NULL) {
spastor 0:fcaad0dfa051 880 _modem_status_handler->unregister_modem_status_cb();
spastor 0:fcaad0dfa051 881 unregister_frame_handler(_modem_status_handler);
spastor 0:fcaad0dfa051 882 delete _modem_status_handler;
spastor 0:fcaad0dfa051 883 _modem_status_handler = NULL; /* as delete does not set to NULL */
spastor 0:fcaad0dfa051 884 }
spastor 0:fcaad0dfa051 885 }
spastor 0:fcaad0dfa051 886
spastor 4:629712865107 887 int XBee::get_AI(void)
spastor 4:629712865107 888 {
spastor 4:629712865107 889 uint32_t atai;
spastor 4:629712865107 890 const AtCmdFrame::AtCmdResp status = get_param("AI", &atai);
spastor 4:629712865107 891
spastor 4:629712865107 892 if (status != AtCmdFrame::AtCmdRespOk) {
spastor 4:629712865107 893 digi_log(LogLevelError, "get_association_indication() failed with %d\r\n", status);
spastor 4:629712865107 894 return -1;
spastor 4:629712865107 895 }
spastor 4:629712865107 896 return atai;
spastor 4:629712865107 897 }