Lorenzo Maiorfi / XBeeLib_Fixed

Dependents:   XBeeZB_Receive_Data

Fork of XBeeLib by Digi International Inc.

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* pnd_timer = new Timer();
00213 
00214     pnd_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         delete pnd_timer;
00229         return;
00230     }
00231 
00232     if (resp_frame->get_data_len() < sizeof (uint16_t) + sizeof (uint64_t)) {
00233         /* In 802.15.4 this might be the OK or Timeout message with no information */
00234         digi_log(LogLevelInfo, "_get_remote_node_by_id: node not found\r\n", __FUNCTION__, node_id);
00235         _framebuf_syncr.free_frame(resp_frame);
00236         delete pnd_timer;
00237         return;
00238     }
00239 
00240     const AtCmdFrame::AtCmdResp resp = (AtCmdFrame::AtCmdResp)resp_frame->get_data_at(ATCMD_RESP_STATUS_OFFSET);
00241     if (resp != AtCmdFrame::AtCmdRespOk) {
00242         digi_log(LogLevelWarning, "_get_remote_node_by_id: send_at_cmd bad response: 0x%x\r\n", resp);
00243         _framebuf_syncr.free_frame(resp_frame);
00244         delete pnd_timer;
00245         return;
00246     }
00247 
00248     rmemcpy((uint8_t *)addr16, resp_frame->get_data() + ATCMD_RESP_DATA_OFFSET, sizeof *addr16);
00249     rmemcpy((uint8_t *)addr64, resp_frame->get_data() + ATCMD_RESP_DATA_OFFSET + sizeof *addr16, sizeof *addr64);
00250     _framebuf_syncr.free_frame(resp_frame);
00251 
00252     if (wait_for_complete_timeout) {
00253         while (pnd_timer->read_ms() < nd_timeout) {
00254             wait_ms(10);
00255         }
00256     }
00257 
00258     delete pnd_timer;
00259     return;
00260 }
00261 
00262 RadioStatus XBee::config_node_discovery(uint16_t backoff_ms, uint8_t options)
00263 {
00264     AtCmdFrame::AtCmdResp cmdresp;
00265 
00266     cmdresp = set_param("NT", (uint8_t)(backoff_ms / 100));
00267     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00268         return Failure;
00269     }
00270 
00271     cmdresp = set_param("NO", (uint8_t)options);
00272     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00273         return Failure;
00274     }
00275     cmdresp = set_param("AC");
00276     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00277         return Failure;
00278     }
00279 
00280     return Success;
00281 }
00282 
00283 RadioStatus XBee::get_config_node_discovery(uint16_t * const backoff_ms, uint8_t * const options)
00284 {
00285     AtCmdFrame::AtCmdResp cmdresp;
00286     uint32_t var32;
00287 
00288     cmdresp = get_param("NT", &var32);
00289     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00290         return Failure;
00291     }
00292     *backoff_ms = var32;
00293 
00294     cmdresp = get_param("NO", &var32);
00295     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00296         return Failure;
00297     }
00298     *options = var32;
00299     return Success;
00300 }
00301 
00302 RadioStatus XBee::_get_iosample(const RemoteXBee& remote, uint8_t * const io_sample, uint16_t * const len)
00303 {
00304     AtCmdFrame::AtCmdResp cmdresp;
00305 
00306     /* Force a sample read */
00307     cmdresp = get_param(remote, "IS", io_sample, len);
00308     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00309         digi_log(LogLevelError, "_get_iosample error %d:\r\n", cmdresp);
00310         return Failure;
00311     }
00312 
00313     return Success;
00314 }
00315 
00316 RadioStatus XBee::config_io_sample_destination(const RemoteXBee& remote, const RemoteXBee& destination)
00317 {
00318     uint32_t dh;
00319     uint32_t dl;
00320 
00321     if (destination.is_valid_addr64b()) {
00322         const uint64_t dest64 = destination.get_addr64();
00323         dh = (uint32_t)((dest64 >> 32) & 0xFFFFFFFF);
00324         dl = (uint32_t)((dest64 & 0xFFFFFFFF));
00325     } else if (destination.is_valid_addr16b()) {
00326         const uint16_t destAddr16 = destination.get_addr16();
00327         dh = 0;
00328         dl = destAddr16;
00329     } else {
00330         digi_log(LogLevelError, "send_io_sample_to: Invalid destination");
00331         return Failure;
00332     }
00333 
00334     AtCmdFrame::AtCmdResp cmdresp;
00335 
00336     cmdresp = set_param(remote, "DH", dh);
00337     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00338         digi_log(LogLevelError, "send_io_sample_to error %d:\r\n", cmdresp);
00339         return Failure;
00340     }
00341 
00342     cmdresp = set_param(remote, "DL", dl);
00343     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00344         digi_log(LogLevelError, "send_io_sample_to error %d:\r\n", cmdresp);
00345         return Failure;
00346     }
00347 
00348     return Success;
00349 }
00350 
00351 RadioStatus XBee::set_io_sample_rate(const RemoteXBee& remote, const float seconds)
00352 {
00353     const float max_seconds = 65.535;
00354 
00355     if (seconds > max_seconds) {
00356         digi_log(LogLevelError, "XBee::set_io_sample_rate error seconds rate exceeds maximum %d:\r\n", max_seconds);
00357         return Failure;
00358     }
00359 
00360     AtCmdFrame::AtCmdResp cmdresp;
00361     const uint16_t milliseconds = seconds * 1000;
00362 
00363     cmdresp = set_param(remote, "IR", milliseconds);
00364     if (cmdresp != AtCmdFrame::AtCmdRespOk) {
00365         digi_log(LogLevelError, "XBee::set_io_sample_rate error %d:\r\n", cmdresp);
00366         return Failure;
00367     }
00368 
00369     return Success;
00370 }