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:
commit
a4c4c25b3b
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user