BA / SerialCom

Fork of OmniWheels by Gustav Atmel

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaMacChannelPlan.cpp Source File

LoRaMacChannelPlan.cpp

00001 /**
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007     (C)2013 Semtech
00008  ___ _____ _   ___ _  _____ ___  ___  ___ ___
00009 / __|_   _/_\ / __| |/ / __/ _ \| _ \/ __| __|
00010 \__ \ | |/ _ \ (__| ' <| _| (_) |   / (__| _|
00011 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
00012 embedded.connectivity.solutions===============
00013 
00014 Description: LoRaWAN stack layer that controls both MAC and PHY underneath
00015 
00016 License: Revised BSD License, see LICENSE.TXT file include in the project
00017 
00018 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
00019 
00020 
00021 Copyright (c) 2017, Arm Limited and affiliates.
00022 
00023 SPDX-License-Identifier: BSD-3-Clause
00024 */
00025 
00026 #include "lorastack/mac/LoRaMacChannelPlan.h"
00027 
00028 LoRaMacChannelPlan::LoRaMacChannelPlan() : _lora_phy(NULL)
00029 {
00030 }
00031 
00032 LoRaMacChannelPlan::~LoRaMacChannelPlan()
00033 {
00034 }
00035 
00036 void LoRaMacChannelPlan::activate_channelplan_subsystem(LoRaPHY *phy)
00037 {
00038     _lora_phy = phy;
00039 }
00040 
00041 lorawan_status_t LoRaMacChannelPlan::set_plan(const lorawan_channelplan_t& plan)
00042 {
00043     channel_params_t  mac_layer_ch_params;
00044     lorawan_status_t status;
00045 
00046     uint8_t max_num_channels;
00047 
00048     if (!_lora_phy->is_custom_channel_plan_supported()) {
00049         return LORAWAN_STATUS_SERVICE_UNKNOWN;
00050     }
00051 
00052     max_num_channels = _lora_phy->get_max_nb_channels();
00053 
00054     // check if user is setting more channels than supported
00055     if (plan.nb_channels > max_num_channels) {
00056         return LORAWAN_STATUS_PARAMETER_INVALID;
00057     }
00058 
00059     for (uint8_t i = 0; i < plan.nb_channels; i++) {
00060 
00061         mac_layer_ch_params.band  = plan.channels[i].ch_param.band;
00062 
00063         mac_layer_ch_params.dr_range .fields.max  = plan.channels[i].ch_param.dr_range.fields.max;
00064         mac_layer_ch_params.dr_range .fields.min  = plan.channels[i].ch_param.dr_range.fields.min;
00065         mac_layer_ch_params.dr_range .value  = plan.channels[i].ch_param.dr_range.value;
00066         mac_layer_ch_params.frequency  = plan.channels[i].ch_param.frequency;
00067         mac_layer_ch_params.rx1_frequency  = plan.channels[i].ch_param.rx1_frequency;
00068 
00069         status = _lora_phy->add_channel(&mac_layer_ch_params, plan.channels[i].id);
00070 
00071         if (status != LORAWAN_STATUS_OK) {
00072             return status;
00073         }
00074     }
00075 
00076     return LORAWAN_STATUS_OK;
00077 }
00078 
00079 lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan,
00080                                              const loramac_mib_req_confirm_t * mib_confirm)
00081 {
00082     if (mib_confirm == NULL) {
00083         return LORAWAN_STATUS_PARAMETER_INVALID;
00084     }
00085 
00086     uint8_t max_num_channels;
00087     uint16_t *channel_mask;
00088     uint8_t count = 0;
00089 
00090     if (!_lora_phy->is_custom_channel_plan_supported()) {
00091         return LORAWAN_STATUS_SERVICE_UNKNOWN;
00092     }
00093 
00094     max_num_channels = _lora_phy->get_max_nb_channels();
00095 
00096     channel_mask = _lora_phy->get_channel_mask(false);
00097 
00098     for (uint8_t i = 0; i < max_num_channels; i++) {
00099         // skip the channels which are not enabled
00100         if (_lora_phy->mask_bit_test(channel_mask, i) == 0) {
00101             continue;
00102         }
00103 
00104         // otherwise add them to the channel_plan struct
00105         plan.channels[count].id = i;
00106         plan.channels[count].ch_param.frequency = mib_confirm->param .channel_list [i].frequency ;
00107         plan.channels[count].ch_param.dr_range.value = mib_confirm->param .channel_list [i].dr_range .value ;
00108         plan.channels[count].ch_param.dr_range.fields.min = mib_confirm->param .channel_list [i].dr_range .fields.min ;
00109         plan.channels[count].ch_param.dr_range.fields.max = mib_confirm->param .channel_list [i].dr_range .fields.max ;
00110         plan.channels[count].ch_param.band = mib_confirm->param .channel_list [i].band ;
00111         plan.channels[count].ch_param.rx1_frequency = mib_confirm->param .channel_list [i].rx1_frequency ;
00112         count++;
00113     }
00114 
00115     plan.nb_channels = count;
00116 
00117     return LORAWAN_STATUS_OK;
00118 }
00119 
00120 lorawan_status_t LoRaMacChannelPlan::remove_plan()
00121 {
00122     lorawan_status_t status = LORAWAN_STATUS_OK;
00123 
00124     uint8_t max_num_channels;
00125     uint16_t *channel_mask;
00126     uint16_t *default_channel_mask;
00127 
00128     if (!_lora_phy->is_custom_channel_plan_supported()) {
00129         return LORAWAN_STATUS_SERVICE_UNKNOWN;
00130     }
00131 
00132     max_num_channels = _lora_phy->get_max_nb_channels();
00133 
00134     channel_mask = _lora_phy->get_channel_mask(false);
00135 
00136     default_channel_mask = _lora_phy->get_channel_mask(true);
00137 
00138     for (uint8_t i = 0; i < max_num_channels; i++) {
00139         // skip any default channels
00140         if (_lora_phy->mask_bit_test(default_channel_mask, i) != 0) {
00141             continue;
00142         }
00143 
00144         // skip any channels which are not currently enabled
00145         if (_lora_phy->mask_bit_test(channel_mask, i) == 0) {
00146             continue;
00147         }
00148 
00149         status = remove_single_channel(i);
00150 
00151         if (status != LORAWAN_STATUS_OK) {
00152             return status;
00153         }
00154     }
00155 
00156     return status;
00157 }
00158 
00159 lorawan_status_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id)
00160 {
00161     uint8_t max_num_channels;
00162 
00163     if (!_lora_phy->is_custom_channel_plan_supported()) {
00164         return LORAWAN_STATUS_SERVICE_UNKNOWN;
00165     }
00166 
00167     max_num_channels = _lora_phy->get_max_nb_channels();
00168 
00169     // According to specification channel IDs start from 0 and last valid
00170     // channel ID is N-1 where N=MAX_NUM_CHANNELS.
00171     // So any ID which is larger or equal to the Max number of channels is invalid
00172     if (channel_id >= max_num_channels) {
00173         return LORAWAN_STATUS_PARAMETER_INVALID;
00174     }
00175 
00176     if (_lora_phy->remove_channel(channel_id) == false) {
00177         return LORAWAN_STATUS_PARAMETER_INVALID;
00178     }
00179 
00180     _lora_phy->put_radio_to_sleep();
00181 
00182     return LORAWAN_STATUS_OK;
00183 }
00184