Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 }
Generated on Thu Jul 14 2022 04:53:34 by
