Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaPHY.cpp Source File

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