Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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), _mib(NULL) 00029 { 00030 } 00031 00032 LoRaMacChannelPlan::~LoRaMacChannelPlan() 00033 { 00034 } 00035 00036 void LoRaMacChannelPlan::activate_channelplan_subsystem(LoRaPHY *phy, LoRaMacMib *mib) 00037 { 00038 _lora_phy = phy; 00039 _mib = mib; 00040 } 00041 00042 lorawan_status_t LoRaMacChannelPlan::set_plan(const lorawan_channelplan_t& plan) 00043 { 00044 channel_params_t mac_layer_ch_params; 00045 lorawan_status_t status; 00046 00047 get_phy_params_t get_phy; 00048 phy_param_t phy_param; 00049 uint8_t max_num_channels; 00050 00051 // Check if the PHY layer supports custom channel plans or not. 00052 get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT ; 00053 phy_param = _lora_phy->get_phy_params(&get_phy); 00054 00055 if (!phy_param.value ) { 00056 return LORAWAN_STATUS_SERVICE_UNKNOWN; 00057 } 00058 00059 // Check first how many channels the selected PHY layer supports 00060 get_phy.attribute = PHY_MAX_NB_CHANNELS ; 00061 phy_param = _lora_phy->get_phy_params(&get_phy); 00062 max_num_channels = (uint8_t) phy_param.value ; 00063 00064 // check if user is setting more channels than supported 00065 if (plan.nb_channels > max_num_channels) { 00066 return LORAWAN_STATUS_PARAMETER_INVALID; 00067 } 00068 00069 for (uint8_t i = 0; i < plan.nb_channels; i++) { 00070 00071 mac_layer_ch_params.band = plan.channels[i].ch_param.band; 00072 00073 mac_layer_ch_params.dr_range .fields.max = plan.channels[i].ch_param.dr_range.fields.max; 00074 mac_layer_ch_params.dr_range .fields.min = plan.channels[i].ch_param.dr_range.fields.min; 00075 mac_layer_ch_params.dr_range .value = plan.channels[i].ch_param.dr_range.value; 00076 mac_layer_ch_params.frequency = plan.channels[i].ch_param.frequency; 00077 mac_layer_ch_params.rx1_frequency = plan.channels[i].ch_param.rx1_frequency; 00078 00079 status = _lora_phy->add_channel(&mac_layer_ch_params, plan.channels[i].id); 00080 00081 if (status != LORAWAN_STATUS_OK) { 00082 return status; 00083 } 00084 } 00085 00086 return LORAWAN_STATUS_OK; 00087 } 00088 00089 lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan, 00090 loramac_protocol_params *params) 00091 { 00092 if (params == NULL) { 00093 return LORAWAN_STATUS_PARAMETER_INVALID; 00094 } 00095 00096 loramac_mib_req_confirm_t mib_confirm; 00097 lorawan_status_t status; 00098 00099 get_phy_params_t get_phy; 00100 phy_param_t phy_param; 00101 uint8_t max_num_channels; 00102 uint16_t *channel_mask; 00103 uint8_t count = 0; 00104 00105 // Check if the PHY layer supports custom channel plans or not. 00106 get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT ; 00107 phy_param = _lora_phy->get_phy_params(&get_phy); 00108 00109 if (!phy_param.value ) { 00110 return LORAWAN_STATUS_SERVICE_UNKNOWN; 00111 } 00112 00113 // Check first how many channels the selected PHY layer supports 00114 get_phy.attribute = PHY_MAX_NB_CHANNELS ; 00115 phy_param = _lora_phy->get_phy_params(&get_phy); 00116 max_num_channels = (uint8_t) phy_param.value ; 00117 00118 // Now check the Default channel mask 00119 get_phy.attribute = PHY_CHANNEL_MASK ; 00120 phy_param = _lora_phy->get_phy_params(&get_phy); 00121 channel_mask = phy_param.channel_mask ; 00122 00123 // Request Mib to get channels 00124 memset(&mib_confirm, 0, sizeof(mib_confirm)); 00125 mib_confirm.type = MIB_CHANNELS ; 00126 00127 status = _mib->get_request(&mib_confirm, params); 00128 00129 if (status != LORAWAN_STATUS_OK) { 00130 return status; 00131 } 00132 00133 for (uint8_t i = 0; i < max_num_channels; i++) { 00134 // skip the channels which are not enabled 00135 if (_lora_phy->mask_bit_test(channel_mask, i) == 0) { 00136 continue; 00137 } 00138 00139 // otherwise add them to the channel_plan struct 00140 plan.channels[count].id = i; 00141 plan.channels[count].ch_param.frequency = mib_confirm.param .channel_list [i].frequency ; 00142 plan.channels[count].ch_param.dr_range.value = mib_confirm.param .channel_list [i].dr_range .value ; 00143 plan.channels[count].ch_param.dr_range.fields.min = mib_confirm.param .channel_list [i].dr_range .fields.min ; 00144 plan.channels[count].ch_param.dr_range.fields.max = mib_confirm.param .channel_list [i].dr_range .fields.max ; 00145 plan.channels[count].ch_param.band = mib_confirm.param .channel_list [i].band ; 00146 plan.channels[count].ch_param.rx1_frequency = mib_confirm.param .channel_list [i].rx1_frequency ; 00147 count++; 00148 } 00149 00150 plan.nb_channels = count; 00151 00152 return LORAWAN_STATUS_OK; 00153 } 00154 00155 lorawan_status_t LoRaMacChannelPlan::remove_plan() 00156 { 00157 lorawan_status_t status = LORAWAN_STATUS_OK; 00158 00159 get_phy_params_t get_phy; 00160 phy_param_t phy_param; 00161 uint8_t max_num_channels; 00162 uint16_t *channel_mask; 00163 uint16_t *default_channel_mask; 00164 00165 // Check if the PHY layer supports custom channel plans or not. 00166 get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT ; 00167 phy_param = _lora_phy->get_phy_params(&get_phy); 00168 00169 if (!phy_param.value ) { 00170 return LORAWAN_STATUS_SERVICE_UNKNOWN; 00171 } 00172 00173 // Check first how many channels the selected PHY layer supports 00174 get_phy.attribute = PHY_MAX_NB_CHANNELS ; 00175 phy_param = _lora_phy->get_phy_params(&get_phy); 00176 max_num_channels = (uint8_t) phy_param.value ; 00177 00178 // Now check the channel mask for enabled channels 00179 get_phy.attribute = PHY_CHANNEL_MASK ; 00180 phy_param = _lora_phy->get_phy_params(&get_phy); 00181 channel_mask = phy_param.channel_mask ; 00182 00183 // Now check the channel mask for default channels 00184 get_phy.attribute = PHY_DEFAULT_CHANNEL_MASK ; 00185 phy_param = _lora_phy->get_phy_params(&get_phy); 00186 default_channel_mask = phy_param.channel_mask ; 00187 00188 for (uint8_t i = 0; i < max_num_channels; i++) { 00189 // skip any default channels 00190 if (_lora_phy->mask_bit_test(default_channel_mask, i) != 0) { 00191 continue; 00192 } 00193 00194 // skip any channels which are not currently enabled 00195 if (_lora_phy->mask_bit_test(channel_mask, i) == 0) { 00196 continue; 00197 } 00198 00199 status = remove_single_channel(i); 00200 00201 if (status != LORAWAN_STATUS_OK) { 00202 return status; 00203 } 00204 } 00205 00206 return status; 00207 } 00208 00209 lorawan_status_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id) 00210 { 00211 get_phy_params_t get_phy; 00212 phy_param_t phy_param; 00213 uint8_t max_num_channels; 00214 00215 // Check if the PHY layer supports custom channel plans or not. 00216 get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT ; 00217 phy_param = _lora_phy->get_phy_params(&get_phy); 00218 00219 if (!phy_param.value ) { 00220 return LORAWAN_STATUS_SERVICE_UNKNOWN; 00221 } 00222 00223 // Check first how many channels the selected PHY layer supports 00224 get_phy.attribute = PHY_MAX_NB_CHANNELS ; 00225 phy_param = _lora_phy->get_phy_params(&get_phy); 00226 max_num_channels = (uint8_t) phy_param.value ; 00227 00228 // According to specification channel IDs start from 0 and last valid 00229 // channel ID is N-1 where N=MAX_NUM_CHANNELS. 00230 // So any ID which is larger or equal to the Max number of channels is invalid 00231 if (channel_id >= max_num_channels) { 00232 return LORAWAN_STATUS_PARAMETER_INVALID; 00233 } 00234 00235 if (_lora_phy->remove_channel(channel_id) == false) { 00236 return LORAWAN_STATUS_PARAMETER_INVALID; 00237 } 00238 00239 _lora_phy->put_radio_to_sleep(); 00240 00241 return LORAWAN_STATUS_OK; 00242 } 00243
Generated on Tue Jul 12 2022 13:30:21 by
