Kenji Arai / TYBLE16_mbedlized_os5_several_examples_1st

Dependencies:   nRF51_Vdd TextLCD BME280

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