Knight KE / Mbed OS Game_Master
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 "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     lorawan_status_t status;
00044 
00045     uint8_t max_num_channels;
00046 
00047     if (!_lora_phy->is_custom_channel_plan_supported()) {
00048         return LORAWAN_STATUS_SERVICE_UNKNOWN;
00049     }
00050 
00051     max_num_channels = _lora_phy->get_max_nb_channels();
00052 
00053     // check if user is setting more channels than supported
00054     if (plan.nb_channels > max_num_channels) {
00055         return LORAWAN_STATUS_PARAMETER_INVALID;
00056     }
00057 
00058     for (uint8_t i = 0; i < plan.nb_channels; i++) {
00059         status = _lora_phy->add_channel(&plan.channels[i].ch_param, plan.channels[i].id);
00060 
00061         if (status != LORAWAN_STATUS_OK) {
00062             return status;
00063         }
00064     }
00065 
00066     return LORAWAN_STATUS_OK;
00067 }
00068 
00069 lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan,
00070                                               const channel_params_t* channel_list)
00071 {
00072     uint8_t max_num_channels;
00073     uint16_t *channel_mask;
00074     uint8_t count = 0;
00075 
00076     if (!_lora_phy->is_custom_channel_plan_supported()) {
00077         return LORAWAN_STATUS_SERVICE_UNKNOWN;
00078     }
00079 
00080     max_num_channels = _lora_phy->get_max_nb_channels();
00081 
00082     channel_mask = _lora_phy->get_channel_mask(false);
00083 
00084     for (uint8_t i = 0; i < max_num_channels; i++) {
00085         // skip the channels which are not enabled
00086         if (_lora_phy->mask_bit_test(channel_mask, i) == 0) {
00087             continue;
00088         }
00089 
00090         // otherwise add them to the channel_plan struct
00091         plan.channels[count].id = i;
00092         plan.channels[count].ch_param.frequency = channel_list[i].frequency;
00093         plan.channels[count].ch_param.dr_range.value = channel_list[i].dr_range.value;
00094         plan.channels[count].ch_param.dr_range.fields.min = channel_list[i].dr_range.fields.min;
00095         plan.channels[count].ch_param.dr_range.fields.max = channel_list[i].dr_range.fields.max;
00096         plan.channels[count].ch_param.band = channel_list[i].band;
00097         plan.channels[count].ch_param.rx1_frequency = channel_list[i].rx1_frequency;
00098         count++;
00099     }
00100 
00101     plan.nb_channels = count;
00102 
00103     return LORAWAN_STATUS_OK;
00104 }
00105 
00106 lorawan_status_t LoRaMacChannelPlan::remove_plan()
00107 {
00108     lorawan_status_t status = LORAWAN_STATUS_OK;
00109 
00110     uint8_t max_num_channels;
00111     uint16_t *channel_mask;
00112     uint16_t *default_channel_mask;
00113 
00114     if (!_lora_phy->is_custom_channel_plan_supported()) {
00115         return LORAWAN_STATUS_SERVICE_UNKNOWN;
00116     }
00117 
00118     max_num_channels = _lora_phy->get_max_nb_channels();
00119 
00120     channel_mask = _lora_phy->get_channel_mask(false);
00121 
00122     default_channel_mask = _lora_phy->get_channel_mask(true);
00123 
00124     for (uint8_t i = 0; i < max_num_channels; i++) {
00125         // skip any default channels
00126         if (_lora_phy->mask_bit_test(default_channel_mask, i) != 0) {
00127             continue;
00128         }
00129 
00130         // skip any channels which are not currently enabled
00131         if (_lora_phy->mask_bit_test(channel_mask, i) == 0) {
00132             continue;
00133         }
00134 
00135         status = remove_single_channel(i);
00136 
00137         if (status != LORAWAN_STATUS_OK) {
00138             return status;
00139         }
00140     }
00141 
00142     return status;
00143 }
00144 
00145 lorawan_status_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id)
00146 {
00147     uint8_t max_num_channels;
00148 
00149     if (!_lora_phy->is_custom_channel_plan_supported()) {
00150         return LORAWAN_STATUS_SERVICE_UNKNOWN;
00151     }
00152 
00153     max_num_channels = _lora_phy->get_max_nb_channels();
00154 
00155     // According to specification channel IDs start from 0 and last valid
00156     // channel ID is N-1 where N=MAX_NUM_CHANNELS.
00157     // So any ID which is larger or equal to the Max number of channels is invalid
00158     if (channel_id >= max_num_channels) {
00159         return LORAWAN_STATUS_PARAMETER_INVALID;
00160     }
00161 
00162     if (_lora_phy->remove_channel(channel_id) == false) {
00163         return LORAWAN_STATUS_PARAMETER_INVALID;
00164     }
00165 
00166     _lora_phy->put_radio_to_sleep();
00167 
00168     return LORAWAN_STATUS_OK;
00169 }
00170