init
Embed:
(wiki syntax)
Show/hide line numbers
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:24:47 by
1.7.2