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