Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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