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