1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 14:33:52 +01:00

Merge pull request #12866 from jia200x/pr/gnrc_lorawan_remove_netdev

net/gnrc_lorawan: remove netdev layer from MAC
This commit is contained in:
Sebastian Meiling 2020-01-30 14:02:59 +01:00 committed by GitHub
commit a4c4c25b3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 193 additions and 201 deletions

View File

@ -246,12 +246,6 @@ typedef enum {
NETDEV_EVENT_CRC_ERROR, /**< wrong CRC */
NETDEV_EVENT_FHSS_CHANGE_CHANNEL, /**< channel changed */
NETDEV_EVENT_CAD_DONE, /**< channel activity detection done */
NETDEV_EVENT_MLME_CONFIRM, /**< MAC MLME confirm event */
NETDEV_EVENT_MLME_INDICATION, /**< MAC MLME indication event */
NETDEV_EVENT_MCPS_CONFIRM, /**< MAC MCPS confirm event */
NETDEV_EVENT_MCPS_INDICATION, /**< MAC MCPS indication event */
NETDEV_EVENT_MLME_GET_BUFFER, /**< MAC layer requests MLME buffer */
NETDEV_EVENT_MCPS_GET_BUFFER, /**< MAC layer requests MCPS buffer */
/* expand this list if needed */
} netdev_event_t;

View File

@ -79,7 +79,9 @@ typedef enum {
* @brief MAC Information Base attributes
*/
typedef enum {
MIB_ACTIVATION_METHOD /**< type is activation method */
MIB_ACTIVATION_METHOD, /**< type is activation method */
MIB_DEV_ADDR, /**< type is dev addr */
MIB_RX2_DR, /**< type is rx2 DR */
} mlme_mib_type_t;
/**
@ -109,6 +111,8 @@ typedef struct {
mlme_mib_type_t type; /**< MIB attribute identifier */
union {
mlme_activation_t activation; /**< holds activation mechanism */
void *dev_addr; /**< pointer to the dev_addr */
uint8_t rx2_dr; /** datarate of second rx window */
};
} mlme_mib_t;
@ -230,12 +234,50 @@ void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_r
void gnrc_lorawan_recv(gnrc_lorawan_t *mac);
/**
* @brief Setup GNRC LoRaWAN netdev layers
* @brief MCPS indication callback
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param mac pointer to the MAC descriptor
* @param lower pointer to the lower netdev device (radio)
* @param[in] mac pointer to the MAC descriptor
* @param[in] ind pointer of the indication (see @ref mcps_indication_t)
*/
void gnrc_lorawan_setup(gnrc_lorawan_t *mac, netdev_t *lower);
void gnrc_lorawan_mcps_indication(gnrc_lorawan_t *mac, mcps_indication_t *ind);
/**
* @brief MLME indication callback
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] ind pointer of the indication (see @ref mlme_indication_t)
*/
void gnrc_lorawan_mlme_indication(gnrc_lorawan_t *mac, mlme_indication_t *ind);
/**
* @brief MCPS Confirm callback
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] confirm pointer to the confirm (see @ref mcps_confirm_t)
*/
void gnrc_lorawan_mcps_confirm(gnrc_lorawan_t *mac, mcps_confirm_t *confirm);
/**
* @brief MLME confirm callback
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] confirm pointer to the confirm (see @ref mlme_confirm_t)
*/
void gnrc_lorawan_mlme_confirm(gnrc_lorawan_t *mac, mlme_confirm_t *confirm);
/**
* @brief Get netdev pointer from mac descriptor
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
*
* @return pointer to the @ref netdev_t structure
*/
netdev_t *gnrc_lorawan_get_netdev(gnrc_lorawan_t *mac);
#ifdef __cplusplus
}

View File

@ -61,7 +61,7 @@ static inline void gnrc_lorawan_mcps_reset(gnrc_lorawan_t *mac)
mac->mcps.fcnt_down = 0;
}
static inline void _set_rx2_dr(gnrc_lorawan_t *mac, uint8_t rx2_dr)
void gnrc_lorawan_set_rx2_dr(gnrc_lorawan_t *mac, uint8_t rx2_dr)
{
mac->dl_settings &= ~GNRC_LORAWAN_DL_RX2_DR_MASK;
mac->dl_settings |= (rx2_dr << GNRC_LORAWAN_DL_RX2_DR_POS) &
@ -70,9 +70,10 @@ static inline void _set_rx2_dr(gnrc_lorawan_t *mac, uint8_t rx2_dr)
static void _sleep_radio(gnrc_lorawan_t *mac)
{
netdev_t *dev = gnrc_lorawan_get_netdev(mac);
netopt_state_t state = NETOPT_STATE_SLEEP;
netdev_set_pass((netdev_t *) mac, NETOPT_STATE, &state, sizeof(state));
dev->driver->set(dev, NETOPT_STATE, &state, sizeof(state));
}
void gnrc_lorawan_init(gnrc_lorawan_t *mac, uint8_t *nwkskey, uint8_t *appskey)
@ -86,19 +87,20 @@ void gnrc_lorawan_init(gnrc_lorawan_t *mac, uint8_t *nwkskey, uint8_t *appskey)
void gnrc_lorawan_reset(gnrc_lorawan_t *mac)
{
netdev_t *dev = gnrc_lorawan_get_netdev(mac);
uint8_t cr = LORA_CR_4_5;
netdev_set_pass(&mac->netdev, NETOPT_CODING_RATE, &cr, sizeof(cr));
dev->driver->set(dev, NETOPT_CODING_RATE, &cr, sizeof(cr));
uint8_t syncword = LORAMAC_DEFAULT_PUBLIC_NETWORK ? LORA_SYNCWORD_PUBLIC
: LORA_SYNCWORD_PRIVATE;
netdev_set_pass(&mac->netdev, NETOPT_SYNCWORD, &syncword, sizeof(syncword));
dev->driver->set(dev, NETOPT_SYNCWORD, &syncword, sizeof(syncword));
/* Continuous reception */
uint32_t rx_timeout = 0;
netdev_set_pass(&mac->netdev, NETOPT_RX_TIMEOUT, &rx_timeout, sizeof(rx_timeout));
dev->driver->set(dev, NETOPT_RX_TIMEOUT, &rx_timeout, sizeof(rx_timeout));
_set_rx2_dr(mac, LORAMAC_DEFAULT_RX2_DR);
gnrc_lorawan_set_rx2_dr(mac, LORAMAC_DEFAULT_RX2_DR);
mac->toa = 0;
gnrc_lorawan_mcps_reset(mac);
@ -108,21 +110,23 @@ void gnrc_lorawan_reset(gnrc_lorawan_t *mac)
static void _config_radio(gnrc_lorawan_t *mac, uint32_t channel_freq, uint8_t dr, int rx)
{
netdev_t *dev = gnrc_lorawan_get_netdev(mac);
if (channel_freq != 0) {
netdev_set_pass(&mac->netdev, NETOPT_CHANNEL_FREQUENCY, &channel_freq, sizeof(channel_freq));
dev->driver->set(dev, NETOPT_CHANNEL_FREQUENCY, &channel_freq, sizeof(channel_freq));
}
netopt_enable_t iq_invert = rx;
netdev_set_pass(&mac->netdev, NETOPT_IQ_INVERT, &iq_invert, sizeof(iq_invert));
dev->driver->set(dev, NETOPT_IQ_INVERT, &iq_invert, sizeof(iq_invert));
gnrc_lorawan_set_dr(mac, dr);
if (rx) {
/* Switch to single listen mode */
const netopt_enable_t single = true;
netdev_set_pass(&mac->netdev, NETOPT_SINGLE_RECEIVE, &single, sizeof(single));
dev->driver->set(dev, NETOPT_SINGLE_RECEIVE, &single, sizeof(single));
const uint16_t timeout = CONFIG_GNRC_LORAWAN_MIN_SYMBOLS_TIMEOUT;
netdev_set_pass(&mac->netdev, NETOPT_RX_SYMBOL_TIMEOUT, &timeout, sizeof(timeout));
dev->driver->set(dev, NETOPT_RX_SYMBOL_TIMEOUT, &timeout, sizeof(timeout));
}
}
@ -133,13 +137,14 @@ static void _configure_rx_window(gnrc_lorawan_t *mac, uint32_t channel_freq, uin
void gnrc_lorawan_open_rx_window(gnrc_lorawan_t *mac)
{
netdev_t *dev = gnrc_lorawan_get_netdev(mac);
mac->msg.type = MSG_TYPE_TIMEOUT;
/* Switch to RX state */
if (mac->state == LORAWAN_STATE_RX_1) {
xtimer_set_msg(&mac->rx, _DRIFT_FACTOR, &mac->msg, thread_getpid());
}
uint8_t state = NETOPT_STATE_RX;
netdev_set_pass(&mac->netdev, NETOPT_STATE, &state, sizeof(state));
dev->driver->set(dev, NETOPT_STATE, &state, sizeof(state));
}
void gnrc_lorawan_event_tx_complete(gnrc_lorawan_t *mac)
@ -183,7 +188,7 @@ void gnrc_lorawan_event_timeout(gnrc_lorawan_t *mac)
}
/* This function uses a precomputed table to calculate time on air without
* using floating point arithmetics */
* using floating point arithmetic */
static uint32_t lora_time_on_air(size_t payload_size, uint8_t dr, uint8_t cr)
{
assert(dr <= LORAMAC_DR_6);
@ -219,6 +224,7 @@ static uint32_t lora_time_on_air(size_t payload_size, uint8_t dr, uint8_t cr)
void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt, uint8_t dr)
{
netdev_t *dev = gnrc_lorawan_get_netdev(mac);
mac->state = LORAWAN_STATE_TX;
iolist_t iolist = {
@ -233,11 +239,11 @@ void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt, uint8_t dr)
mac->last_dr = dr;
uint8_t cr;
netdev_get_pass(&mac->netdev, NETOPT_CODING_RATE, &cr, sizeof(cr));
dev->driver->get(dev, NETOPT_CODING_RATE, &cr, sizeof(cr));
mac->toa = lora_time_on_air(gnrc_pkt_len(pkt), dr, cr + 4);
if (netdev_send_pass(&mac->netdev, &iolist) == -ENOTSUP) {
if (dev->driver->send(dev, &iolist) == -ENOTSUP) {
DEBUG("gnrc_lorawan: Cannot send: radio is still transmitting");
}
@ -267,81 +273,20 @@ void gnrc_lorawan_process_pkt(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt)
gnrc_lorawan_mac_release(mac);
}
int gnrc_lorawan_netdev_get(netdev_t *dev, netopt_t opt, void *value, size_t max_len)
{
int res = 0;
gnrc_lorawan_t *mac = (gnrc_lorawan_t *) dev;
uint32_t tmp;
switch (opt) {
case NETOPT_ADDRESS:
assert(max_len >= sizeof(mac->dev_addr));
tmp = byteorder_swapl(mac->dev_addr.u32);
memcpy(value, &tmp, sizeof(mac->dev_addr));
res = sizeof(mac->dev_addr);
break;
default:
res = netdev_get_pass(dev, opt, value, max_len);
break;
}
return res;
}
int gnrc_lorawan_netdev_set(netdev_t *dev, netopt_t opt, const void *value, size_t len)
{
gnrc_lorawan_t *mac = (gnrc_lorawan_t *) dev;
uint32_t tmp;
if (mac->busy) {
return -EBUSY;
}
switch (opt) {
case NETOPT_ADDRESS:
assert(len == sizeof(uint32_t));
tmp = byteorder_swapl(*((uint32_t *) value));
memcpy(&mac->dev_addr, &tmp, sizeof(uint32_t));
break;
case NETOPT_LORAWAN_RX2_DR:
assert(len == sizeof(uint8_t));
_set_rx2_dr(mac, *((uint8_t *) value));
break;
default:
netdev_set_pass(dev, opt, value, len);
break;
}
return 0;
}
const netdev_driver_t gnrc_lorawan_driver = {
.init = netdev_init_pass,
.send = netdev_send_pass,
.recv = netdev_recv_pass,
.get = gnrc_lorawan_netdev_get,
.set = gnrc_lorawan_netdev_set,
.isr = netdev_isr_pass,
};
void gnrc_lorawan_setup(gnrc_lorawan_t *mac, netdev_t *lower)
{
mac->netdev.driver = &gnrc_lorawan_driver;
mac->netdev.lower = lower;
lower->context = mac;
}
void gnrc_lorawan_recv(gnrc_lorawan_t *mac)
{
int bytes_expected = netdev_recv_pass((netdev_t *) mac, NULL, 0, 0);
netdev_t *dev = gnrc_lorawan_get_netdev(mac);
int bytes_expected = dev->driver->recv(dev, NULL, 0, 0);
int nread;
struct netdev_radio_rx_info rx_info;
gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, bytes_expected, GNRC_NETTYPE_UNDEF);
if (pkt == NULL) {
DEBUG("_recv_ieee802154: cannot allocate pktsnip.\n");
/* Discard packet on netdev device */
netdev_recv_pass((netdev_t *) mac, NULL, bytes_expected, NULL);
dev->driver->recv(dev, NULL, bytes_expected, NULL);
return;
}
nread = netdev_recv_pass((netdev_t *) mac, pkt->data, bytes_expected, &rx_info);
nread = dev->driver->recv(dev, pkt->data, bytes_expected, &rx_info);
_sleep_radio(mac);
if (nread <= 0) {
gnrc_pktbuf_release(pkt);

View File

@ -138,17 +138,17 @@ void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt
pkt->type = GNRC_NETTYPE_LORAWAN;
release = false;
mcps_indication_t *mcps_indication = gnrc_lorawan_mcps_allocate(mac);
mcps_indication->type = ack_req;
mcps_indication->data.pkt = pkt;
mcps_indication->data.port = *((uint8_t *) fport->data);
mac->netdev.event_callback((netdev_t *) mac, NETDEV_EVENT_MCPS_INDICATION);
mcps_indication_t mcps_indication;
mcps_indication.type = ack_req;
mcps_indication.data.pkt = pkt;
mcps_indication.data.port = *((uint8_t *) fport->data);
gnrc_lorawan_mcps_indication(mac, &mcps_indication);
}
if (lorawan_hdr_get_frame_pending(lw_hdr)) {
mlme_indication_t *mlme_indication = gnrc_lorawan_mlme_allocate(mac);
mlme_indication->type = MLME_SCHEDULE_UPLINK;
mac->netdev.event_callback((netdev_t *) mac, NETDEV_EVENT_MLME_INDICATION);
mlme_indication_t mlme_indication;
mlme_indication.type = MLME_SCHEDULE_UPLINK;
gnrc_lorawan_mlme_indication(mac, &mlme_indication);
}
out:
@ -232,11 +232,11 @@ static void _end_of_tx(gnrc_lorawan_t *mac, int type, int status)
{
mac->mcps.waiting_for_ack = false;
mcps_confirm_t *mcps_confirm = gnrc_lorawan_mcps_allocate(mac);
mcps_confirm_t mcps_confirm;
mcps_confirm->type = type;
mcps_confirm->status = status;
mac->netdev.event_callback((netdev_t *) mac, NETDEV_EVENT_MCPS_CONFIRM);
mcps_confirm.type = type;
mcps_confirm.status = status;
gnrc_lorawan_mcps_confirm(mac, &mcps_confirm);
mac->mcps.fcnt += 1;
}

View File

@ -59,7 +59,7 @@ static gnrc_pktsnip_t *_build_join_req_pkt(uint8_t *appeui, uint8_t *deveui, uin
static int gnrc_lorawan_send_join_request(gnrc_lorawan_t *mac, uint8_t *deveui,
uint8_t *appeui, uint8_t *appkey, uint8_t dr)
{
netdev_t *dev = mac->netdev.lower;
netdev_t *dev = gnrc_lorawan_get_netdev(mac);
/* Dev Nonce */
uint32_t random_number;
@ -100,7 +100,7 @@ void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt)
goto out;
}
/* Substract 1 from join accept max size, since the MHDR was already read */
/* Subtract 1 from join accept max size, since the MHDR was already read */
uint8_t out[GNRC_LORAWAN_JOIN_ACCEPT_MAX_SIZE - 1];
uint8_t has_cflist = (pkt->size - 1) >= CFLIST_SIZE;
gnrc_lorawan_decrypt_join_accept(mac->appskey, ((uint8_t *) pkt->data) + 1,
@ -139,11 +139,11 @@ void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt)
out:
gnrc_pktbuf_release(pkt);
mlme_confirm_t *mlme_confirm = gnrc_lorawan_mlme_allocate(mac);
mlme_confirm->type = MLME_JOIN;
mlme_confirm->status = status;
mlme_confirm_t mlme_confirm;
mlme_confirm.type = MLME_JOIN;
mlme_confirm.status = status;
mac->netdev.event_callback((netdev_t *) mac, NETDEV_EVENT_MLME_CONFIRM);
gnrc_lorawan_mlme_confirm(mac, &mlme_confirm);
}
void gnrc_lorawan_mlme_backoff_expire(gnrc_lorawan_t *mac)
@ -189,6 +189,14 @@ static void _mlme_set(gnrc_lorawan_t *mac, const mlme_request_t *mlme_request,
mac->mlme.activation = mlme_request->mib.activation;
}
break;
case MIB_DEV_ADDR:
mlme_confirm->status = GNRC_LORAWAN_REQ_STATUS_SUCCESS;
memcpy(&mac->dev_addr, mlme_request->mib.dev_addr, sizeof(uint32_t));
break;
case MIB_RX2_DR:
mlme_confirm->status = GNRC_LORAWAN_REQ_STATUS_SUCCESS;
gnrc_lorawan_set_rx2_dr(mac, mlme_request->mib.rx2_dr);
break;
default:
break;
}
@ -202,6 +210,10 @@ static void _mlme_get(gnrc_lorawan_t *mac, const mlme_request_t *mlme_request,
mlme_confirm->status = GNRC_LORAWAN_REQ_STATUS_SUCCESS;
mlme_confirm->mib.activation = mac->mlme.activation;
break;
case MIB_DEV_ADDR:
mlme_confirm->status = GNRC_LORAWAN_REQ_STATUS_SUCCESS;
mlme_confirm->mib.dev_addr = &mac->dev_addr;
break;
default:
mlme_confirm->status = -EINVAL;
break;
@ -261,13 +273,13 @@ int _fopts_mlme_link_check_req(lorawan_buffer_t *buf)
static void _mlme_link_check_ans(gnrc_lorawan_t *mac, uint8_t *p)
{
mlme_confirm_t *mlme_confirm = gnrc_lorawan_mlme_allocate(mac);
mlme_confirm->link_req.margin = p[1];
mlme_confirm->link_req.num_gateways = p[2];
mlme_confirm_t mlme_confirm;
mlme_confirm.link_req.margin = p[1];
mlme_confirm.link_req.num_gateways = p[2];
mlme_confirm->type = MLME_LINK_CHECK;
mlme_confirm->status = GNRC_LORAWAN_REQ_STATUS_SUCCESS;
mac->netdev.event_callback(&mac->netdev, NETDEV_EVENT_MLME_CONFIRM);
mlme_confirm.type = MLME_LINK_CHECK;
mlme_confirm.status = GNRC_LORAWAN_REQ_STATUS_SUCCESS;
gnrc_lorawan_mlme_confirm(mac, &mlme_confirm);
mac->mlme.pending_mlme_opts &= ~GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ;
}
@ -312,17 +324,17 @@ uint8_t gnrc_lorawan_build_options(gnrc_lorawan_t *mac, lorawan_buffer_t *buf)
void gnrc_lorawan_mlme_no_rx(gnrc_lorawan_t *mac)
{
mlme_confirm_t *mlme_confirm = gnrc_lorawan_mlme_allocate(mac);
mlme_confirm_t mlme_confirm;
mlme_confirm->status = -ETIMEDOUT;
mlme_confirm.status = -ETIMEDOUT;
if (mac->mlme.activation == MLME_ACTIVATION_NONE) {
mlme_confirm->type = MLME_JOIN;
mac->netdev.event_callback(&mac->netdev, NETDEV_EVENT_MLME_CONFIRM);
mlme_confirm.type = MLME_JOIN;
gnrc_lorawan_mlme_confirm(mac, &mlme_confirm);
}
else if (mac->mlme.pending_mlme_opts & GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ) {
mlme_confirm->type = MLME_LINK_CHECK;
mac->netdev.event_callback(&mac->netdev, NETDEV_EVENT_MLME_CONFIRM);
mlme_confirm.type = MLME_LINK_CHECK;
gnrc_lorawan_mlme_confirm(mac, &mlme_confirm);
mac->mlme.pending_mlme_opts &= ~GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ;
}
}

View File

@ -24,7 +24,7 @@ static uint8_t dr_bw[GNRC_LORAWAN_DATARATES_NUMOF] =
int gnrc_lorawan_set_dr(gnrc_lorawan_t *mac, uint8_t datarate)
{
netdev_t *dev = mac->netdev.lower;
netdev_t *dev = gnrc_lorawan_get_netdev(mac);
if (!gnrc_lorawan_validate_dr(datarate)) {
return -EINVAL;
@ -84,7 +84,7 @@ void gnrc_lorawan_channels_init(gnrc_lorawan_t *mac)
uint32_t gnrc_lorawan_pick_channel(gnrc_lorawan_t *mac)
{
netdev_t *netdev = mac->netdev.lower;
netdev_t *netdev = gnrc_lorawan_get_netdev(mac);
uint32_t random_number;
netdev->driver->get(netdev, NETOPT_RANDOM, &random_number,

View File

@ -46,7 +46,7 @@ extern "C" {
#define MTYPE_CNF_UPLINK 0x4 /**< Confirmed uplink type */
#define MTYPE_CNF_DOWNLINK 0x5 /**< Confirmed downlink type */
#define MTYPE_REJOIN_REQ 0x6 /**< Re-join request type */
#define MTYPE_PROPIETARY 0x7 /**< Propietary frame type */
#define MTYPE_PROPIETARY 0x7 /**< Proprietary frame type */
#define MAJOR_MASK 0x3 /**< Major mtype mask */
#define MAJOR_LRWAN_R1 0x0 /**< LoRaWAN R1 version type */
@ -143,7 +143,7 @@ typedef struct {
uint32_t fcnt_down; /**< downlink frame counter */
gnrc_pktsnip_t *outgoing_pkt; /**< holds the outgoing packet in case of retransmissions */
int nb_trials; /**< holds the remaining number of retransmissions */
int ack_requested; /**< wether the network server requested an ACK */
int ack_requested; /**< whether the network server requested an ACK */
int waiting_for_ack; /**< true if the MAC layer is waiting for an ACK */
} gnrc_lorawan_mcps_t;
@ -164,7 +164,6 @@ typedef struct {
/**
* @brief GNRC LoRaWAN mac descriptor */
typedef struct {
netdev_t netdev; /**< netdev for the MAC layer */
xtimer_t rx; /**< RX timer */
msg_t msg; /**< MAC layer message descriptor */
gnrc_lorawan_mcps_t mcps; /**< MCPS descriptor */
@ -211,7 +210,7 @@ void gnrc_lorawan_decrypt_join_accept(const uint8_t *key, uint8_t *pkt, int has_
/**
* @brief Generate LoRaWAN session keys
*
* Intended to be called after a successfull Join Request in order to generate
* Intended to be called after a successful Join Request in order to generate
* NwkSKey and AppSKey
*
* @param[in] app_nonce pointer to the app_nonce of the Join Accept message
@ -447,31 +446,12 @@ static inline void gnrc_lorawan_mac_release(gnrc_lorawan_t *mac)
}
/**
* @brief Allocate memory to hold a GNRC LoRaWAN MCPS request
* @brief Set the datarate of the second reception window
*
* @param[in] mac pointer to the MAC descriptor
*
* @return pointer the allocated buffer
* @param[in] rx2_dr datarate of RX2
*/
static inline void *gnrc_lorawan_mcps_allocate(gnrc_lorawan_t *mac)
{
mac->netdev.event_callback((netdev_t *) mac, NETDEV_EVENT_MCPS_GET_BUFFER);
return mac->mcps_buf;
}
/**
* @brief Allocate memory to hold a GNRC LoRaWAN MLME request
*
* @param[in] mac pointer to the MAC descriptor
*
* @return pointer the allocated buffer
*/
static inline void *gnrc_lorawan_mlme_allocate(gnrc_lorawan_t *mac)
{
mac->netdev.event_callback((netdev_t *) mac, NETDEV_EVENT_MLME_GET_BUFFER);
return mac->mlme_buf;
}
void gnrc_lorawan_set_rx2_dr(gnrc_lorawan_t *mac, uint8_t rx2_dr);
#ifdef __cplusplus
}

View File

@ -49,13 +49,9 @@ static const gnrc_netif_ops_t lorawan_ops = {
.msg_handler = _msg_handler
};
static uint8_t _mcps_buffer[sizeof(mcps_confirm_t) > sizeof(mcps_indication_t) ?
sizeof(mcps_confirm_t) : sizeof(mcps_indication_t)];
static uint8_t _mlme_buffer[sizeof(mlme_confirm_t) > sizeof(mlme_indication_t) ?
sizeof(mlme_confirm_t) : sizeof(mlme_indication_t)];
static void _mlme_confirm(gnrc_netif_t *netif, mlme_confirm_t *confirm)
void gnrc_lorawan_mlme_confirm(gnrc_lorawan_t *mac, mlme_confirm_t *confirm)
{
gnrc_netif_lorawan_t *lw_netif = container_of(mac, gnrc_netif_lorawan_t, mac);
if (confirm->type == MLME_JOIN) {
if (confirm->status == 0) {
DEBUG("gnrc_lorawan: join succeeded\n");
@ -65,58 +61,56 @@ static void _mlme_confirm(gnrc_netif_t *netif, mlme_confirm_t *confirm)
}
}
else if (confirm->type == MLME_LINK_CHECK) {
netif->lorawan.flags &= ~GNRC_NETIF_LORAWAN_FLAGS_LINK_CHECK;
netif->lorawan.demod_margin = confirm->link_req.margin;
netif->lorawan.num_gateways = confirm->link_req.num_gateways;
lw_netif->flags &= ~GNRC_NETIF_LORAWAN_FLAGS_LINK_CHECK;
lw_netif->demod_margin = confirm->link_req.margin;
lw_netif->num_gateways = confirm->link_req.num_gateways;
}
}
static void _mac_cb(netdev_t *dev, netdev_event_t event)
static inline void _set_be_addr(gnrc_lorawan_t *mac, uint8_t *be_addr)
{
gnrc_lorawan_t *mac = (gnrc_lorawan_t *) dev;
uint32_t tmp = *((uint32_t*) be_addr);
tmp = byteorder_swapl(tmp);
mlme_request_t mlme_request;
mlme_confirm_t mlme_confirm;
mcps_confirm_t *mcps_confirm;
mcps_indication_t *mcps_indication;
mlme_request.type = MLME_SET;
mlme_request.mib.type = MIB_DEV_ADDR;
mlme_request.mib.dev_addr = &tmp;
switch (event) {
case NETDEV_EVENT_MLME_INDICATION:
/* ignore */
break;
case NETDEV_EVENT_MCPS_INDICATION:
mcps_indication = mac->mcps_buf;
if (!gnrc_netapi_dispatch_receive(GNRC_NETTYPE_LORAWAN, mcps_indication->data.port, mcps_indication->data.pkt)) {
gnrc_pktbuf_release(mcps_indication->data.pkt);
}
break;
case NETDEV_EVENT_MLME_CONFIRM:
_mlme_confirm((gnrc_netif_t *) mac->netdev.context, mac->mlme_buf);
break;
case NETDEV_EVENT_MCPS_CONFIRM:
mcps_confirm = mac->mcps_buf;
if (mcps_confirm->status == 0) {
gnrc_pktbuf_release(mac->mcps.outgoing_pkt);
}
else {
gnrc_pktbuf_release_error(mac->mcps.outgoing_pkt, 1);
}
mac->mcps.outgoing_pkt = NULL;
break;
case NETDEV_EVENT_MLME_GET_BUFFER:
mac->mlme_buf = _mlme_buffer;
break;
case NETDEV_EVENT_MCPS_GET_BUFFER:
mac->mcps_buf = _mcps_buffer;
break;
default:
netdev_event_cb_pass(dev, event);
break;
gnrc_lorawan_mlme_request(mac, &mlme_request, &mlme_confirm);
}
void gnrc_lorawan_mcps_indication(gnrc_lorawan_t *mac, mcps_indication_t *ind)
{
(void) mac;
if (!gnrc_netapi_dispatch_receive(GNRC_NETTYPE_LORAWAN, ind->data.port,
ind->data.pkt)) {
gnrc_pktbuf_release(ind->data.pkt);
}
}
void gnrc_lorawan_mlme_indication(gnrc_lorawan_t *mac, mlme_indication_t *ind)
{
(void) mac;
(void) ind;
}
void gnrc_lorawan_mcps_confirm(gnrc_lorawan_t *mac, mcps_confirm_t *confirm)
{
if (confirm->status == 0) {
gnrc_pktbuf_release(mac->mcps.outgoing_pkt);
}
else {
gnrc_pktbuf_release_error(mac->mcps.outgoing_pkt, 1);
}
mac->mcps.outgoing_pkt = NULL;
}
static void _driver_cb(netdev_t *dev, netdev_event_t event)
{
gnrc_lorawan_t *mac = (gnrc_lorawan_t *) dev->context;
gnrc_netif_t *netif = (gnrc_netif_t *) mac->netdev.context;
gnrc_netif_t *netif = dev->context;
gnrc_lorawan_t *mac = &netif->lorawan.mac;
if (event == NETDEV_EVENT_ISR) {
msg_t msg = { .type = NETDEV_MSG_TYPE_EVENT,
@ -163,12 +157,16 @@ static void _memcpy_reversed(uint8_t *dst, uint8_t *src, size_t size)
}
}
netdev_t *gnrc_lorawan_get_netdev(gnrc_lorawan_t *mac)
{
gnrc_netif_t *netif = container_of(mac, gnrc_netif_t, lorawan.mac);
return netif->dev;
}
static void _init(gnrc_netif_t *netif)
{
gnrc_netif_default_init(netif);
netif->dev->event_callback = _driver_cb;
netif->lorawan.mac.netdev.event_callback = _mac_cb;
netif->lorawan.mac.netdev.context = netif;
_reset(netif);
/* Initialize default keys, address and EUIs */
@ -178,8 +176,7 @@ static void _init(gnrc_netif_t *netif)
memcpy(netif->lorawan.appkey, _appkey, sizeof(_appkey));
_memcpy_reversed(netif->lorawan.appeui, _appeui, sizeof(_appeui));
gnrc_lorawan_setup(&netif->lorawan.mac, netif->dev);
netif->lorawan.mac.netdev.driver->set(&netif->lorawan.mac.netdev, NETOPT_ADDRESS, _devaddr, sizeof(_devaddr));
_set_be_addr(&netif->lorawan.mac, _devaddr);
gnrc_lorawan_init(&netif->lorawan.mac, netif->lorawan.nwkskey, netif->lorawan.appskey);
}
@ -236,6 +233,7 @@ static void _msg_handler(gnrc_netif_t *netif, msg_t *msg)
static int _get(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt)
{
int res = 0;
uint32_t tmp;
mlme_confirm_t mlme_confirm;
mlme_request_t mlme_request;
@ -263,8 +261,18 @@ static int _get(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt)
assert(opt->data_len == sizeof(uint8_t));
*((uint8_t *) opt->data) = netif->lorawan.demod_margin;
break;
case NETOPT_ADDRESS:
mlme_request.type = MLME_GET;
mlme_request.mib.type = MIB_DEV_ADDR;
gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, &mlme_confirm);
tmp = *((uint32_t*) mlme_confirm.mib.dev_addr);
tmp = byteorder_swapl(tmp);
memcpy(opt->data, &tmp, sizeof(uint32_t));
res = sizeof(uint32_t);
break;
default:
res = netif->lorawan.mac.netdev.driver->get(&netif->lorawan.mac.netdev, opt->opt, opt->data, opt->data_len);
res = netif->dev->driver->get(netif->dev, opt->opt, opt->data, opt->data_len);
break;
}
return res;
@ -343,11 +351,22 @@ static int _set(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt)
}
break;
}
case NETOPT_ADDRESS:
assert(opt->data_len == sizeof(uint32_t));
_set_be_addr(&netif->lorawan.mac, opt->data);
break;
case NETOPT_LINK_CHECK:
netif->lorawan.flags |= GNRC_NETIF_LORAWAN_FLAGS_LINK_CHECK;
break;
case NETOPT_LORAWAN_RX2_DR:
assert(opt->data_len == sizeof(uint8_t));
mlme_request.type = MLME_SET;
mlme_request.mib.type = MIB_RX2_DR;
mlme_request.mib.rx2_dr = *((uint8_t*) opt->data);
gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, &mlme_confirm);
break;
default:
res = netif->lorawan.mac.netdev.driver->set(&netif->lorawan.mac.netdev, opt->opt, opt->data, opt->data_len);
res = netif->dev->driver->set(netif->dev, opt->opt, opt->data, opt->data_len);
break;
}
gnrc_netif_release(netif);