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