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