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.
Fork of XBeeLib by
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 } 00253 } 00254 00255 return; 00256 } 00257 00258 RadioStatus XBee::config_node_discovery(uint16_t backoff_ms, uint8_t options) 00259 { 00260 AtCmdFrame::AtCmdResp cmdresp; 00261 00262 cmdresp = set_param("NT", (uint8_t)(backoff_ms / 100)); 00263 if (cmdresp != AtCmdFrame::AtCmdRespOk) { 00264 return Failure; 00265 } 00266 00267 cmdresp = set_param("NO", (uint8_t)options); 00268 if (cmdresp != AtCmdFrame::AtCmdRespOk) { 00269 return Failure; 00270 } 00271 cmdresp = set_param("AC"); 00272 if (cmdresp != AtCmdFrame::AtCmdRespOk) { 00273 return Failure; 00274 } 00275 00276 return Success; 00277 } 00278 00279 RadioStatus XBee::get_config_node_discovery(uint16_t * const backoff_ms, uint8_t * const options) 00280 { 00281 AtCmdFrame::AtCmdResp cmdresp; 00282 uint32_t var32; 00283 00284 cmdresp = get_param("NT", &var32); 00285 if (cmdresp != AtCmdFrame::AtCmdRespOk) { 00286 return Failure; 00287 } 00288 *backoff_ms = var32; 00289 00290 cmdresp = get_param("NO", &var32); 00291 if (cmdresp != AtCmdFrame::AtCmdRespOk) { 00292 return Failure; 00293 } 00294 *options = var32; 00295 return Success; 00296 } 00297 00298 RadioStatus XBee::_get_iosample(const RemoteXBee& remote, uint8_t * const io_sample, uint16_t * const len) 00299 { 00300 AtCmdFrame::AtCmdResp cmdresp; 00301 00302 /* Force a sample read */ 00303 cmdresp = get_param(remote, "IS", io_sample, len); 00304 if (cmdresp != AtCmdFrame::AtCmdRespOk) { 00305 digi_log(LogLevelError, "_get_iosample error %d:\r\n", cmdresp); 00306 return Failure; 00307 } 00308 00309 return Success; 00310 } 00311 00312 RadioStatus XBee::config_io_sample_destination(const RemoteXBee& remote, const RemoteXBee& destination) 00313 { 00314 uint32_t dh; 00315 uint32_t dl; 00316 00317 if (destination.is_valid_addr64b()) { 00318 const uint64_t dest64 = destination.get_addr64(); 00319 dh = (uint32_t)((dest64 >> 32) & 0xFFFFFFFF); 00320 dl = (uint32_t)((dest64 & 0xFFFFFFFF)); 00321 } else if (destination.is_valid_addr16b()) { 00322 const uint16_t destAddr16 = destination.get_addr16(); 00323 dh = 0; 00324 dl = destAddr16; 00325 } else { 00326 digi_log(LogLevelError, "send_io_sample_to: Invalid destination"); 00327 return Failure; 00328 } 00329 00330 AtCmdFrame::AtCmdResp cmdresp; 00331 00332 cmdresp = set_param(remote, "DH", dh); 00333 if (cmdresp != AtCmdFrame::AtCmdRespOk) { 00334 digi_log(LogLevelError, "send_io_sample_to error %d:\r\n", cmdresp); 00335 return Failure; 00336 } 00337 00338 cmdresp = set_param(remote, "DL", dl); 00339 if (cmdresp != AtCmdFrame::AtCmdRespOk) { 00340 digi_log(LogLevelError, "send_io_sample_to error %d:\r\n", cmdresp); 00341 return Failure; 00342 } 00343 00344 return Success; 00345 } 00346 00347 RadioStatus XBee::set_io_sample_rate(const RemoteXBee& remote, const float seconds) 00348 { 00349 const float max_seconds = 65.535; 00350 00351 if (seconds > max_seconds) { 00352 digi_log(LogLevelError, "XBee::set_io_sample_rate error seconds rate exceeds maximum %d:\r\n", max_seconds); 00353 return Failure; 00354 } 00355 00356 AtCmdFrame::AtCmdResp cmdresp; 00357 const uint16_t milliseconds = seconds * 1000; 00358 00359 cmdresp = set_param(remote, "IR", milliseconds); 00360 if (cmdresp != AtCmdFrame::AtCmdRespOk) { 00361 digi_log(LogLevelError, "XBee::set_io_sample_rate error %d:\r\n", cmdresp); 00362 return Failure; 00363 } 00364 00365 return Success; 00366 }
Generated on Tue Jul 12 2022 20:40:23 by
