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 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 uint8_t LoRaPHY::val_in_range( int8_t value, int8_t min, int8_t max ) 00190 { 00191 if ((value >= min) && (value <= max)) { 00192 return 1; 00193 } 00194 00195 return 0; 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(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 // Try to add channel 00737 add_channel(&new_channel, channel_id); 00738 } else { 00739 remove_channel(channel_id); 00740 } 00741 } 00742 } 00743 00744 00745 bool LoRaPHY::get_next_ADR(bool restore_channel_mask, int8_t& dr_out, 00746 int8_t& tx_power_out, uint32_t& adr_ack_cnt) 00747 { 00748 bool set_adr_ack_bit = false; 00749 00750 uint16_t ack_limit_plus_delay = phy_params.adr_ack_limit + phy_params.adr_ack_delay; 00751 00752 if (dr_out == phy_params.min_tx_datarate) { 00753 adr_ack_cnt = 0; 00754 return set_adr_ack_bit; 00755 } 00756 00757 if (adr_ack_cnt < phy_params.adr_ack_limit) { 00758 return set_adr_ack_bit; 00759 } 00760 00761 // ADR ack counter is larger than ADR-ACK-LIMIT 00762 set_adr_ack_bit = true; 00763 tx_power_out = phy_params.max_tx_power; 00764 00765 if (adr_ack_cnt >= ack_limit_plus_delay) { 00766 if ((adr_ack_cnt % phy_params.adr_ack_delay) == 1) { 00767 // Decrease the datarate 00768 dr_out = get_next_lower_tx_datarate(dr_out); 00769 00770 if (dr_out == phy_params.min_tx_datarate) { 00771 // We must set adrAckReq to false as soon as we reach the lowest datarate 00772 set_adr_ack_bit = false; 00773 if (restore_channel_mask) { 00774 // Re-enable default channels 00775 restore_default_channels(); 00776 } 00777 } 00778 } 00779 } 00780 00781 return set_adr_ack_bit; 00782 } 00783 00784 void LoRaPHY::compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols, 00785 uint32_t rx_error, 00786 rx_config_params_t *rx_conf_params) 00787 { 00788 double t_symbol = 0.0; 00789 00790 // Get the datarate, perform a boundary check 00791 rx_conf_params->datarate = MIN( datarate, phy_params.max_rx_datarate); 00792 00793 rx_conf_params->bandwidth = get_bandwidth(rx_conf_params->datarate ); 00794 00795 if (phy_params.fsk_supported && rx_conf_params->datarate == phy_params.max_rx_datarate) { 00796 // FSK 00797 t_symbol = compute_symb_timeout_fsk(((uint8_t *)phy_params.datarates.table)[rx_conf_params->datarate ]); 00798 } else { 00799 // LoRa 00800 t_symbol = compute_symb_timeout_lora(((uint8_t *)phy_params.datarates.table)[rx_conf_params->datarate ], 00801 ((uint32_t *)phy_params.bandwidths.table)[rx_conf_params->datarate ]); 00802 } 00803 00804 get_rx_window_params(t_symbol, min_rx_symbols, rx_error, RADIO_WAKEUP_TIME, 00805 &rx_conf_params->window_timeout , &rx_conf_params->window_offset ); 00806 } 00807 00808 bool LoRaPHY::rx_config(rx_config_params_t * rx_conf, int8_t* datarate) 00809 { 00810 radio_modems_t modem; 00811 uint8_t dr = rx_conf->datarate ; 00812 uint8_t max_payload = 0; 00813 uint8_t phy_dr = 0; 00814 uint32_t frequency = rx_conf->frequency ; 00815 00816 _radio->lock(); 00817 00818 if (_radio->get_status() != RF_IDLE) { 00819 _radio->unlock(); 00820 return false; 00821 } 00822 00823 _radio->unlock(); 00824 00825 if (rx_conf->rx_slot == RX_SLOT_WIN_1 ) { 00826 // Apply window 1 frequency 00827 frequency = phy_params.channels.channel_list[rx_conf->channel ].frequency; 00828 // Apply the alternative RX 1 window frequency, if it is available 00829 if (phy_params.channels.channel_list[rx_conf->channel ].rx1_frequency != 0) { 00830 frequency = phy_params.channels.channel_list[rx_conf->channel ].rx1_frequency; 00831 } 00832 } 00833 00834 // Read the physical datarate from the datarates table 00835 uint8_t *datarate_table = (uint8_t *) phy_params.datarates.table; 00836 uint8_t *payload_table = (uint8_t *) phy_params.payloads.table; 00837 uint8_t *payload_with_repeater_table = (uint8_t *) phy_params.payloads_with_repeater.table; 00838 00839 phy_dr = datarate_table[dr]; 00840 00841 _radio->lock(); 00842 00843 _radio->set_channel(frequency); 00844 00845 // Radio configuration 00846 if (dr == DR_7 && phy_params.fsk_supported) { 00847 modem = MODEM_FSK; 00848 _radio->set_rx_config(modem, 50000, phy_dr * 1000, 0, 83333, 5, 00849 rx_conf->window_timeout , false, 0, true, 0, 0, 00850 false, rx_conf->is_rx_continuous ); 00851 } else { 00852 modem = MODEM_LORA; 00853 _radio->set_rx_config(modem, rx_conf->bandwidth , phy_dr, 1, 0, 8, 00854 rx_conf->window_timeout , false, 0, false, 0, 0, 00855 true, rx_conf->is_rx_continuous ); 00856 } 00857 00858 if (rx_conf->is_repeater_supported ) { 00859 max_payload = payload_with_repeater_table[dr]; 00860 } else { 00861 max_payload = payload_table[dr]; 00862 } 00863 00864 _radio->set_max_payload_length(modem, max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); 00865 00866 _radio->unlock(); 00867 00868 *datarate = phy_dr; 00869 00870 return true; 00871 } 00872 00873 bool LoRaPHY::tx_config(tx_config_params_t* tx_conf, int8_t* tx_power, 00874 lorawan_time_t* tx_toa) 00875 { 00876 radio_modems_t modem; 00877 int8_t phy_dr = ((uint8_t *)phy_params.datarates.table)[tx_conf->datarate]; 00878 channel_params_t *list = phy_params.channels.channel_list; 00879 uint8_t band_idx = list[tx_conf->channel].band ; 00880 band_t *bands = (band_t *)phy_params.bands.table; 00881 00882 // limit TX power if set to too much 00883 if (tx_conf->tx_power > bands[band_idx].max_tx_pwr ) { 00884 tx_conf->tx_power = bands[band_idx].max_tx_pwr ; 00885 } 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 || 00965 adr_settings.ch_mask_ctrl == 6) { 00966 00967 for (uint8_t i = 0; i < phy_params.max_channel_cnt; i++) { 00968 00969 // turn on all channels if channel mask control is 6 00970 if (adr_settings.ch_mask_ctrl == 6) { 00971 if (phy_params.channels.channel_list[i].frequency != 0) { 00972 mask_bit_set(temp_channel_mask, i); 00973 } 00974 00975 continue; 00976 } 00977 00978 // if channel mask control is 0, we test the bits and 00979 // frequencies and change the status if we find a discrepancy 00980 if ((mask_bit_test(temp_channel_mask, i)) && 00981 (phy_params.channels.channel_list[i].frequency == 0)) { 00982 // Trying to enable an undefined channel 00983 status &= 0xFE; // Channel mask KO 00984 } 00985 } 00986 } else { 00987 // Channel mask control applies to RFUs 00988 status &= 0xFE; // Channel mask KO 00989 } 00990 } 00991 00992 if (is_datarate_supported(adr_settings.datarate)) { 00993 verify_params.status = status; 00994 00995 verify_params.adr_enabled = link_adr_req->adr_enabled ; 00996 verify_params.current_datarate = link_adr_req->current_datarate ; 00997 verify_params.current_tx_power = link_adr_req->current_tx_power ; 00998 verify_params.current_nb_rep = link_adr_req->current_nb_rep ; 00999 01000 verify_params.datarate = adr_settings.datarate; 01001 verify_params.tx_power = adr_settings.tx_power; 01002 verify_params.nb_rep = adr_settings.nb_rep; 01003 01004 01005 verify_params.channel_mask = temp_channel_mask; 01006 01007 // Verify the parameters and update, if necessary 01008 status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, 01009 &adr_settings.tx_power, &adr_settings.nb_rep); 01010 } else { 01011 status &= 0xFD; // Datarate KO 01012 } 01013 01014 // Update channelsMask if everything is correct 01015 if (status == 0x07) { 01016 // Set the channels mask to a default value 01017 memset(phy_params.channels.mask, 0, 01018 sizeof(uint16_t)*phy_params.channels.mask_size); 01019 01020 // Update the channels mask 01021 copy_channel_mask(phy_params.channels.mask, temp_channel_mask, 01022 phy_params.channels.mask_size); 01023 } 01024 01025 // Update status variables 01026 *dr_out = adr_settings.datarate; 01027 *tx_power_out = adr_settings.tx_power; 01028 *nb_rep_out = adr_settings.nb_rep; 01029 *nb_bytes_processed = bytes_processed; 01030 01031 return status; 01032 } 01033 01034 uint8_t LoRaPHY::accept_rx_param_setup_req(rx_param_setup_req_t* params) 01035 { 01036 uint8_t status = 0x07; 01037 01038 // Verify radio frequency 01039 if (_radio->check_rf_frequency(params->frequency) == false) { 01040 status &= 0xFE; // Channel frequency KO 01041 } 01042 01043 // Verify datarate 01044 if (val_in_range(params->datarate, phy_params.min_rx_datarate, 01045 phy_params.max_rx_datarate) == 0) { 01046 status &= 0xFD; // Datarate KO 01047 } 01048 01049 // Verify datarate offset 01050 if (val_in_range(params->dr_offset, phy_params.min_rx1_dr_offset, 01051 phy_params.max_rx1_dr_offset) == 0) { 01052 status &= 0xFB; // Rx1DrOffset range KO 01053 } 01054 01055 return status; 01056 } 01057 01058 bool LoRaPHY::accept_tx_param_setup_req(uint8_t ul_dwell_time, uint8_t dl_dwell_time) 01059 { 01060 if (phy_params.accept_tx_param_setup_req) { 01061 phy_params.ul_dwell_time_setting = ul_dwell_time; 01062 phy_params.dl_dwell_time_setting = dl_dwell_time; 01063 } 01064 01065 return phy_params.accept_tx_param_setup_req; 01066 } 01067 01068 bool LoRaPHY::verify_frequency(uint32_t freq) 01069 { 01070 band_t *bands_table = (band_t *)phy_params.bands.table; 01071 01072 // check all sub bands (if there are sub-bands) to check if the given 01073 // frequency falls into any of the frequency ranges 01074 01075 for (uint8_t i=0; i<phy_params.bands.size; i++) { 01076 if (freq <= bands_table[i].higher_band_freq 01077 && freq >= bands_table[i].lower_band_freq) { 01078 return true; 01079 } 01080 } 01081 01082 return false; 01083 } 01084 01085 uint8_t LoRaPHY::dl_channel_request(uint8_t channel_id, uint32_t rx1_frequency) 01086 { 01087 if (!phy_params.dl_channel_req_supported) { 01088 return 0; 01089 } 01090 01091 uint8_t status = 0x03; 01092 01093 // Verify if the frequency is supported 01094 if (verify_frequency(rx1_frequency) == false) { 01095 status &= 0xFE; 01096 } 01097 01098 // Verify if an uplink frequency exists 01099 if (phy_params.channels.channel_list[channel_id].frequency == 0) { 01100 status &= 0xFD; 01101 } 01102 01103 // Apply Rx1 frequency, if the status is OK 01104 if (status == 0x03) { 01105 phy_params.channels.channel_list[channel_id].rx1_frequency = rx1_frequency; 01106 } 01107 01108 return status; 01109 } 01110 01111 /** 01112 * Alternate datarate algorithm for join requests. 01113 * - We check from the PHY and take note of total 01114 * number of data rates available upto the default data rate for 01115 * default channels. 01116 * 01117 * - Application sets a total number of re-trials for a Join Request, i.e., 01118 * MBED_CONF_LORA_NB_TRIALS. So MAC layer will send us a counter 01119 * nb_trials < MBED_CONF_LORA_NB_TRIALS which is the current number of trial. 01120 * 01121 * - We roll over total available datarates and pick one according to the 01122 * number of trial sequentially. 01123 * 01124 * - We always start from the Default Data rate and and set the next lower 01125 * data rate for every iteration. 01126 * 01127 * - MAC layer will stop when maximum number of re-trials, i.e., 01128 * MBED_CONF_LORA_NB_TRIALS is achieved. 01129 * 01130 * So essentially MBED_CONF_LORA_NB_TRIALS should be a multiple of range of 01131 * data rates available. For example, in EU868 band, default max. data rate is 01132 * DR_5 and min. data rate is DR_0, so total data rates available are 6. 01133 * 01134 * Hence MBED_CONF_LORA_NB_TRIALS should be a multiple of 6. Setting, 01135 * MBED_CONF_LORA_NB_TRIALS = 6 would mean that every data rate will be tried 01136 * exactly once starting from the largest and finishing at the smallest. 01137 * 01138 * PHY layers which do not have datarates scheme similar to EU band will ofcourse 01139 * override this method. 01140 */ 01141 int8_t LoRaPHY::get_alternate_DR(uint8_t nb_trials) 01142 { 01143 int8_t datarate = 0; 01144 uint8_t total_nb_datrates = (phy_params.default_max_datarate - phy_params.min_tx_datarate) + 1; 01145 01146 uint8_t res = nb_trials % total_nb_datrates; 01147 01148 if (res == 0) { 01149 datarate = phy_params.min_tx_datarate; 01150 } else if (res == 1) { 01151 datarate = phy_params.default_max_datarate; 01152 } else { 01153 datarate = (phy_params.default_max_datarate - res) + 1; 01154 } 01155 01156 return datarate; 01157 } 01158 01159 void LoRaPHY::calculate_backoff(bool joined, bool last_tx_was_join_req, bool dc_enabled, uint8_t channel, 01160 lorawan_time_t elapsed_time, lorawan_time_t tx_toa) 01161 { 01162 band_t *band_table = (band_t *) phy_params.bands.table; 01163 channel_params_t *channel_list = phy_params.channels.channel_list; 01164 01165 uint8_t band_idx = channel_list[channel].band ; 01166 uint16_t duty_cycle = band_table[band_idx].duty_cycle ; 01167 uint16_t join_duty_cycle = 0; 01168 01169 // Reset time-off to initial value. 01170 band_table[band_idx].off_time = 0; 01171 01172 if (joined == false) { 01173 // Get the join duty cycle 01174 if (elapsed_time < 3600000) { 01175 join_duty_cycle = BACKOFF_DC_1_HOUR; 01176 } else if (elapsed_time < (3600000 + 36000000)) { 01177 join_duty_cycle = BACKOFF_DC_10_HOURS; 01178 } else { 01179 join_duty_cycle = BACKOFF_DC_24_HOURS; 01180 } 01181 01182 // Apply the most restricting duty cycle 01183 duty_cycle = MAX(duty_cycle, join_duty_cycle); 01184 } 01185 01186 // No back-off if the last frame was not a join request and when the 01187 // duty cycle is not enabled 01188 if (dc_enabled == false && 01189 last_tx_was_join_req == false) { 01190 band_table[band_idx].off_time = 0; 01191 } else { 01192 // Apply band time-off. 01193 band_table[band_idx].off_time = tx_toa * duty_cycle - tx_toa; 01194 } 01195 } 01196 01197 lorawan_status_t LoRaPHY::set_next_channel(channel_selection_params_t* params, 01198 uint8_t* channel, lorawan_time_t* time, 01199 lorawan_time_t* aggregate_timeoff) 01200 { 01201 uint8_t channel_count = 0; 01202 uint8_t delay_tx = 0; 01203 01204 // Note here that the PHY layer implementations which have more than 01205 // 16 channels at their disposal, override this function. That's why 01206 // it is safe to assume that we are dealing with a block of 16 channels 01207 // i.e., EU like implementations. So rather than dynamically allocating 01208 // memory we chose to use a magic number of 16 01209 uint8_t enabled_channels[16]; 01210 01211 memset(enabled_channels, 0xFF, sizeof(uint8_t)*16); 01212 01213 lorawan_time_t next_tx_delay = 0; 01214 band_t *band_table = (band_t *) phy_params.bands.table; 01215 01216 if (num_active_channels(phy_params.channels.mask, 0, 01217 phy_params.channels.mask_size) == 0) { 01218 01219 // Reactivate default channels 01220 copy_channel_mask(phy_params.channels.mask, 01221 phy_params.channels.default_mask, 01222 phy_params.channels.mask_size); 01223 } 01224 01225 if (params->aggregate_timeoff 01226 <= _lora_time.get_elapsed_time(params->last_aggregate_tx_time)) { 01227 // Reset Aggregated time off 01228 *aggregate_timeoff = 0; 01229 01230 // Update bands Time OFF 01231 next_tx_delay = update_band_timeoff(params->joined, 01232 params->dc_enabled, 01233 band_table, phy_params.bands.size); 01234 01235 // Search how many channels are enabled 01236 channel_count = enabled_channel_count(params->joined, params->current_datarate, 01237 phy_params.channels.mask, 01238 enabled_channels, &delay_tx); 01239 } else { 01240 delay_tx++; 01241 next_tx_delay = params->aggregate_timeoff 01242 - _lora_time.get_elapsed_time(params->last_aggregate_tx_time); 01243 } 01244 01245 if (channel_count > 0) { 01246 // We found a valid channel 01247 *channel = enabled_channels[get_random(0, channel_count - 1)]; 01248 *time = 0; 01249 return LORAWAN_STATUS_OK; 01250 } 01251 01252 if (delay_tx > 0) { 01253 // Delay transmission due to AggregatedTimeOff or to a band time off 01254 *time = next_tx_delay; 01255 return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; 01256 } 01257 01258 // Datarate not supported by any channel, restore defaults 01259 copy_channel_mask(phy_params.channels.mask, 01260 phy_params.channels.default_mask, 01261 phy_params.channels.mask_size); 01262 *time = 0; 01263 return LORAWAN_STATUS_NO_CHANNEL_FOUND; 01264 } 01265 01266 lorawan_status_t LoRaPHY::add_channel(channel_params_t * new_channel, uint8_t id) 01267 { 01268 bool dr_invalid = false; 01269 bool freq_invalid = false; 01270 01271 if (!phy_params.custom_channelplans_supported 01272 || id >= phy_params.max_channel_cnt) { 01273 01274 return LORAWAN_STATUS_PARAMETER_INVALID; 01275 } 01276 01277 // Validate the datarate range 01278 if (val_in_range(new_channel->dr_range .fields.min , 01279 phy_params.min_tx_datarate, 01280 phy_params.max_tx_datarate) == 0) { 01281 dr_invalid = true; 01282 } 01283 01284 if (val_in_range(new_channel->dr_range .fields.max , phy_params.min_tx_datarate, 01285 phy_params.max_tx_datarate) == 0) { 01286 dr_invalid = true; 01287 } 01288 01289 if (new_channel->dr_range .fields.min > new_channel->dr_range .fields.max ) { 01290 dr_invalid = true; 01291 } 01292 01293 // Default channels don't accept all values 01294 if (id < phy_params.default_channel_cnt) { 01295 // Validate the datarate range for min: must be DR_0 01296 if (new_channel->dr_range .fields.min > phy_params.min_tx_datarate) { 01297 dr_invalid = true; 01298 } 01299 01300 // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE 01301 if (val_in_range(new_channel->dr_range .fields.max , 01302 phy_params.default_max_datarate, 01303 phy_params.max_tx_datarate) == 0) { 01304 dr_invalid = true; 01305 } 01306 01307 // We are not allowed to change the frequency 01308 if (new_channel->frequency != phy_params.channels.channel_list[id].frequency) { 01309 freq_invalid = true; 01310 } 01311 } 01312 01313 // Check frequency 01314 if (!freq_invalid) { 01315 if (verify_frequency(new_channel->frequency ) == false) { 01316 freq_invalid = true; 01317 } 01318 } 01319 01320 // Check status 01321 if (dr_invalid && freq_invalid) { 01322 return LORAWAN_STATUS_FREQ_AND_DR_INVALID; 01323 } 01324 01325 if (dr_invalid) { 01326 return LORAWAN_STATUS_DATARATE_INVALID; 01327 } 01328 01329 if (freq_invalid) { 01330 return LORAWAN_STATUS_FREQUENCY_INVALID; 01331 } 01332 01333 memcpy(&(phy_params.channels.channel_list[id]), new_channel, sizeof(channel_params_t )); 01334 01335 phy_params.channels.channel_list[id].band = new_channel->band ; 01336 01337 mask_bit_set(phy_params.channels.mask, id); 01338 01339 return LORAWAN_STATUS_OK; 01340 } 01341 01342 bool LoRaPHY::remove_channel(uint8_t channel_id) 01343 { 01344 // upper layers are checking if the custom channel planning is supported or 01345 // not. So we don't need to worry about that 01346 if (mask_bit_test(phy_params.channels.default_mask, channel_id)) { 01347 return false; 01348 } 01349 01350 01351 // Remove the channel from the list of channels 01352 const channel_params_t empty_channel = { 0, 0, {0}, 0 }; 01353 phy_params.channels.channel_list[channel_id] = empty_channel; 01354 01355 return disable_channel(phy_params.channels.mask, channel_id, 01356 phy_params.max_channel_cnt); 01357 } 01358 01359 void LoRaPHY::set_tx_cont_mode(cw_mode_params_t * params, uint32_t given_frequency) 01360 { 01361 band_t *bands_table = (band_t *) phy_params.bands.table; 01362 channel_params_t *channels = phy_params.channels.channel_list; 01363 01364 if (params->tx_power > bands_table[channels[params->channel ].band ].max_tx_pwr ) { 01365 params->tx_power = bands_table[channels[params->channel ].band].max_tx_pwr ; 01366 } 01367 01368 int8_t phy_tx_power = 0; 01369 uint32_t frequency = 0; 01370 01371 if (given_frequency == 0) { 01372 frequency = channels[params->channel ].frequency; 01373 } else { 01374 frequency = given_frequency; 01375 } 01376 01377 // Calculate physical TX power 01378 if (params->max_eirp > 0 && params->antenna_gain > 0) { 01379 phy_tx_power = compute_tx_power(params->tx_power , params->max_eirp , 01380 params->antenna_gain ); 01381 } else { 01382 phy_tx_power = params->tx_power ; 01383 } 01384 01385 _radio->lock(); 01386 _radio->set_tx_continuous_wave(frequency, phy_tx_power, params->timeout ); 01387 _radio->unlock(); 01388 } 01389 01390 uint8_t LoRaPHY::apply_DR_offset(int8_t dr, int8_t dr_offset) 01391 { 01392 int8_t datarate = dr - dr_offset; 01393 01394 if (datarate < 0) { 01395 datarate = phy_params.min_tx_datarate; 01396 } 01397 01398 return datarate; 01399 } 01400 01401
Generated on Tue Jul 12 2022 15:17:25 by
1.7.2