Renan Alves / XBeeLib

Dependents:   Navitec-Firmware

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RadioConfig.cpp Source File

RadioConfig.cpp

00001 /**
00002  * Copyright (c) 2015 Digi International Inc.,
00003  * All rights not expressly granted are reserved.
00004  *
00005  * This Source Code Form is subject to the terms of the Mozilla Public
00006  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
00007  * You can obtain one at http://mozilla.org/MPL/2.0/.
00008  *
00009  * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
00010  * =======================================================================
00011  */
00012 
00013 #include "XBeeLib.h"
00014 #include "Frames/ApiFrame.h"
00015 
00016 using namespace XBeeLib;
00017 
00018 RadioStatus XBee::write_config(void)
00019 {
00020     AtCmdFrame::AtCmdResp cmdresp;
00021 
00022     cmdresp = set_param("WR");
00023     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00024         return Failure;
00025     }
00026     return Success;
00027 }
00028 
00029 RadioStatus XBee::set_power_level(uint8_t  level)
00030 {
00031     AtCmdFrame::AtCmdResp cmdresp;
00032 
00033     if (level > 4) {
00034         return Failure;
00035     }
00036 
00037     cmdresp = set_param("PL", level);
00038     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00039         return Failure;
00040     }
00041 
00042     return Success;
00043 }
00044 
00045 RadioStatus XBee::get_power_level(uint8_t * const  level)
00046 {
00047     if (level == NULL) {
00048         return Failure;
00049     }
00050     AtCmdFrame::AtCmdResp cmdresp;
00051 
00052     uint32_t var32;
00053     cmdresp = get_param("PL", &var32);
00054     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00055         return Failure;
00056     }
00057     *level = var32;
00058     return Success;
00059 }
00060 
00061 RadioStatus XBee::software_reset(void)
00062 {
00063     volatile uint16_t * const rst_cnt_p = &_wd_reset_cnt;
00064     const uint16_t init_rst_cnt = *rst_cnt_p;
00065 
00066     AtCmdFrame::AtCmdResp cmdresp;
00067 
00068     cmdresp = set_param("FR");
00069     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00070         digi_log(LogLevelError, "software_reset failed!\r\n");
00071         return Failure;
00072     }
00073 
00074     return wait_for_module_to_reset(rst_cnt_p, init_rst_cnt);
00075 }
00076 
00077 RadioStatus XBee::set_node_identifier(const char * const node_id)
00078 {
00079     if (node_id == NULL) {
00080         return Failure;
00081     }
00082 
00083     AtCmdFrame::AtCmdResp cmdresp;
00084     const size_t str_len = strlen(node_id);
00085 
00086     if(str_len > 20 || str_len < 1) {
00087         return Failure;
00088     }
00089 
00090     cmdresp = set_param("NI", (const uint8_t *)node_id, str_len);
00091     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00092         return Failure;
00093     }
00094     return Success;
00095 }
00096 
00097 RadioStatus XBee::get_node_identifier(char * const node_id)
00098 {
00099     if (node_id == NULL) {
00100         return Failure;
00101     }
00102 
00103     uint16_t max_ni_length = 20;
00104     AtCmdFrame::AtCmdResp cmdresp;
00105 
00106     cmdresp = get_param("NI", (uint8_t *)node_id, &max_ni_length);
00107     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00108         return Failure;
00109     }
00110     node_id[max_ni_length] = '\0';
00111     return Success;
00112 }
00113 
00114 RadioStatus XBee::enable_network_encryption(bool enable)
00115 {
00116     AtCmdFrame::AtCmdResp cmdresp;
00117 
00118     cmdresp = set_param("EE", enable);
00119     return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
00120 }
00121 
00122 RadioStatus XBee::set_network_encryption_key(const uint8_t * const key, const uint16_t length)
00123 {
00124     if (key == NULL || length == 0 || length > 16) {
00125         return Failure;
00126     }
00127     AtCmdFrame::AtCmdResp cmdresp;
00128 
00129     cmdresp = set_param("KY", key, length);
00130     return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
00131 }
00132 
00133 uint16_t XBee::get_hw_version() const
00134 {
00135     return _hw_version;
00136 }
00137 
00138 uint16_t XBee::get_fw_version() const
00139 {
00140     return _fw_version;
00141 }
00142 
00143 void XBee::set_tx_options(uint8_t options)
00144 {
00145     _tx_options = options;
00146 }
00147 
00148 uint8_t XBee::get_tx_options() const
00149 {
00150     return _tx_options;
00151 }
00152 
00153 RadioStatus XBee::start_node_discovery()
00154 {
00155     RadioStatus status;
00156     uint16_t nd_timeout;
00157 
00158     status = get_node_discovery_timeout(&nd_timeout);
00159     if (status != Success) {
00160         return status;
00161     }
00162 
00163     _nd_timeout = nd_timeout;
00164 
00165     _nd_timer.start();
00166 
00167     AtCmdFrame cmd_frame = AtCmdFrame("ND");
00168     send_api_frame(&cmd_frame);
00169 
00170     return Success;
00171 }
00172 
00173 bool XBee::is_node_discovery_in_progress()
00174 {
00175     const int nd_timer = _nd_timer.read_ms();
00176 
00177     if (nd_timer == 0)
00178         return false;
00179 
00180     if (nd_timer > _nd_timeout) {
00181         _nd_timer.stop();
00182         _nd_timer.reset();
00183     }
00184 
00185     return true;
00186 }
00187 
00188 void XBee::_get_remote_node_by_id(const char * const node_id, uint64_t * const addr64, uint16_t * const addr16)
00189 {
00190     *addr64 = ADDR64_UNASSIGNED;
00191     *addr16 = ADDR16_UNKNOWN;
00192     if (node_id == NULL) {
00193         return;
00194     }
00195     const size_t node_id_len = strlen(node_id);
00196     if (node_id_len == 0 || node_id_len > MAX_NI_PARAM_LEN) {
00197         return;
00198     }
00199 
00200     const uint16_t old_timeout = _timeout_ms;
00201 
00202     RadioStatus status;
00203     uint16_t nd_timeout;
00204     bool wait_for_complete_timeout;
00205 
00206     status = get_node_discovery_timeout(&nd_timeout, &wait_for_complete_timeout);
00207     if (status != Success) {
00208         return;
00209     }
00210     _timeout_ms = nd_timeout;
00211 
00212     Timer nd_timer = Timer();
00213 
00214     nd_timer.start();
00215 
00216     AtCmdFrame atnd_frame = AtCmdFrame("ND", (const uint8_t *)node_id, strlen(node_id));
00217     const uint8_t frame_id = atnd_frame.get_frame_id();
00218     _node_by_ni_frame_id = frame_id;
00219     send_api_frame(&atnd_frame);
00220 
00221     ApiFrame * const resp_frame = get_this_api_frame(frame_id, ApiFrame::AtCmdResp);
00222     _timeout_ms = old_timeout;
00223 
00224     _node_by_ni_frame_id = 0;
00225 
00226     if (resp_frame == NULL) {
00227         digi_log(LogLevelWarning, "_get_remote_node_by_id: timeout when waiting for ATND response");
00228         return;
00229     }
00230 
00231     if (resp_frame->get_data_len() < sizeof (uint16_t) + sizeof (uint64_t)) {
00232         /* In 802.15.4 this might be the OK or Timeout message with no information */
00233         digi_log(LogLevelInfo, "_get_remote_node_by_id: node not found\r\n", __FUNCTION__, node_id);
00234         _framebuf_syncr.free_frame(resp_frame);
00235         return;
00236     }
00237 
00238     const AtCmdFrame::AtCmdResp resp = (AtCmdFrame::AtCmdResp)resp_frame->get_data_at(ATCMD_RESP_STATUS_OFFSET);
00239     if (resp != AtCmdFrame::AtCmdRespOk) {
00240         digi_log(LogLevelWarning, "_get_remote_node_by_id: send_at_cmd bad response: 0x%x\r\n", resp);
00241         _framebuf_syncr.free_frame(resp_frame);
00242         return;
00243     }
00244 
00245     rmemcpy((uint8_t *)addr16, resp_frame->get_data() + ATCMD_RESP_DATA_OFFSET, sizeof *addr16);
00246     rmemcpy((uint8_t *)addr64, resp_frame->get_data() + ATCMD_RESP_DATA_OFFSET + sizeof *addr16, sizeof *addr64);
00247     _framebuf_syncr.free_frame(resp_frame);
00248 
00249     if (wait_for_complete_timeout) {
00250         while (nd_timer.read_ms() < nd_timeout) {
00251             //wait_ms(10);
00252             ThisThread::sleep_for(chrono::milliseconds(10));
00253         }
00254     }
00255 
00256     return;
00257 }
00258 
00259 RadioStatus XBee::config_node_discovery(uint16_t backoff_ms, uint8_t options)
00260 {
00261     AtCmdFrame::AtCmdResp cmdresp;
00262 
00263     cmdresp = set_param("NT", (uint8_t)(backoff_ms / 100));
00264     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00265         return Failure;
00266     }
00267 
00268     cmdresp = set_param("NO", (uint8_t)options);
00269     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00270         return Failure;
00271     }
00272     cmdresp = set_param("AC");
00273     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00274         return Failure;
00275     }
00276 
00277     return Success;
00278 }
00279 
00280 RadioStatus XBee::get_config_node_discovery(uint16_t * const backoff_ms, uint8_t * const options)
00281 {
00282     AtCmdFrame::AtCmdResp cmdresp;
00283     uint32_t var32;
00284 
00285     cmdresp = get_param("NT", &var32);
00286     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00287         return Failure;
00288     }
00289     *backoff_ms = var32;
00290 
00291     cmdresp = get_param("NO", &var32);
00292     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00293         return Failure;
00294     }
00295     *options = var32;
00296     return Success;
00297 }
00298 
00299 RadioStatus XBee::_get_iosample(const RemoteXBee& remote, uint8_t * const io_sample, uint16_t * const len)
00300 {
00301     AtCmdFrame::AtCmdResp cmdresp;
00302 
00303     /* Force a sample read */
00304     cmdresp = get_param(remote, "IS", io_sample, len);
00305     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00306         digi_log(LogLevelError, "_get_iosample error %d:\r\n", cmdresp);
00307         return Failure;
00308     }
00309 
00310     return Success;
00311 }
00312 
00313 RadioStatus XBee::config_io_sample_destination(const RemoteXBee& remote, const RemoteXBee& destination)
00314 {
00315     uint32_t dh;
00316     uint32_t dl;
00317 
00318     if (destination.is_valid_addr64b()) {
00319         const uint64_t dest64 = destination.get_addr64();
00320         dh = (uint32_t)((dest64 >> 32) & 0xFFFFFFFF);
00321         dl = (uint32_t)((dest64 & 0xFFFFFFFF));
00322     } else if (destination.is_valid_addr16b()) {
00323         const uint16_t destAddr16 = destination.get_addr16();
00324         dh = 0;
00325         dl = destAddr16;
00326     } else {
00327         digi_log(LogLevelError, "send_io_sample_to: Invalid destination");
00328         return Failure;
00329     }
00330 
00331     AtCmdFrame::AtCmdResp cmdresp;
00332 
00333     cmdresp = set_param(remote, "DH", dh);
00334     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00335         digi_log(LogLevelError, "send_io_sample_to error %d:\r\n", cmdresp);
00336         return Failure;
00337     }
00338 
00339     cmdresp = set_param(remote, "DL", dl);
00340     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00341         digi_log(LogLevelError, "send_io_sample_to error %d:\r\n", cmdresp);
00342         return Failure;
00343     }
00344 
00345     return Success;
00346 }
00347 
00348 RadioStatus XBee::set_io_sample_rate(const RemoteXBee& remote, const float seconds)
00349 {
00350     const float max_seconds = 65.535;
00351 
00352     if (seconds > max_seconds) {
00353         digi_log(LogLevelError, "XBee::set_io_sample_rate error seconds rate exceeds maximum %d:\r\n", max_seconds);
00354         return Failure;
00355     }
00356 
00357     AtCmdFrame::AtCmdResp cmdresp;
00358     const uint16_t milliseconds = seconds * 1000;
00359 
00360     cmdresp = set_param(remote, "IR", milliseconds);
00361     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00362         digi_log(LogLevelError, "XBee::set_io_sample_rate error %d:\r\n", cmdresp);
00363         return Failure;
00364     }
00365 
00366     return Success;
00367 }