takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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