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:
commit
99c7ec57cf
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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]);
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user