Skip to content

Commit 6ea541c

Browse files
author
Hasnain Virk
committed
[IOTCELL-286] Adding Channel Plan subsystem
Channel planning was distributed over LoRaWANStack and LoRaMac previously. We now centralize it by allocating the service to its own class. Thus making the workflow consistent, i.e., Request for channel plan = Application->Interface->stack->Mac->ChannelPlan Major change apart from adding the channel plan subsystem are the API changes in LoRaMac class.
1 parent 34c034d commit 6ea541c

File tree

6 files changed

+428
-178
lines changed

6 files changed

+428
-178
lines changed

features/lorawan/LoRaWANInterface.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ class LoRaWANInterface: public LoRaWANBase {
226226
* is already active, the request is silently ignored. A negative error
227227
* code is returned if there is any problem with parameters.
228228
*
229+
* Please note that this API can also be used to add a single channel to the
230+
* existing channel plan.
231+
*
229232
* There is no reverse mechanism in the 1.0.2 specification for a node to request
230233
* a particular channel. Only the network server can initiate such a request.
231234
* You need to ensure that the corresponding base station supports the channel or channels being added.

features/lorawan/LoRaWANStack.cpp

Lines changed: 6 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -471,91 +471,19 @@ lora_mac_status_t LoRaWANStack::add_channels(const lora_channelplan_t &channel_p
471471
return LORA_MAC_STATUS_NOT_INITIALIZED;
472472
}
473473

474-
ChannelParams_t mac_layer_ch_params;
475-
LoRaMacStatus_t status;
474+
LoRaMacStatus_t status = _loramac.AddChannelPlan(channel_plan);
476475

477-
GetPhyParams_t get_phy;
478-
PhyParam_t phy_param;
479-
uint8_t max_num_channels;
480-
481-
// Check first how many channels the selected PHY layer supports
482-
get_phy.Attribute = PHY_MAX_NB_CHANNELS;
483-
phy_param = _lora_phy.get_phy_params(&get_phy);
484-
max_num_channels = (uint8_t) phy_param.Value;
485-
486-
// check if user is setting more channels than supported
487-
if (channel_plan.nb_channels > max_num_channels) {
488-
return LORA_MAC_STATUS_PARAMETER_INVALID;
489-
}
490-
491-
for (uint8_t i = 0; i < channel_plan.nb_channels; i++) {
492-
mac_layer_ch_params.Band = channel_plan.channels[i].ch_param.band;
493-
mac_layer_ch_params.DrRange.Fields.Max = channel_plan.channels[i].ch_param.dr_range.lora_mac_fields_s.max;
494-
mac_layer_ch_params.DrRange.Fields.Min = channel_plan.channels[i].ch_param.dr_range.lora_mac_fields_s.min;
495-
mac_layer_ch_params.DrRange.Value = channel_plan.channels[i].ch_param.dr_range.value;
496-
mac_layer_ch_params.Frequency = channel_plan.channels[i].ch_param.frequency;
497-
mac_layer_ch_params.Rx1Frequency =channel_plan.channels[i].ch_param.rx1_frequency;
498-
499-
status = _loramac.LoRaMacChannelAdd(channel_plan.channels[i].id, mac_layer_ch_params);
500-
501-
if (status != LORAMAC_STATUS_OK) {
502-
return error_type_converter(status);
503-
}
504-
}
505-
506-
return LORA_MAC_STATUS_OK;
476+
return error_type_converter(status);
507477
}
508478

509479
lora_mac_status_t LoRaWANStack::drop_channel_list()
510480
{
511-
if (_device_current_state == DEVICE_STATE_NOT_INITIALIZED )
512-
{
481+
if (_device_current_state == DEVICE_STATE_NOT_INITIALIZED) {
513482
tr_error("Stack not initialized!");
514483
return LORA_MAC_STATUS_NOT_INITIALIZED;
515484
}
516485

517-
lora_mac_status_t status = LORA_MAC_STATUS_OK;
518-
519-
GetPhyParams_t get_phy;
520-
PhyParam_t phy_param;
521-
uint8_t max_num_channels;
522-
uint16_t *channel_masks;
523-
uint16_t *default_channel_masks;
524-
525-
// Check first how many channels the selected PHY layer supports
526-
get_phy.Attribute = PHY_MAX_NB_CHANNELS;
527-
phy_param = _lora_phy.get_phy_params(&get_phy);
528-
max_num_channels = (uint8_t) phy_param.Value;
529-
530-
// Now check the channel mask for enabled channels
531-
get_phy.Attribute = PHY_CHANNELS_MASK;
532-
phy_param = _lora_phy.get_phy_params(&get_phy);
533-
channel_masks = phy_param.ChannelsMask;
534-
535-
// Now check the channel mask for default channels
536-
get_phy.Attribute = PHY_CHANNELS_DEFAULT_MASK;
537-
phy_param = _lora_phy.get_phy_params(&get_phy);
538-
default_channel_masks = phy_param.ChannelsMask;
539-
540-
for (uint8_t i = 0; i < max_num_channels; i++) {
541-
// skip any default channels
542-
if ((default_channel_masks[0] & (1U<<i)) != 0) {
543-
continue;
544-
}
545-
546-
// skip any channels which are not currently enabled
547-
if ((channel_masks[0] & (1U<<i)) == 0) {
548-
continue;
549-
}
550-
551-
status = error_type_converter(_loramac.LoRaMacChannelRemove(i));
552-
553-
if (status != LORA_MAC_STATUS_OK) {
554-
return status;
555-
}
556-
}
557-
558-
return status;
486+
return error_type_converter(_loramac.RemoveChannelPlan());
559487
}
560488

561489
lora_mac_status_t LoRaWANStack::remove_a_channel(uint8_t channel_id)
@@ -566,38 +494,7 @@ lora_mac_status_t LoRaWANStack::remove_a_channel(uint8_t channel_id)
566494
return LORA_MAC_STATUS_NOT_INITIALIZED;
567495
}
568496

569-
GetPhyParams_t get_phy;
570-
PhyParam_t phy_param;
571-
uint8_t max_num_channels;
572-
uint16_t *channel_masks;
573-
574-
// Check first how many channels the selected PHY layer supports
575-
get_phy.Attribute = PHY_MAX_NB_CHANNELS;
576-
phy_param = _lora_phy.get_phy_params(&get_phy);
577-
max_num_channels = (uint8_t) phy_param.Value;
578-
579-
// According to specification channel IDs start from 0 and last valid
580-
// channel ID is N-1 where N=MAX_NUM_CHANNELS.
581-
// So any ID which is larger or equal to the Max number of channels is invalid
582-
if (channel_id >= max_num_channels) {
583-
return LORA_MAC_STATUS_PARAMETER_INVALID;
584-
}
585-
586-
// Now check the Default channel mask
587-
get_phy.Attribute = PHY_CHANNELS_DEFAULT_MASK;
588-
phy_param = _lora_phy.get_phy_params(&get_phy);
589-
channel_masks = phy_param.ChannelsMask;
590-
591-
// check if the channel ID give belongs to a default channel
592-
// Mostly the default channels are in the first mask if the region
593-
// have multiple channel masks for various sub-bands. So we check the first
594-
// mask only and return an error code if user sent a default channel id
595-
if ((channel_masks[0] & (1U << channel_id)) != 0) {
596-
tr_error("Not allowed to remove a Default Channel.");
597-
return LORA_MAC_STATUS_PARAMETER_INVALID;
598-
}
599-
600-
return error_type_converter(_loramac.LoRaMacChannelRemove(channel_id));
497+
return error_type_converter(_loramac.RemoveSingleChannel(channel_id));
601498
}
602499

603500
lora_mac_status_t LoRaWANStack::get_enabled_channels(lora_channelplan_t& channel_plan)
@@ -610,49 +507,7 @@ lora_mac_status_t LoRaWANStack::get_enabled_channels(lora_channelplan_t& channel
610507
return LORA_MAC_STATUS_BUSY;
611508
}
612509

613-
lora_mac_mib_request_confirm_t mib_params;
614-
615-
GetPhyParams_t get_phy;
616-
PhyParam_t phy_param;
617-
uint8_t max_num_channels;
618-
uint16_t *channel_masks;
619-
uint8_t count = 0;
620-
621-
// Check first how many channels the selected PHY layer supports
622-
get_phy.Attribute = PHY_MAX_NB_CHANNELS;
623-
phy_param = _lora_phy.get_phy_params(&get_phy);
624-
max_num_channels = (uint8_t) phy_param.Value;
625-
626-
// Now check the Default channel mask
627-
get_phy.Attribute = PHY_CHANNELS_MASK;
628-
phy_param = _lora_phy.get_phy_params(&get_phy);
629-
channel_masks = phy_param.ChannelsMask;
630-
631-
// Request Mib to get channels
632-
memset(&mib_params, 0, sizeof(mib_params));
633-
mib_params.type = LORA_MIB_CHANNELS;
634-
mib_get_request(&mib_params);
635-
636-
for (uint8_t i = 0; i < max_num_channels; i++) {
637-
// skip the channels which are not enabled
638-
if ((channel_masks[0] & (1U << i)) == 0) {
639-
continue;
640-
}
641-
642-
// otherwise add them to the channel_plan struct
643-
channel_plan.channels[count].id = i;
644-
channel_plan.channels[count].ch_param.frequency = mib_params.param.channel_list[i].frequency;
645-
channel_plan.channels[count].ch_param.dr_range.value = mib_params.param.channel_list[i].dr_range.value;
646-
channel_plan.channels[count].ch_param.dr_range.lora_mac_fields_s.min = mib_params.param.channel_list[i].dr_range.lora_mac_fields_s.min;
647-
channel_plan.channels[count].ch_param.dr_range.lora_mac_fields_s.max = mib_params.param.channel_list[i].dr_range.lora_mac_fields_s.max;
648-
channel_plan.channels[count].ch_param.band = mib_params.param.channel_list[i].band;
649-
channel_plan.channels[count].ch_param.rx1_frequency = mib_params.param.channel_list[i].rx1_frequency;
650-
count++;
651-
}
652-
653-
channel_plan.nb_channels = count;
654-
655-
return LORA_MAC_STATUS_OK;
510+
return error_type_converter(_loramac.GetChannelPlan(channel_plan));
656511
}
657512

658513
lora_mac_status_t LoRaWANStack::enable_adaptive_datarate(bool adr_enabled)

features/lorawan/lorastack/mac/LoRaMac.cpp

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,6 +1704,9 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives,
17041704
// Activate MIB subsystem
17051705
mib.activate_mib_subsystem(this, lora_phy);
17061706

1707+
// Activate channel planning subsystem
1708+
ch_plan.activate_channelplan_subsystem(lora_phy, &mib);
1709+
17071710
LoRaMacPrimitives = primitives;
17081711
LoRaMacCallbacks = callbacks;
17091712

@@ -1889,10 +1892,8 @@ LoRaMacStatus_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t*
18891892
return LORAMAC_STATUS_OK;
18901893
}
18911894

1892-
LoRaMacStatus_t LoRaMac::LoRaMacChannelAdd( uint8_t id, ChannelParams_t params )
1895+
LoRaMacStatus_t LoRaMac::AddChannelPlan(const lora_channelplan_t& plan)
18931896
{
1894-
ChannelAddParams_t channelAdd;
1895-
18961897
// Validate if the MAC is in a correct state
18971898
if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
18981899
{
@@ -1902,16 +1903,11 @@ LoRaMacStatus_t LoRaMac::LoRaMacChannelAdd( uint8_t id, ChannelParams_t params )
19021903
}
19031904
}
19041905

1905-
channelAdd.NewChannel = &params;
1906-
channelAdd.ChannelId = id;
1907-
1908-
return lora_phy->add_channel(&channelAdd);
1906+
return ch_plan.set_plan(plan);
19091907
}
19101908

1911-
LoRaMacStatus_t LoRaMac::LoRaMacChannelRemove( uint8_t id )
1909+
LoRaMacStatus_t LoRaMac::RemoveChannelPlan()
19121910
{
1913-
ChannelRemoveParams_t channelRemove;
1914-
19151911
if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
19161912
{
19171913
if( ( _params.LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
@@ -1920,16 +1916,26 @@ LoRaMacStatus_t LoRaMac::LoRaMacChannelRemove( uint8_t id )
19201916
}
19211917
}
19221918

1923-
channelRemove.ChannelId = id;
1919+
return ch_plan.remove_plan();
1920+
1921+
}
19241922

1925-
if(lora_phy->remove_channel(&channelRemove) == false)
1923+
LoRaMacStatus_t LoRaMac::GetChannelPlan(lora_channelplan_t& plan)
1924+
{
1925+
return ch_plan.get_plan(plan, &_params);
1926+
}
1927+
1928+
LoRaMacStatus_t LoRaMac::RemoveSingleChannel(uint8_t id)
1929+
{
1930+
if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
19261931
{
1927-
return LORAMAC_STATUS_PARAMETER_INVALID;
1932+
if( ( _params.LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
1933+
{
1934+
return LORAMAC_STATUS_BUSY;
1935+
}
19281936
}
19291937

1930-
lora_phy->put_radio_to_sleep();
1931-
1932-
return LORAMAC_STATUS_OK;
1938+
return ch_plan.remove_single_channel(id);
19331939
}
19341940

19351941
LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelLink( MulticastParams_t *channelParam )

features/lorawan/lorastack/mac/LoRaMac.h

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
#include "lorastack/mac/LoRaMacMlme.h"
5050
#include "lorastack/mac/LoRaMacMcps.h"
5151
#include "lorastack/mac/LoRaMacMib.h"
52-
52+
#include "lorastack/mac/LoRaMacChannelPlan.h"
5353

5454
class LoRaMac
5555
{
@@ -117,27 +117,57 @@ class LoRaMac
117117
LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo );
118118

119119
/*!
120-
* \brief LoRaMAC channel add service.
120+
* \brief Adds a channel plan to the system.
121+
*
122+
* \details Adds a whole channel plan or a single new channel to the.
123+
* Please note that this functionality is not available in all regions.
124+
* Information on the allowed ranges is available at the
125+
* LoRaWAN Regional Parameters V1.0.2rB.
126+
*
127+
* \param plan [in] - A reference to application provided channel plan.
128+
*
129+
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
130+
* \ref LORAMAC_STATUS_OK
131+
* \ref LORAMAC_STATUS_BUSY
132+
* \ref LORAMAC_STATUS_PARAMETER_INVALID
133+
*/
134+
LoRaMacStatus_t AddChannelPlan(const lora_channelplan_t& plan);
135+
136+
/*!
137+
* \brief Removes a channel plan from the system.
121138
*
122-
* \details Adds a new channel to the channel list and activates the ID in
123-
* the channel mask. Please note that this functionality is not available
124-
* in all regions. Information on the allowed ranges is available at the LoRaWAN Regional Parameters V1.0.2rB.
139+
* \details Removes the whole active channel plan except the 'Default Channels'..
140+
* Please note that this functionality is not available in all regions.
141+
* Information on the allowed ranges is available at the
142+
* LoRaWAN Regional Parameters V1.0.2rB.
125143
*
126-
* \param id [in] - The ID of the channel.
144+
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
145+
* \ref LORAMAC_STATUS_OK
146+
* \ref LORAMAC_STATUS_BUSY
147+
* \ref LORAMAC_STATUS_PARAMETER_INVALID
148+
*/
149+
LoRaMacStatus_t RemoveChannelPlan();
150+
151+
/*!
152+
* \brief Access active channel plan.
153+
*
154+
* \details Provides access to the current active channel plan.
127155
*
128-
* \param params [in] - The channel parameters to set.
156+
* \param plan [out] - A reference to application provided channel plan data
157+
* structure which will be filled in with active channel
158+
* plan.
129159
*
130160
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
131161
* \ref LORAMAC_STATUS_OK
132162
* \ref LORAMAC_STATUS_BUSY
133163
* \ref LORAMAC_STATUS_PARAMETER_INVALID
134164
*/
135-
LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params );
165+
LoRaMacStatus_t GetChannelPlan(lora_channelplan_t& plan);
136166

137167
/*!
138-
* \brief LoRaMAC channel remove service.
168+
* \brief Remove a given channel from the active plan.
139169
*
140-
* \details Deactivates the ID in the channel mask.
170+
* \details Deactivates the given channel.
141171
*
142172
* \param id - Id of the channel.
143173
*
@@ -146,7 +176,7 @@ class LoRaMac
146176
* \ref LORAMAC_STATUS_BUSY
147177
* \ref LORAMAC_STATUS_PARAMETER_INVALID
148178
*/
149-
LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id );
179+
LoRaMacStatus_t RemoveSingleChannel( uint8_t id );
150180

151181
/*!
152182
* \brief LoRaMAC multicast channel link service.
@@ -626,6 +656,11 @@ class LoRaMac
626656
*/
627657
LoRaMacMib mib;
628658

659+
/**
660+
* Channel planning subsystem
661+
*/
662+
LoRaMacChannelPlan ch_plan;
663+
629664
/**
630665
* Timer subsystem handle
631666
*/

0 commit comments

Comments
 (0)