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