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.
LoRaPHY.cpp
00001 /** 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2013 Semtech 00008 ___ _____ _ ___ _ _____ ___ ___ ___ ___ 00009 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 00010 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 00011 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 00012 embedded.connectivity.solutions=============== 00013 00014 License: Revised BSD License, see LICENSE.TXT file include in the project 00015 00016 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) 00017 00018 00019 Copyright (c) 2017, Arm Limited and affiliates. 00020 00021 SPDX-License-Identifier: BSD-3-Clause 00022 */ 00023 00024 #include <stdbool.h> 00025 #include <stdlib.h> 00026 #include <string.h> 00027 #include <stdint.h> 00028 #include <math.h> 00029 00030 #include "LoRaPHY.h" 00031 00032 #define BACKOFF_DC_1_HOUR 100 00033 #define BACKOFF_DC_10_HOURS 1000 00034 #define BACKOFF_DC_24_HOURS 10000 00035 00036 #define CHANNELS_IN_MASK 16 00037 00038 LoRaPHY::LoRaPHY(LoRaWANTimeHandler &lora_time) 00039 : _radio(NULL), 00040 _lora_time(lora_time) 00041 { 00042 memset(&phy_params, 0, sizeof(phy_params)); 00043 } 00044 00045 LoRaPHY::~LoRaPHY() 00046 { 00047 _radio = NULL; 00048 } 00049 00050 bool LoRaPHY::mask_bit_test(const uint16_t *mask, unsigned bit) 00051 { 00052 return mask[bit / 16] & (1U << (bit % 16)); 00053 } 00054 00055 void LoRaPHY::mask_bit_set(uint16_t *mask, unsigned bit) 00056 { 00057 mask[bit / 16] |= (1U << (bit % 16)); 00058 } 00059 00060 void LoRaPHY::mask_bit_clear(uint16_t *mask, unsigned bit) 00061 { 00062 mask[bit / 16] &= ~(1U << (bit % 16)); 00063 } 00064 00065 void LoRaPHY::set_radio_instance(LoRaRadio &radio) 00066 { 00067 _radio = &radio; 00068 } 00069 00070 void LoRaPHY::put_radio_to_sleep() 00071 { 00072 _radio->lock(); 00073 _radio->sleep(); 00074 _radio->unlock(); 00075 } 00076 00077 void LoRaPHY::put_radio_to_standby() 00078 { 00079 _radio->lock(); 00080 _radio->standby(); 00081 _radio->unlock(); 00082 } 00083 00084 void LoRaPHY::setup_public_network_mode(bool set) 00085 { 00086 _radio->lock(); 00087 _radio->set_public_network(set); 00088 _radio->unlock(); 00089 } 00090 00091 void LoRaPHY::setup_rx_window(bool rx_continuous, uint32_t max_rx_window) 00092 { 00093 _radio->lock(); 00094 if (!rx_continuous) { 00095 _radio->receive(max_rx_window); 00096 } else { 00097 _radio->receive(0); // Continuous mode 00098 } 00099 _radio->unlock(); 00100 } 00101 00102 // For DevNonce for example 00103 uint32_t LoRaPHY::get_radio_rng() 00104 { 00105 uint32_t rand; 00106 00107 _radio->lock(); 00108 rand = _radio->random(); 00109 _radio->unlock(); 00110 00111 return rand; 00112 } 00113 00114 void LoRaPHY::handle_send(uint8_t *buf, uint8_t size) 00115 { 00116 _radio->lock(); 00117 _radio->send(buf, size); 00118 _radio->unlock(); 00119 } 00120 00121 uint8_t LoRaPHY::request_new_channel(int8_t channel_id, channel_params_t *new_channel) 00122 { 00123 if (!phy_params.custom_channelplans_supported) { 00124 return 0; 00125 } 00126 00127 uint8_t status = 0x03; 00128 00129 if (new_channel->frequency == 0) { 00130 // Remove 00131 if (remove_channel(channel_id) == false) { 00132 status &= 0xFC; 00133 } 00134 } else { 00135 new_channel->band = lookup_band_for_frequency(new_channel->frequency); 00136 switch (add_channel(new_channel, channel_id)) { 00137 case LORAWAN_STATUS_OK: { 00138 break; 00139 } 00140 case LORAWAN_STATUS_FREQUENCY_INVALID: { 00141 status &= 0xFE; 00142 break; 00143 } 00144 case LORAWAN_STATUS_DATARATE_INVALID: { 00145 status &= 0xFD; 00146 break; 00147 } 00148 case LORAWAN_STATUS_FREQ_AND_DR_INVALID: { 00149 status &= 0xFC; 00150 break; 00151 } 00152 default: { 00153 status &= 0xFC; 00154 break; 00155 } 00156 } 00157 } 00158 00159 return status; 00160 } 00161 00162 int32_t LoRaPHY::get_random(int32_t min, int32_t max) 00163 { 00164 return (int32_t) rand() % (max - min + 1) + min; 00165 } 00166 00167 bool LoRaPHY::verify_channel_DR(uint8_t nb_channels, uint16_t *channel_mask, 00168 int8_t dr, int8_t min_dr, int8_t max_dr, 00169 channel_params_t *channels) 00170 { 00171 if (val_in_range(dr, min_dr, max_dr) == 0) { 00172 return false; 00173 } 00174 00175 for (uint8_t i = 0; i < phy_params.max_channel_cnt; i++) { 00176 if (mask_bit_test(channel_mask, i)) { 00177 // Check datarate validity for enabled channels 00178 if (val_in_range(dr, (channels[i].dr_range.fields.min & 0x0F), 00179 (channels[i].dr_range.fields.max & 0x0F))) { 00180 // At least 1 channel has been found we can return OK. 00181 return true; 00182 } 00183 } 00184 } 00185 00186 return false; 00187 } 00188 00189 bool LoRaPHY::val_in_range(int8_t value, int8_t min, int8_t max) 00190 { 00191 if ((value >= min) && (value <= max)) { 00192 return true; 00193 } 00194 00195 return false; 00196 } 00197 00198 bool LoRaPHY::disable_channel(uint16_t *channel_mask, uint8_t id, 00199 uint8_t max_channels_num) 00200 { 00201 uint8_t index = id / 16; 00202 00203 if ((index > phy_params.channels.mask_size) || (id >= max_channels_num)) { 00204 return false; 00205 } 00206 00207 // Deactivate channel 00208 mask_bit_clear(channel_mask, id); 00209 00210 return true; 00211 } 00212 00213 uint8_t LoRaPHY::count_bits(uint16_t mask, uint8_t nbBits) 00214 { 00215 uint8_t nbActiveBits = 0; 00216 00217 for (uint8_t j = 0; j < nbBits; j++) { 00218 if (mask_bit_test(&mask, j)) { 00219 nbActiveBits++; 00220 } 00221 } 00222 00223 return nbActiveBits; 00224 } 00225 00226 uint8_t LoRaPHY::num_active_channels(uint16_t *channel_mask, uint8_t start_idx, 00227 uint8_t stop_idx) 00228 { 00229 uint8_t nb_channels = 0; 00230 00231 if (channel_mask == NULL) { 00232 return 0; 00233 } 00234 00235 for (uint8_t i = start_idx; i < stop_idx; i++) { 00236 nb_channels += count_bits(channel_mask[i], 16); 00237 } 00238 00239 return nb_channels; 00240 } 00241 00242 void LoRaPHY::copy_channel_mask(uint16_t *dest_mask, uint16_t *src_mask, uint8_t len) 00243 { 00244 if ((dest_mask != NULL) && (src_mask != NULL)) { 00245 for (uint8_t i = 0; i < len; i++) { 00246 dest_mask[i] = src_mask[i]; 00247 } 00248 } 00249 } 00250 00251 void LoRaPHY::set_last_tx_done(uint8_t channel, bool joined, lorawan_time_t last_tx_done_time) 00252 { 00253 band_t *band_table = (band_t *) phy_params.bands.table; 00254 channel_params_t *channel_list = phy_params.channels.channel_list; 00255 00256 if (joined == true) { 00257 band_table[channel_list[channel].band].last_tx_time = last_tx_done_time; 00258 return; 00259 } 00260 00261 band_table[channel_list[channel].band].last_tx_time = last_tx_done_time; 00262 band_table[channel_list[channel].band].last_join_tx_time = last_tx_done_time; 00263 00264 } 00265 00266 lorawan_time_t LoRaPHY::update_band_timeoff(bool joined, bool duty_cycle, 00267 band_t *bands, uint8_t nb_bands) 00268 { 00269 lorawan_time_t next_tx_delay = (lorawan_time_t)(-1); 00270 00271 // Update bands Time OFF 00272 for (uint8_t i = 0; i < nb_bands; i++) { 00273 00274 if (joined == false) { 00275 uint32_t txDoneTime = MAX(_lora_time.get_elapsed_time(bands[i].last_join_tx_time ), 00276 (duty_cycle == true) ? 00277 _lora_time.get_elapsed_time(bands[i].last_tx_time ) : 0); 00278 00279 if (bands[i].off_time <= txDoneTime) { 00280 bands[i].off_time = 0; 00281 } 00282 00283 if (bands[i].off_time != 0) { 00284 next_tx_delay = MIN(bands[i].off_time - txDoneTime, next_tx_delay); 00285 } 00286 00287 } else { 00288 // if network has been joined 00289 if (duty_cycle == true) { 00290 00291 if (bands[i].off_time <= _lora_time.get_elapsed_time(bands[i].last_tx_time )) { 00292 bands[i].off_time = 0; 00293 } 00294 00295 if (bands[i].off_time != 0) { 00296 next_tx_delay = MIN(bands[i].off_time - _lora_time.get_elapsed_time(bands[i].last_tx_time ), 00297 next_tx_delay); 00298 } 00299 } else { 00300 // if duty cycle is not on 00301 next_tx_delay = 0; 00302 bands[i].off_time = 0; 00303 } 00304 } 00305 } 00306 00307 return next_tx_delay; 00308 } 00309 00310 uint8_t LoRaPHY::parse_link_ADR_req(const uint8_t *payload, 00311 link_adr_params_t *params) 00312 { 00313 uint8_t ret_index = 0; 00314 00315 if (payload[0] == SRV_MAC_LINK_ADR_REQ ) { 00316 00317 // Parse datarate and tx power 00318 params->datarate = payload[1]; 00319 params->tx_power = params->datarate & 0x0F; 00320 params->datarate = (params->datarate >> 4) & 0x0F; 00321 00322 // Parse ChMask 00323 params->channel_mask = (uint16_t) payload[2]; 00324 params->channel_mask |= (uint16_t) payload[3] << 8; 00325 00326 // Parse ChMaskCtrl and nbRep 00327 params->nb_rep = payload[4]; 00328 params->ch_mask_ctrl = (params->nb_rep >> 4) & 0x07; 00329 params->nb_rep &= 0x0F; 00330 00331 // LinkAdrReq has 4 bytes length + 1 byte CMD 00332 ret_index = 5; 00333 } 00334 00335 return ret_index; 00336 } 00337 00338 uint8_t LoRaPHY::verify_link_ADR_req(verify_adr_params_t *verify_params, 00339 int8_t *dr, int8_t *tx_pow, uint8_t *nb_rep) 00340 { 00341 uint8_t status = verify_params->status ; 00342 int8_t datarate = verify_params->datarate ; 00343 int8_t tx_power = verify_params->tx_power ; 00344 int8_t nb_repetitions = verify_params->nb_rep ; 00345 00346 // Handle the case when ADR is off. 00347 if (verify_params->adr_enabled == false) { 00348 // When ADR is off, we are allowed to change the channels mask and the NbRep, 00349 // if the datarate and the TX power of the LinkAdrReq are set to 0x0F. 00350 if ((verify_params->datarate != 0x0F) || (verify_params->tx_power != 0x0F)) { 00351 status = 0; 00352 nb_repetitions = verify_params->current_nb_rep ; 00353 } 00354 00355 // Get the current datarate and tx power 00356 datarate = verify_params->current_datarate ; 00357 tx_power = verify_params->current_tx_power ; 00358 } 00359 00360 if (status != 0) { 00361 // Verify channel datarate 00362 if (verify_channel_DR(phy_params.max_channel_cnt, verify_params->channel_mask , 00363 datarate, phy_params.min_tx_datarate, 00364 phy_params.max_tx_datarate, phy_params.channels.channel_list) 00365 == false) { 00366 status &= 0xFD; // Datarate KO 00367 } 00368 00369 // Verify tx power 00370 if (val_in_range(tx_power, phy_params.max_tx_power, 00371 phy_params.min_tx_power) == 0) { 00372 // Verify if the maximum TX power is exceeded 00373 if (phy_params.max_tx_power > tx_power) { 00374 // Apply maximum TX power. Accept TX power. 00375 tx_power = phy_params.max_tx_power; 00376 } else { 00377 status &= 0xFB; // TxPower KO 00378 } 00379 } 00380 } 00381 00382 // If the status is ok, verify the NbRep 00383 if (status == 0x07 && nb_repetitions == 0) { 00384 // Restore the default value according to the LoRaWAN specification 00385 nb_repetitions = 1; 00386 } 00387 00388 // Apply changes 00389 *dr = datarate; 00390 *tx_pow = tx_power; 00391 *nb_rep = nb_repetitions; 00392 00393 return status; 00394 } 00395 00396 double LoRaPHY::compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth) 00397 { 00398 return ((double)(1 << phy_dr) / (double) bandwidth) * 1000; 00399 } 00400 00401 double LoRaPHY::compute_symb_timeout_fsk(uint8_t phy_dr) 00402 { 00403 return (8.0 / (double) phy_dr); // 1 symbol equals 1 byte 00404 } 00405 00406 void LoRaPHY::get_rx_window_params(double t_symb, uint8_t min_rx_symb, 00407 uint32_t rx_error, uint32_t wakeup_time, 00408 uint32_t *window_timeout, int32_t *window_offset) 00409 { 00410 // Computed number of symbols 00411 *window_timeout = MAX((uint32_t) ceil(((2 * min_rx_symb - 8) * t_symb + 2 * rx_error) / t_symb), min_rx_symb); 00412 *window_offset = (int32_t) ceil((4.0 * t_symb) - ((*window_timeout * t_symb) / 2.0 ) - wakeup_time); 00413 } 00414 00415 int8_t LoRaPHY::compute_tx_power(int8_t tx_power_idx, float max_eirp, 00416 float antenna_gain) 00417 { 00418 int8_t phy_tx_power = 0; 00419 00420 phy_tx_power = (int8_t) floor((max_eirp - (tx_power_idx * 2U)) - antenna_gain); 00421 00422 return phy_tx_power; 00423 } 00424 00425 00426 int8_t LoRaPHY::get_next_lower_dr(int8_t dr, int8_t min_dr) 00427 { 00428 uint8_t next_lower_dr = dr; 00429 00430 do { 00431 if (next_lower_dr != min_dr) { 00432 next_lower_dr -= 1; 00433 } 00434 } while ((next_lower_dr != min_dr) && !is_datarate_supported(next_lower_dr)); 00435 00436 return next_lower_dr; 00437 } 00438 00439 uint8_t LoRaPHY::get_bandwidth(uint8_t dr) 00440 { 00441 uint32_t *bandwidths = (uint32_t *) phy_params.bandwidths.table; 00442 00443 switch (bandwidths[dr]) { 00444 default: 00445 case 125000: 00446 return 0; 00447 case 250000: 00448 return 1; 00449 case 500000: 00450 return 2; 00451 } 00452 } 00453 00454 uint8_t LoRaPHY::enabled_channel_count(bool joined, uint8_t datarate, 00455 const uint16_t *channel_mask, 00456 uint8_t *channel_indices, 00457 uint8_t *delayTx) 00458 { 00459 uint8_t count = 0; 00460 uint8_t delay_transmission = 0; 00461 00462 for (uint8_t i = 0; i < phy_params.max_channel_cnt; i++) { 00463 if (mask_bit_test(channel_mask, i)) { 00464 00465 if (val_in_range(datarate, phy_params.channels.channel_list[i].dr_range.fields.min, 00466 phy_params.channels.channel_list[i].dr_range.fields.max) == 0) { 00467 // data rate range invalid for this channel 00468 continue; 00469 } 00470 00471 band_t *band_table = (band_t *) phy_params.bands.table; 00472 if (band_table[phy_params.channels.channel_list[i].band].off_time > 0) { 00473 // Check if the band is available for transmission 00474 delay_transmission++; 00475 continue; 00476 } 00477 00478 // otherwise count the channel as enabled 00479 channel_indices[count++] = i; 00480 } 00481 } 00482 00483 *delayTx = delay_transmission; 00484 00485 return count; 00486 } 00487 00488 bool LoRaPHY::is_datarate_supported(const int8_t datarate) const 00489 { 00490 if (datarate < phy_params.datarates.size) { 00491 return (((uint8_t *)phy_params.datarates.table)[datarate] != 0) ? true : false; 00492 } else { 00493 return false; 00494 } 00495 } 00496 00497 void LoRaPHY::reset_to_default_values(loramac_protocol_params *params, bool init) 00498 { 00499 if (init) { 00500 params->is_dutycycle_on = phy_params.duty_cycle_enabled; 00501 00502 params->sys_params.max_rx_win_time = phy_params.max_rx_window; 00503 00504 params->sys_params.recv_delay1 = phy_params.recv_delay1; 00505 00506 params->sys_params.recv_delay2 = phy_params.recv_delay2; 00507 00508 params->sys_params.join_accept_delay1 = phy_params.join_accept_delay1; 00509 00510 params->sys_params.join_accept_delay2 = phy_params.join_accept_delay2; 00511 00512 params->sys_params.downlink_dwell_time = phy_params.dl_dwell_time_setting; 00513 } 00514 00515 params->sys_params.channel_tx_power = get_default_tx_power(); 00516 00517 params->sys_params.channel_data_rate = get_default_tx_datarate(); 00518 00519 params->sys_params.rx1_dr_offset = phy_params.default_rx1_dr_offset; 00520 00521 params->sys_params.rx2_channel.frequency = get_default_rx2_frequency(); 00522 00523 params->sys_params.rx2_channel.datarate = get_default_rx2_datarate(); 00524 00525 params->sys_params.uplink_dwell_time = phy_params.ul_dwell_time_setting; 00526 00527 params->sys_params.max_eirp = phy_params.default_max_eirp; 00528 00529 params->sys_params.antenna_gain = phy_params.default_antenna_gain; 00530 } 00531 00532 int8_t LoRaPHY::get_next_lower_tx_datarate(int8_t datarate) 00533 { 00534 if (phy_params.ul_dwell_time_setting == 0) { 00535 return get_next_lower_dr(datarate, phy_params.min_tx_datarate); 00536 } 00537 00538 return get_next_lower_dr(datarate, phy_params.dwell_limit_datarate); 00539 00540 } 00541 00542 uint8_t LoRaPHY::get_minimum_rx_datarate() 00543 { 00544 if (phy_params.dl_dwell_time_setting == 0) { 00545 return phy_params.min_rx_datarate; 00546 } 00547 return phy_params.dwell_limit_datarate; 00548 } 00549 00550 uint8_t LoRaPHY::get_minimum_tx_datarate() 00551 { 00552 if (phy_params.ul_dwell_time_setting == 0) { 00553 return phy_params.min_tx_datarate; 00554 } 00555 return phy_params.dwell_limit_datarate; 00556 } 00557 00558 uint8_t LoRaPHY::get_default_tx_datarate() 00559 { 00560 return phy_params.default_datarate; 00561 } 00562 00563 uint8_t LoRaPHY::get_default_tx_power() 00564 { 00565 return phy_params.default_tx_power; 00566 } 00567 00568 uint8_t LoRaPHY::get_max_payload(uint8_t datarate, bool use_repeater) 00569 { 00570 uint8_t *payload_table = NULL; 00571 00572 if (use_repeater) { 00573 // if (datarate >= phy_params.payloads_with_repeater.size) { 00574 // //TODO: Can this ever happen? If yes, should we return 0? 00575 // } 00576 payload_table = (uint8_t *) phy_params.payloads_with_repeater.table; 00577 } else { 00578 payload_table = (uint8_t *) phy_params.payloads.table; 00579 } 00580 00581 return payload_table[datarate]; 00582 } 00583 00584 uint16_t LoRaPHY::get_maximum_frame_counter_gap() 00585 { 00586 return phy_params.max_fcnt_gap; 00587 } 00588 00589 uint32_t LoRaPHY::get_ack_timeout() 00590 { 00591 uint16_t ack_timeout_rnd = phy_params.ack_timeout_rnd; 00592 return (phy_params.ack_timeout 00593 + get_random(-ack_timeout_rnd, ack_timeout_rnd)); 00594 } 00595 00596 uint32_t LoRaPHY::get_default_rx2_frequency() 00597 { 00598 return phy_params.rx_window2_frequency; 00599 } 00600 00601 uint8_t LoRaPHY::get_default_rx2_datarate() 00602 { 00603 return phy_params.rx_window2_datarate; 00604 } 00605 00606 uint16_t *LoRaPHY::get_channel_mask(bool get_default) 00607 { 00608 if (get_default) { 00609 return phy_params.channels.default_mask; 00610 } 00611 return phy_params.channels.mask; 00612 } 00613 00614 uint8_t LoRaPHY::get_max_nb_channels() 00615 { 00616 return phy_params.max_channel_cnt; 00617 } 00618 00619 channel_params_t *LoRaPHY::get_phy_channels() 00620 { 00621 return phy_params.channels.channel_list; 00622 } 00623 00624 bool LoRaPHY::is_custom_channel_plan_supported() 00625 { 00626 return phy_params.custom_channelplans_supported; 00627 } 00628 00629 void LoRaPHY::restore_default_channels() 00630 { 00631 // Restore channels default mask 00632 for (uint8_t i = 0; i < phy_params.channels.mask_size; i++) { 00633 phy_params.channels.mask[i] |= phy_params.channels.default_mask[i]; 00634 } 00635 } 00636 00637 bool LoRaPHY::verify_rx_datarate(uint8_t datarate) 00638 { 00639 if (is_datarate_supported(datarate)) { 00640 if (phy_params.dl_dwell_time_setting == 0) { 00641 //TODO: Check this! datarate must be same as minimum! Can be compared directly if OK 00642 return val_in_range(datarate, 00643 phy_params.min_rx_datarate, 00644 phy_params.max_rx_datarate); 00645 } else { 00646 return val_in_range(datarate, 00647 phy_params.dwell_limit_datarate, 00648 phy_params.max_rx_datarate); 00649 } 00650 } 00651 return false; 00652 } 00653 00654 bool LoRaPHY::verify_tx_datarate(uint8_t datarate, bool use_default) 00655 { 00656 if (!is_datarate_supported(datarate)) { 00657 return false; 00658 } 00659 00660 if (use_default) { 00661 return val_in_range(datarate, phy_params.default_datarate, 00662 phy_params.default_max_datarate); 00663 } else if (phy_params.ul_dwell_time_setting == 0) { 00664 return val_in_range(datarate, phy_params.min_tx_datarate, 00665 phy_params.max_tx_datarate); 00666 } else { 00667 return val_in_range(datarate, phy_params.dwell_limit_datarate, 00668 phy_params.max_tx_datarate); 00669 } 00670 } 00671 00672 bool LoRaPHY::verify_tx_power(uint8_t tx_power) 00673 { 00674 return val_in_range(tx_power, phy_params.max_tx_power, 00675 phy_params.min_tx_power); 00676 } 00677 00678 bool LoRaPHY::verify_duty_cycle(bool cycle) 00679 { 00680 if (cycle == phy_params.duty_cycle_enabled) { 00681 return true; 00682 } 00683 return false; 00684 } 00685 00686 bool LoRaPHY::verify_nb_join_trials(uint8_t nb_join_trials) 00687 { 00688 if (nb_join_trials < MBED_CONF_LORA_NB_TRIALS) { 00689 return false; 00690 } 00691 return true; 00692 } 00693 00694 void LoRaPHY::apply_cf_list(const uint8_t *payload, uint8_t size) 00695 { 00696 // if the underlying PHY doesn't support CF-List, ignore the request 00697 if (!phy_params.cflist_supported) { 00698 return; 00699 } 00700 00701 channel_params_t new_channel; 00702 00703 // Setup default datarate range 00704 new_channel.dr_range.value = (phy_params.default_max_datarate << 4) | 00705 phy_params.default_datarate; 00706 00707 // Size of the optional CF list 00708 if (size != 16) { 00709 return; 00710 } 00711 00712 // Last byte is RFU, don't take it into account 00713 // NOTE: Currently the PHY layers supported by LoRaWAN who accept a CF-List 00714 // define first 2 or 3 channels as default channels. this function is 00715 // written keeping that in mind. If there would be a PHY in the future that 00716 // accepts CF-list but have haphazard allocation of default channels, we 00717 // should override this function in the implementation of that particular 00718 // PHY. 00719 for (uint8_t i = 0, channel_id = phy_params.default_channel_cnt; 00720 channel_id < phy_params.max_channel_cnt; i += 3, channel_id++) { 00721 if (channel_id < (phy_params.cflist_channel_cnt + phy_params.default_channel_cnt)) { 00722 // Channel frequency 00723 new_channel.frequency = (uint32_t) payload[i]; 00724 new_channel.frequency |= ((uint32_t) payload[i + 1] << 8); 00725 new_channel.frequency |= ((uint32_t) payload[i + 2] << 16); 00726 new_channel.frequency *= 100; 00727 00728 // Initialize alternative frequency to 0 00729 new_channel.rx1_frequency = 0; 00730 } else { 00731 new_channel.frequency = 0; 00732 new_channel.dr_range.value = 0; 00733 new_channel.rx1_frequency = 0; 00734 } 00735 00736 if (new_channel.frequency != 0) { 00737 //lookup for band 00738 new_channel.band = lookup_band_for_frequency(new_channel.frequency); 00739 00740 // Try to add channel 00741 add_channel(&new_channel, channel_id); 00742 } else { 00743 remove_channel(channel_id); 00744 } 00745 } 00746 } 00747 00748 00749 bool LoRaPHY::get_next_ADR(bool restore_channel_mask, int8_t &dr_out, 00750 int8_t &tx_power_out, uint32_t &adr_ack_cnt) 00751 { 00752 bool set_adr_ack_bit = false; 00753 00754 uint16_t ack_limit_plus_delay = phy_params.adr_ack_limit + phy_params.adr_ack_delay; 00755 00756 if (dr_out == phy_params.min_tx_datarate) { 00757 adr_ack_cnt = 0; 00758 return set_adr_ack_bit; 00759 } 00760 00761 if (adr_ack_cnt < phy_params.adr_ack_limit) { 00762 return set_adr_ack_bit; 00763 } 00764 00765 // ADR ack counter is larger than ADR-ACK-LIMIT 00766 set_adr_ack_bit = true; 00767 tx_power_out = phy_params.max_tx_power; 00768 00769 if (adr_ack_cnt >= ack_limit_plus_delay) { 00770 if ((adr_ack_cnt % phy_params.adr_ack_delay) == 1) { 00771 // Decrease the datarate 00772 dr_out = get_next_lower_tx_datarate(dr_out); 00773 00774 if (dr_out == phy_params.min_tx_datarate) { 00775 // We must set adrAckReq to false as soon as we reach the lowest datarate 00776 set_adr_ack_bit = false; 00777 if (restore_channel_mask) { 00778 // Re-enable default channels 00779 restore_default_channels(); 00780 } 00781 } 00782 } 00783 } 00784 00785 return set_adr_ack_bit; 00786 } 00787 00788 void LoRaPHY::compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols, 00789 uint32_t rx_error, 00790 rx_config_params_t *rx_conf_params) 00791 { 00792 double t_symbol = 0.0; 00793 00794 // Get the datarate, perform a boundary check 00795 rx_conf_params->datarate = MIN(datarate, phy_params.max_rx_datarate); 00796 00797 rx_conf_params->bandwidth = get_bandwidth(rx_conf_params->datarate ); 00798 00799 if (phy_params.fsk_supported && rx_conf_params->datarate == phy_params.max_rx_datarate) { 00800 // FSK 00801 t_symbol = compute_symb_timeout_fsk(((uint8_t *)phy_params.datarates.table)[rx_conf_params->datarate ]); 00802 } else { 00803 // LoRa 00804 t_symbol = compute_symb_timeout_lora(((uint8_t *)phy_params.datarates.table)[rx_conf_params->datarate ], 00805 ((uint32_t *)phy_params.bandwidths.table)[rx_conf_params->datarate ]); 00806 } 00807 00808 get_rx_window_params(t_symbol, min_rx_symbols, rx_error, RADIO_WAKEUP_TIME, 00809 &rx_conf_params->window_timeout , &rx_conf_params->window_offset ); 00810 } 00811 00812 bool LoRaPHY::rx_config(rx_config_params_t *rx_conf) 00813 { 00814 radio_modems_t modem; 00815 uint8_t dr = rx_conf->datarate ; 00816 uint8_t max_payload = 0; 00817 uint8_t phy_dr = 0; 00818 uint32_t frequency = rx_conf->frequency ; 00819 00820 _radio->lock(); 00821 00822 if (_radio->get_status() != RF_IDLE) { 00823 _radio->unlock(); 00824 return false; 00825 } 00826 00827 _radio->unlock(); 00828 00829 if (rx_conf->rx_slot == RX_SLOT_WIN_1 ) { 00830 // Apply window 1 frequency 00831 frequency = phy_params.channels.channel_list[rx_conf->channel ].frequency; 00832 // Apply the alternative RX 1 window frequency, if it is available 00833 if (phy_params.channels.channel_list[rx_conf->channel ].rx1_frequency != 0) { 00834 frequency = phy_params.channels.channel_list[rx_conf->channel ].rx1_frequency; 00835 } 00836 } 00837 00838 // Read the physical datarate from the datarates table 00839 uint8_t *datarate_table = (uint8_t *) phy_params.datarates.table; 00840 uint8_t *payload_table = (uint8_t *) phy_params.payloads.table; 00841 uint8_t *payload_with_repeater_table = (uint8_t *) phy_params.payloads_with_repeater.table; 00842 00843 phy_dr = datarate_table[dr]; 00844 00845 _radio->lock(); 00846 00847 _radio->set_channel(frequency); 00848 00849 // Radio configuration 00850 if (dr == DR_7 && phy_params.fsk_supported) { 00851 modem = MODEM_FSK; 00852 _radio->set_rx_config(modem, 50000, phy_dr * 1000, 0, 83333, 5, 00853 rx_conf->window_timeout , false, 0, true, 0, 0, 00854 false, rx_conf->is_rx_continuous ); 00855 } else { 00856 modem = MODEM_LORA; 00857 _radio->set_rx_config(modem, rx_conf->bandwidth , phy_dr, 1, 0, 8, 00858 rx_conf->window_timeout , false, 0, false, 0, 0, 00859 true, rx_conf->is_rx_continuous ); 00860 } 00861 00862 if (rx_conf->is_repeater_supported ) { 00863 max_payload = payload_with_repeater_table[dr]; 00864 } else { 00865 max_payload = payload_table[dr]; 00866 } 00867 00868 _radio->set_max_payload_length(modem, max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); 00869 00870 _radio->unlock(); 00871 00872 return true; 00873 } 00874 00875 bool LoRaPHY::tx_config(tx_config_params_t *tx_conf, int8_t *tx_power, 00876 lorawan_time_t *tx_toa) 00877 { 00878 radio_modems_t modem; 00879 int8_t phy_dr = ((uint8_t *)phy_params.datarates.table)[tx_conf->datarate]; 00880 channel_params_t *list = phy_params.channels.channel_list; 00881 uint8_t band_idx = list[tx_conf->channel].band; 00882 band_t *bands = (band_t *)phy_params.bands.table; 00883 00884 // limit TX power if set to too much 00885 tx_conf->tx_power = MAX(tx_conf->tx_power, bands[band_idx].max_tx_pwr ); 00886 00887 uint8_t bandwidth = get_bandwidth(tx_conf->datarate); 00888 int8_t phy_tx_power = 0; 00889 00890 // Calculate physical TX power 00891 phy_tx_power = compute_tx_power(tx_conf->tx_power, tx_conf->max_eirp, 00892 tx_conf->antenna_gain); 00893 00894 _radio->lock(); 00895 00896 // Setup the radio frequency 00897 _radio->set_channel(list[tx_conf->channel].frequency); 00898 00899 if (tx_conf->datarate == phy_params.max_tx_datarate) { 00900 // High Speed FSK channel 00901 modem = MODEM_FSK; 00902 _radio->set_tx_config(modem, phy_tx_power, 25000, bandwidth, 00903 phy_dr * 1000, 0, 5, false, true, 0, 0, false, 00904 3000); 00905 } else { 00906 modem = MODEM_LORA; 00907 _radio->set_tx_config(modem, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, 00908 false, true, 0, 0, false, 3000); 00909 } 00910 00911 // Setup maximum payload lenght of the radio driver 00912 _radio->set_max_payload_length(modem, tx_conf->pkt_len); 00913 // Get the time-on-air of the next tx frame 00914 *tx_toa = _radio->time_on_air(modem, tx_conf->pkt_len); 00915 00916 _radio->unlock(); 00917 00918 *tx_power = tx_conf->tx_power; 00919 00920 return true; 00921 } 00922 00923 uint8_t LoRaPHY::link_ADR_request(adr_req_params_t *link_adr_req, 00924 int8_t *dr_out, int8_t *tx_power_out, 00925 uint8_t *nb_rep_out, uint8_t *nb_bytes_processed) 00926 { 00927 uint8_t status = 0x07; 00928 link_adr_params_t adr_settings; 00929 uint8_t next_index = 0; 00930 uint8_t bytes_processed = 0; 00931 00932 // rather than dynamically allocating memory, we choose to set 00933 // a channel mask list size of unity here as we know that all 00934 // the PHY layer implementations who have more than 16 channels, i.e., 00935 // have channel mask list size more than unity, override this method. 00936 uint16_t temp_channel_mask[1] = {0}; 00937 00938 verify_adr_params_t verify_params; 00939 00940 while (bytes_processed < link_adr_req->payload_size) { 00941 // Get ADR request parameters 00942 next_index = parse_link_ADR_req(&(link_adr_req->payload [bytes_processed]), 00943 &adr_settings); 00944 00945 if (next_index == 0) { 00946 break; // break loop, since no more request has been found 00947 } 00948 00949 // Update bytes processed 00950 bytes_processed += next_index; 00951 00952 // Revert status, as we only check the last ADR request for the channel mask KO 00953 status = 0x07; 00954 00955 // Setup temporary channels mask 00956 temp_channel_mask[0] = adr_settings.channel_mask; 00957 00958 // Verify channels mask 00959 if (adr_settings.ch_mask_ctrl == 0 && temp_channel_mask[0] == 0) { 00960 status &= 0xFE; // Channel mask KO 00961 } 00962 00963 // channel mask applies to first 16 channels 00964 if (adr_settings.ch_mask_ctrl == 0 || adr_settings.ch_mask_ctrl == 6) { 00965 00966 for (uint8_t i = 0; i < phy_params.max_channel_cnt; i++) { 00967 00968 // turn on all channels if channel mask control is 6 00969 if (adr_settings.ch_mask_ctrl == 6) { 00970 if (phy_params.channels.channel_list[i].frequency != 0) { 00971 mask_bit_set(temp_channel_mask, i); 00972 } 00973 00974 continue; 00975 } 00976 00977 // if channel mask control is 0, we test the bits and 00978 // frequencies and change the status if we find a discrepancy 00979 if ((mask_bit_test(temp_channel_mask, i)) && 00980 (phy_params.channels.channel_list[i].frequency == 0)) { 00981 // Trying to enable an undefined channel 00982 status &= 0xFE; // Channel mask KO 00983 } 00984 } 00985 } else { 00986 // Channel mask control applies to RFUs 00987 status &= 0xFE; // Channel mask KO 00988 } 00989 } 00990 00991 if (is_datarate_supported(adr_settings.datarate)) { 00992 verify_params.status = status; 00993 00994 verify_params.adr_enabled = link_adr_req->adr_enabled ; 00995 verify_params.current_datarate = link_adr_req->current_datarate ; 00996 verify_params.current_tx_power = link_adr_req->current_tx_power ; 00997 verify_params.current_nb_rep = link_adr_req->current_nb_rep ; 00998 00999 verify_params.datarate = adr_settings.datarate; 01000 verify_params.tx_power = adr_settings.tx_power; 01001 verify_params.nb_rep = adr_settings.nb_rep; 01002 01003 01004 verify_params.channel_mask = temp_channel_mask; 01005 01006 // Verify the parameters and update, if necessary 01007 status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, 01008 &adr_settings.tx_power, &adr_settings.nb_rep); 01009 } else { 01010 status &= 0xFD; // Datarate KO 01011 } 01012 01013 // Update channelsMask if everything is correct 01014 if (status == 0x07) { 01015 // Set the channels mask to a default value 01016 memset(phy_params.channels.mask, 0, 01017 sizeof(uint16_t)*phy_params.channels.mask_size); 01018 01019 // Update the channels mask 01020 copy_channel_mask(phy_params.channels.mask, temp_channel_mask, 01021 phy_params.channels.mask_size); 01022 } 01023 01024 // Update status variables 01025 *dr_out = adr_settings.datarate; 01026 *tx_power_out = adr_settings.tx_power; 01027 *nb_rep_out = adr_settings.nb_rep; 01028 *nb_bytes_processed = bytes_processed; 01029 01030 return status; 01031 } 01032 01033 uint8_t LoRaPHY::accept_rx_param_setup_req(rx_param_setup_req_t *params) 01034 { 01035 uint8_t status = 0x07; 01036 01037 if (lookup_band_for_frequency(params->frequency) < 0) { 01038 status &= 0xFE; 01039 } 01040 01041 // Verify radio frequency 01042 if (_radio->check_rf_frequency(params->frequency) == false) { 01043 status &= 0xFE; // Channel frequency KO 01044 } 01045 01046 // Verify datarate 01047 if (val_in_range(params->datarate, phy_params.min_rx_datarate, 01048 phy_params.max_rx_datarate) == 0) { 01049 status &= 0xFD; // Datarate KO 01050 } 01051 01052 // Verify datarate offset 01053 if (val_in_range(params->dr_offset, phy_params.min_rx1_dr_offset, 01054 phy_params.max_rx1_dr_offset) == 0) { 01055 status &= 0xFB; // Rx1DrOffset range KO 01056 } 01057 01058 return status; 01059 } 01060 01061 bool LoRaPHY::accept_tx_param_setup_req(uint8_t ul_dwell_time, uint8_t dl_dwell_time) 01062 { 01063 if (phy_params.accept_tx_param_setup_req) { 01064 phy_params.ul_dwell_time_setting = ul_dwell_time; 01065 phy_params.dl_dwell_time_setting = dl_dwell_time; 01066 } 01067 01068 return phy_params.accept_tx_param_setup_req; 01069 } 01070 01071 int LoRaPHY::lookup_band_for_frequency(uint32_t freq) const 01072 { 01073 // check all sub bands (if there are sub-bands) to check if the given 01074 // frequency falls into any of the frequency ranges 01075 01076 for (int band = 0; band < phy_params.bands.size; band++) { 01077 if (verify_frequency_for_band(freq, band)) { 01078 return band; 01079 } 01080 } 01081 01082 return -1; 01083 } 01084 01085 bool LoRaPHY::verify_frequency_for_band(uint32_t freq, uint8_t band) const 01086 { 01087 band_t *bands_table = (band_t *)phy_params.bands.table; 01088 01089 if (freq <= bands_table[band].higher_band_freq 01090 && freq >= bands_table[band].lower_band_freq) { 01091 return true; 01092 } else { 01093 return false; 01094 } 01095 } 01096 01097 uint8_t LoRaPHY::dl_channel_request(uint8_t channel_id, uint32_t rx1_frequency) 01098 { 01099 if (!phy_params.dl_channel_req_supported) { 01100 return 0; 01101 } 01102 01103 uint8_t status = 0x03; 01104 01105 // Verify if the frequency is supported 01106 uint8_t band = lookup_band_for_frequency(rx1_frequency); 01107 if (verify_frequency_for_band(rx1_frequency, band) == false) { 01108 status &= 0xFE; 01109 } 01110 01111 // Verify if an uplink frequency exists 01112 if (phy_params.channels.channel_list[channel_id].frequency == 0) { 01113 status &= 0xFD; 01114 } 01115 01116 // Apply Rx1 frequency, if the status is OK 01117 if (status == 0x03) { 01118 phy_params.channels.channel_list[channel_id].rx1_frequency = rx1_frequency; 01119 } 01120 01121 return status; 01122 } 01123 01124 /** 01125 * Alternate datarate algorithm for join requests. 01126 * - We check from the PHY and take note of total 01127 * number of data rates available upto the default data rate for 01128 * default channels. 01129 * 01130 * - Application sets a total number of re-trials for a Join Request, i.e., 01131 * MBED_CONF_LORA_NB_TRIALS. So MAC layer will send us a counter 01132 * nb_trials < MBED_CONF_LORA_NB_TRIALS which is the current number of trial. 01133 * 01134 * - We roll over total available datarates and pick one according to the 01135 * number of trial sequentially. 01136 * 01137 * - We always start from the Default Data rate and and set the next lower 01138 * data rate for every iteration. 01139 * 01140 * - MAC layer will stop when maximum number of re-trials, i.e., 01141 * MBED_CONF_LORA_NB_TRIALS is achieved. 01142 * 01143 * So essentially MBED_CONF_LORA_NB_TRIALS should be a multiple of range of 01144 * data rates available. For example, in EU868 band, default max. data rate is 01145 * DR_5 and min. data rate is DR_0, so total data rates available are 6. 01146 * 01147 * Hence MBED_CONF_LORA_NB_TRIALS should be a multiple of 6. Setting, 01148 * MBED_CONF_LORA_NB_TRIALS = 6 would mean that every data rate will be tried 01149 * exactly once starting from the largest and finishing at the smallest. 01150 * 01151 * PHY layers which do not have datarates scheme similar to EU band will ofcourse 01152 * override this method. 01153 */ 01154 int8_t LoRaPHY::get_alternate_DR(uint8_t nb_trials) 01155 { 01156 int8_t datarate = 0; 01157 uint8_t total_nb_datrates = (phy_params.default_max_datarate - phy_params.min_tx_datarate) + 1; 01158 01159 uint8_t res = nb_trials % total_nb_datrates; 01160 01161 if (res == 0) { 01162 datarate = phy_params.min_tx_datarate; 01163 } else if (res == 1) { 01164 datarate = phy_params.default_max_datarate; 01165 } else { 01166 datarate = (phy_params.default_max_datarate - res) + 1; 01167 } 01168 01169 return datarate; 01170 } 01171 01172 void LoRaPHY::calculate_backoff(bool joined, bool last_tx_was_join_req, bool dc_enabled, uint8_t channel, 01173 lorawan_time_t elapsed_time, lorawan_time_t tx_toa) 01174 { 01175 band_t *band_table = (band_t *) phy_params.bands.table; 01176 channel_params_t *channel_list = phy_params.channels.channel_list; 01177 01178 uint8_t band_idx = channel_list[channel].band; 01179 uint16_t duty_cycle = band_table[band_idx].duty_cycle ; 01180 uint16_t join_duty_cycle = 0; 01181 01182 // Reset time-off to initial value. 01183 band_table[band_idx].off_time = 0; 01184 01185 if (joined == false) { 01186 // Get the join duty cycle 01187 if (elapsed_time < 3600000) { 01188 join_duty_cycle = BACKOFF_DC_1_HOUR; 01189 } else if (elapsed_time < (3600000 + 36000000)) { 01190 join_duty_cycle = BACKOFF_DC_10_HOURS; 01191 } else { 01192 join_duty_cycle = BACKOFF_DC_24_HOURS; 01193 } 01194 01195 // Apply the most restricting duty cycle 01196 duty_cycle = MAX(duty_cycle, join_duty_cycle); 01197 } 01198 01199 // No back-off if the last frame was not a join request and when the 01200 // duty cycle is not enabled 01201 if (dc_enabled == false && last_tx_was_join_req == false) { 01202 band_table[band_idx].off_time = 0; 01203 } else { 01204 // Apply band time-off. 01205 band_table[band_idx].off_time = tx_toa * duty_cycle - tx_toa; 01206 } 01207 } 01208 01209 lorawan_status_t LoRaPHY::set_next_channel(channel_selection_params_t *params, 01210 uint8_t *channel, lorawan_time_t *time, 01211 lorawan_time_t *aggregate_timeoff) 01212 { 01213 uint8_t channel_count = 0; 01214 uint8_t delay_tx = 0; 01215 01216 // Note here that the PHY layer implementations which have more than 01217 // 16 channels at their disposal, override this function. That's why 01218 // it is safe to assume that we are dealing with a block of 16 channels 01219 // i.e., EU like implementations. So rather than dynamically allocating 01220 // memory we chose to use a magic number of 16 01221 uint8_t enabled_channels[16]; 01222 01223 memset(enabled_channels, 0xFF, sizeof(uint8_t) * 16); 01224 01225 lorawan_time_t next_tx_delay = 0; 01226 band_t *band_table = (band_t *) phy_params.bands.table; 01227 01228 if (num_active_channels(phy_params.channels.mask, 0, 01229 phy_params.channels.mask_size) == 0) { 01230 01231 // Reactivate default channels 01232 copy_channel_mask(phy_params.channels.mask, 01233 phy_params.channels.default_mask, 01234 phy_params.channels.mask_size); 01235 } 01236 01237 if (params->aggregate_timeoff 01238 <= _lora_time.get_elapsed_time(params->last_aggregate_tx_time)) { 01239 // Reset Aggregated time off 01240 *aggregate_timeoff = 0; 01241 01242 // Update bands Time OFF 01243 next_tx_delay = update_band_timeoff(params->joined, 01244 params->dc_enabled, 01245 band_table, phy_params.bands.size); 01246 01247 // Search how many channels are enabled 01248 channel_count = enabled_channel_count(params->joined, params->current_datarate, 01249 phy_params.channels.mask, 01250 enabled_channels, &delay_tx); 01251 } else { 01252 delay_tx++; 01253 next_tx_delay = params->aggregate_timeoff - 01254 _lora_time.get_elapsed_time(params->last_aggregate_tx_time); 01255 } 01256 01257 if (channel_count > 0) { 01258 // We found a valid channel 01259 *channel = enabled_channels[get_random(0, channel_count - 1)]; 01260 *time = 0; 01261 return LORAWAN_STATUS_OK; 01262 } 01263 01264 if (delay_tx > 0) { 01265 // Delay transmission due to AggregatedTimeOff or to a band time off 01266 *time = next_tx_delay; 01267 return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; 01268 } 01269 01270 // Datarate not supported by any channel, restore defaults 01271 copy_channel_mask(phy_params.channels.mask, 01272 phy_params.channels.default_mask, 01273 phy_params.channels.mask_size); 01274 *time = 0; 01275 return LORAWAN_STATUS_NO_CHANNEL_FOUND; 01276 } 01277 01278 lorawan_status_t LoRaPHY::add_channel(const channel_params_t *new_channel, 01279 uint8_t id) 01280 { 01281 bool dr_invalid = false; 01282 bool freq_invalid = false; 01283 01284 if (!phy_params.custom_channelplans_supported 01285 || id >= phy_params.max_channel_cnt) { 01286 01287 return LORAWAN_STATUS_PARAMETER_INVALID; 01288 } 01289 01290 // Validate the datarate range 01291 if (val_in_range(new_channel->dr_range.fields.min, 01292 phy_params.min_tx_datarate, 01293 phy_params.max_tx_datarate) == 0) { 01294 dr_invalid = true; 01295 } 01296 01297 if (val_in_range(new_channel->dr_range.fields.max, phy_params.min_tx_datarate, 01298 phy_params.max_tx_datarate) == 0) { 01299 dr_invalid = true; 01300 } 01301 01302 if (new_channel->dr_range.fields.min > new_channel->dr_range.fields.max) { 01303 dr_invalid = true; 01304 } 01305 01306 // Default channels don't accept all values 01307 if (id < phy_params.default_channel_cnt) { 01308 // Validate the datarate range for min: must be DR_0 01309 if (new_channel->dr_range.fields.min > phy_params.min_tx_datarate) { 01310 dr_invalid = true; 01311 } 01312 01313 // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE 01314 if (val_in_range(new_channel->dr_range.fields.max, 01315 phy_params.default_max_datarate, 01316 phy_params.max_tx_datarate) == 0) { 01317 dr_invalid = true; 01318 } 01319 01320 // We are not allowed to change the frequency 01321 if (new_channel->frequency != phy_params.channels.channel_list[id].frequency) { 01322 freq_invalid = true; 01323 } 01324 } 01325 01326 // Check frequency 01327 if (!freq_invalid) { 01328 if (new_channel->band >= phy_params.bands.size 01329 || verify_frequency_for_band(new_channel->frequency, 01330 new_channel->band) == false) { 01331 freq_invalid = true; 01332 } 01333 } 01334 01335 // Check status 01336 if (dr_invalid && freq_invalid) { 01337 return LORAWAN_STATUS_FREQ_AND_DR_INVALID; 01338 } 01339 01340 if (dr_invalid) { 01341 return LORAWAN_STATUS_DATARATE_INVALID; 01342 } 01343 01344 if (freq_invalid) { 01345 return LORAWAN_STATUS_FREQUENCY_INVALID; 01346 } 01347 01348 memcpy(&(phy_params.channels.channel_list[id]), new_channel, sizeof(channel_params_t)); 01349 01350 phy_params.channels.channel_list[id].band = new_channel->band; 01351 01352 mask_bit_set(phy_params.channels.mask, id); 01353 01354 return LORAWAN_STATUS_OK; 01355 } 01356 01357 bool LoRaPHY::remove_channel(uint8_t channel_id) 01358 { 01359 // upper layers are checking if the custom channel planning is supported or 01360 // not. So we don't need to worry about that 01361 if (mask_bit_test(phy_params.channels.default_mask, channel_id)) { 01362 return false; 01363 } 01364 01365 01366 // Remove the channel from the list of channels 01367 const channel_params_t empty_channel = { 0, 0, {0}, 0 }; 01368 phy_params.channels.channel_list[channel_id] = empty_channel; 01369 01370 return disable_channel(phy_params.channels.mask, channel_id, 01371 phy_params.max_channel_cnt); 01372 } 01373 01374 void LoRaPHY::set_tx_cont_mode(cw_mode_params_t *params, uint32_t given_frequency) 01375 { 01376 band_t *bands_table = (band_t *) phy_params.bands.table; 01377 channel_params_t *channels = phy_params.channels.channel_list; 01378 01379 if (params->tx_power > bands_table[channels[params->channel ].band].max_tx_pwr ) { 01380 params->tx_power = bands_table[channels[params->channel ].band].max_tx_pwr ; 01381 } 01382 01383 int8_t phy_tx_power = 0; 01384 uint32_t frequency = 0; 01385 01386 if (given_frequency == 0) { 01387 frequency = channels[params->channel ].frequency; 01388 } else { 01389 frequency = given_frequency; 01390 } 01391 01392 // Calculate physical TX power 01393 if (params->max_eirp > 0 && params->antenna_gain > 0) { 01394 phy_tx_power = compute_tx_power(params->tx_power , params->max_eirp , 01395 params->antenna_gain ); 01396 } else { 01397 phy_tx_power = params->tx_power ; 01398 } 01399 01400 _radio->lock(); 01401 _radio->set_tx_continuous_wave(frequency, phy_tx_power, params->timeout ); 01402 _radio->unlock(); 01403 } 01404 01405 uint8_t LoRaPHY::apply_DR_offset(int8_t dr, int8_t dr_offset) 01406 { 01407 int8_t datarate = dr - dr_offset; 01408 01409 if (datarate < 0) { 01410 datarate = phy_params.min_tx_datarate; 01411 } 01412 01413 return datarate; 01414 } 01415 01416
Generated on Tue Jul 12 2022 12:44:31 by
1.7.2