1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-28 07:51:19 +01:00

Merge pull request #15943 from jia200x/pr/gnrc_lorawan_channel_mask

net/gnrc_lorawan: implement channel mask support
This commit is contained in:
Leandro Lanzieri 2021-03-19 16:23:13 +01:00 committed by GitHub
commit 99c7ec57cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 26 deletions

View File

@ -284,6 +284,18 @@ void gnrc_lorawan_mlme_confirm(gnrc_lorawan_t *mac, mlme_confirm_t *confirm);
*/
netdev_t *gnrc_lorawan_get_netdev(gnrc_lorawan_t *mac);
/**
* @brief Set the channel mask in order to enable or disable LoRaWAN channels
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] channel_mask the channel mask. LSB maps to channel 0
*
* @return 0 on success
* @return -EINVAL if @p channel_mask is zero or if the channel mask tries to
* enable an undefined channel
*/
int gnrc_lorawan_phy_set_channel_mask(gnrc_lorawan_t *mac, uint16_t channel_mask);
#ifdef __cplusplus
}
#endif

View File

@ -144,6 +144,7 @@ void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, uint8_t *data,
gnrc_lorawan_process_cflist(mac, out + sizeof(lorawan_join_accept_t) - 1);
}
DEBUG("gnrc_lorawan: Channel mask is %04x\n", mac->channel_mask);
mac->mlme.activation = MLME_ACTIVATION_OTAA;
status = GNRC_LORAWAN_REQ_STATUS_SUCCESS;

View File

@ -13,6 +13,8 @@
* @author José Ignacio Alamos <jose.alamos@haw-hamburg.de>
*/
#include "kernel_defines.h"
#include "bitarithm.h"
#include "random.h"
#include "net/gnrc/lorawan/region.h"
#define ENABLE_DEBUG 0
@ -62,35 +64,27 @@ uint8_t gnrc_lorawan_rx1_get_dr_offset(uint8_t dr_up, uint8_t dr_offset)
}
#endif
static size_t _get_num_used_channels(gnrc_lorawan_t *mac)
int gnrc_lorawan_phy_set_channel_mask(gnrc_lorawan_t *mac, uint16_t channel_mask)
{
size_t count = 0;
if (!channel_mask) {
return -EINVAL;
}
for (unsigned i = 0; i < GNRC_LORAWAN_MAX_CHANNELS; i++) {
if (mac->channel[i]) {
count++;
for (int n = channel_mask, i = 0; n; n = n >> 1, i++) {
if ((n & 0x1) && !mac->channel[i]) {
return -EINVAL;
}
}
return count;
}
static uint32_t _get_nth_channel(gnrc_lorawan_t *mac, size_t n)
{
int i = 0;
uint32_t channel = 0;
while (n) {
if (mac->channel[i]) {
n--;
channel = mac->channel[i];
i++;
}
}
return channel;
mac->channel_mask = channel_mask;
return 0;
}
void gnrc_lorawan_channels_init(gnrc_lorawan_t *mac)
{
/* We set the channel mask for the default channels and populate from the list */
mac->channel_mask = UINT16_MAX >> (16 - GNRC_LORAWAN_DEFAULT_CHANNELS_NUMOF);
for (unsigned i = 0; i < GNRC_LORAWAN_DEFAULT_CHANNELS_NUMOF; i++) {
mac->channel[i] = gnrc_lorawan_default_channels[i];
DEBUG("gnrc_lorawan_region: Mac -> Channel %u %" PRIu32 " \n", i, mac->channel[i]);
@ -104,14 +98,15 @@ void gnrc_lorawan_channels_init(gnrc_lorawan_t *mac)
uint32_t gnrc_lorawan_pick_channel(gnrc_lorawan_t *mac)
{
netdev_t *netdev = gnrc_lorawan_get_netdev(mac);
uint32_t random_number;
uint8_t index = 0;
netdev->driver->get(netdev, NETOPT_RANDOM, &random_number,
sizeof(random_number));
uint8_t random_number = random_uint32_range(0, bitarithm_bits_set(mac->channel_mask));
unsigned state = mac->channel_mask;
return _get_nth_channel(mac,
1 + (random_number % _get_num_used_channels(mac)));
for (int i = 0; i < random_number; i++) {
state = bitarithm_test_and_clear(state, &index);
}
return mac->channel[index];
}
void gnrc_lorawan_process_cflist(gnrc_lorawan_t *mac, uint8_t *cflist)
@ -122,6 +117,7 @@ void gnrc_lorawan_process_cflist(gnrc_lorawan_t *mac, uint8_t *cflist)
cl.u32 = 0;
memcpy(&cl, cflist, GNRC_LORAWAN_CFLIST_ENTRY_SIZE);
mac->channel[i] = byteorder_ltohl(cl) * 100;
mac->channel_mask |= 1 << i;
cflist += GNRC_LORAWAN_CFLIST_ENTRY_SIZE;
DEBUG("gnrc_lorawan_region: Mac -> Channel %u %" PRIu32 " \n", i, mac->channel[i]);
}

View File

@ -185,6 +185,7 @@ typedef struct {
uint8_t *nwkskey; /**< pointer to Network SKey buffer */
uint8_t *appskey; /**< pointer to Application SKey buffer */
uint32_t channel[GNRC_LORAWAN_MAX_CHANNELS]; /**< channel array */
uint16_t channel_mask; /**< channel mask */
uint32_t toa; /**< Time on Air of the last transmission */
int busy; /**< MAC busy */
int shutdown_req; /**< MAC Shutdown request */