From 5146261f034c683b8ec73b9b4472b7a025ab4df0 Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Fri, 8 May 2020 12:55:45 +0200 Subject: [PATCH 1/5] gnrc_lorawan: rename radio event functions --- sys/include/net/gnrc/lorawan.h | 6 +++--- sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c | 6 +++--- sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sys/include/net/gnrc/lorawan.h b/sys/include/net/gnrc/lorawan.h index f495fd03c6..4371ea4a78 100644 --- a/sys/include/net/gnrc/lorawan.h +++ b/sys/include/net/gnrc/lorawan.h @@ -180,14 +180,14 @@ typedef struct { * * @param[in] mac pointer to the MAC descriptor */ -void gnrc_lorawan_event_timeout(gnrc_lorawan_t *mac); +void gnrc_lorawan_radio_rx_timeout_cb(gnrc_lorawan_t *mac); /** * @brief Indicate the MAC layer when the transmission finished * * @param[in] mac pointer to the MAC descriptor */ -void gnrc_lorawan_event_tx_complete(gnrc_lorawan_t *mac); +void gnrc_lorawan_radio_tx_done_cb(gnrc_lorawan_t *mac); /** * @brief Init GNRC LoRaWAN @@ -231,7 +231,7 @@ void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_r * * @param[in] mac pointer to the MAC descriptor */ -void gnrc_lorawan_recv(gnrc_lorawan_t *mac); +void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac); /** * @brief MCPS indication callback diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c index db93cfc806..b11a9f604b 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c @@ -147,7 +147,7 @@ void gnrc_lorawan_open_rx_window(gnrc_lorawan_t *mac) dev->driver->set(dev, NETOPT_STATE, &state, sizeof(state)); } -void gnrc_lorawan_event_tx_complete(gnrc_lorawan_t *mac) +void gnrc_lorawan_radio_tx_done_cb(gnrc_lorawan_t *mac) { mac->msg.type = MSG_TYPE_TIMEOUT; mac->state = LORAWAN_STATE_RX_1; @@ -166,7 +166,7 @@ void gnrc_lorawan_event_tx_complete(gnrc_lorawan_t *mac) _sleep_radio(mac); } -void gnrc_lorawan_event_timeout(gnrc_lorawan_t *mac) +void gnrc_lorawan_radio_rx_timeout_cb(gnrc_lorawan_t *mac) { (void) mac; switch (mac->state) { @@ -273,7 +273,7 @@ void gnrc_lorawan_process_pkt(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt) gnrc_lorawan_mac_release(mac); } -void gnrc_lorawan_recv(gnrc_lorawan_t *mac) +void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac) { netdev_t *dev = gnrc_lorawan_get_netdev(mac); int bytes_expected = dev->driver->recv(dev, NULL, 0, 0); diff --git a/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c b/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c index 51821dbcdd..6eff506302 100644 --- a/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c +++ b/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c @@ -125,13 +125,13 @@ static void _driver_cb(netdev_t *dev, netdev_event_t event) DEBUG("gnrc_netif: event triggered -> %i\n", event); switch (event) { case NETDEV_EVENT_RX_COMPLETE: - gnrc_lorawan_recv(mac); + gnrc_lorawan_radio_rx_done_cb(mac); break; case NETDEV_EVENT_TX_COMPLETE: - gnrc_lorawan_event_tx_complete(mac); + gnrc_lorawan_radio_tx_done_cb(mac); break; case NETDEV_EVENT_RX_TIMEOUT: - gnrc_lorawan_event_timeout(mac); + gnrc_lorawan_radio_rx_timeout_cb(mac); break; default: DEBUG("gnrc_netif: warning: unhandled event %u.\n", event); From 2e6ba90435f03a85dec30a925a8d74ac68baf7f0 Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Fri, 8 May 2020 13:40:34 +0200 Subject: [PATCH 2/5] gnrc_lorawan: refactor rx_done callback --- sys/include/net/gnrc/lorawan.h | 3 +- .../gnrc/link_layer/lorawan/gnrc_lorawan.c | 29 ++++--------------- .../gnrc/netif/lorawan/gnrc_netif_lorawan.c | 26 ++++++++++++++++- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/sys/include/net/gnrc/lorawan.h b/sys/include/net/gnrc/lorawan.h index 4371ea4a78..dd4cc5fc44 100644 --- a/sys/include/net/gnrc/lorawan.h +++ b/sys/include/net/gnrc/lorawan.h @@ -230,8 +230,9 @@ void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_r * To be called on radio RX done event. * * @param[in] mac pointer to the MAC descriptor + * @param[in] pkt pointer to the packet */ -void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac); +void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt); /** * @brief MCPS indication callback diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c index b11a9f604b..059d7ca6bc 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c @@ -249,8 +249,12 @@ void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt, uint8_t dr) } -void gnrc_lorawan_process_pkt(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt) +void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt) { + _sleep_radio(mac); + if (pkt == NULL) { + return; + } mac->state = LORAWAN_STATE_IDLE; xtimer_remove(&mac->rx); @@ -272,26 +276,3 @@ void gnrc_lorawan_process_pkt(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt) gnrc_lorawan_mac_release(mac); } - -void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac) -{ - 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 */ - dev->driver->recv(dev, NULL, bytes_expected, NULL); - return; - } - nread = dev->driver->recv(dev, pkt->data, bytes_expected, &rx_info); - _sleep_radio(mac); - if (nread <= 0) { - gnrc_pktbuf_release(pkt); - return; - } - - gnrc_lorawan_process_pkt(mac, pkt); -} diff --git a/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c b/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c index 6eff506302..43e213282a 100644 --- a/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c +++ b/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c @@ -108,6 +108,30 @@ void gnrc_lorawan_mcps_confirm(gnrc_lorawan_t *mac, mcps_confirm_t *confirm) mac->mcps.outgoing_pkt = NULL; } +static void _rx_done(gnrc_lorawan_t *mac) +{ + 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 */ + dev->driver->recv(dev, NULL, bytes_expected, NULL); + gnrc_lorawan_radio_rx_done_cb(mac, NULL); + return; + } + nread = dev->driver->recv(dev, pkt->data, bytes_expected, &rx_info); + if (nread <= 0) { + gnrc_pktbuf_release(pkt); + gnrc_lorawan_radio_rx_done_cb(mac, NULL); + return; + } + + gnrc_lorawan_radio_rx_done_cb(mac, pkt); +} + static void _driver_cb(netdev_t *dev, netdev_event_t event) { gnrc_netif_t *netif = dev->context; @@ -125,7 +149,7 @@ static void _driver_cb(netdev_t *dev, netdev_event_t event) DEBUG("gnrc_netif: event triggered -> %i\n", event); switch (event) { case NETDEV_EVENT_RX_COMPLETE: - gnrc_lorawan_radio_rx_done_cb(mac); + _rx_done(mac); break; case NETDEV_EVENT_TX_COMPLETE: gnrc_lorawan_radio_tx_done_cb(mac); From 0162a16d82711b918201c9a150134831bb185b5a Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Tue, 12 May 2020 14:28:22 +0200 Subject: [PATCH 3/5] gnrc_lorawan: fix BUSY logic --- sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c index 5e2e7e04fa..d689c70bad 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c @@ -291,7 +291,7 @@ void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_r if (!gnrc_lorawan_mac_acquire(mac)) { mcps_confirm->status = -EBUSY; - goto out; + return; } if (mcps_request->data.port < LORAMAC_PORT_MIN || From 71bda3bcd8b65f9e6a36f055139e82318ef9a1e3 Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Fri, 8 May 2020 14:49:00 +0200 Subject: [PATCH 4/5] gnrc_lorawan: remove GNRC specific dependencies --- Makefile.dep | 1 - examples/gnrc_lorawan/Makefile | 1 + examples/gnrc_lorawan/main.c | 8 +- sys/include/net/gnrc/lorawan.h | 9 +- .../gnrc/link_layer/lorawan/gnrc_lorawan.c | 33 +- .../link_layer/lorawan/gnrc_lorawan_crypto.c | 22 +- .../link_layer/lorawan/gnrc_lorawan_mcps.c | 372 ++++++++++-------- .../link_layer/lorawan/gnrc_lorawan_mlme.c | 84 ++-- .../lorawan/include/gnrc_lorawan_internal.h | 59 ++- .../gnrc/netif/lorawan/gnrc_netif_lorawan.c | 34 +- 10 files changed, 330 insertions(+), 293 deletions(-) diff --git a/Makefile.dep b/Makefile.dep index 5dece5690e..5afb81bdb9 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -89,7 +89,6 @@ ifneq (,$(filter gnrc_lorawan,$(USEMODULE))) USEMODULE += hashes USEMODULE += crypto_aes USEMODULE += netdev_layer - USEMODULE += gnrc_neterr USEMODULE += gnrc_nettype_lorawan endif diff --git a/examples/gnrc_lorawan/Makefile b/examples/gnrc_lorawan/Makefile index 3d8a22d523..ab320f4094 100644 --- a/examples/gnrc_lorawan/Makefile +++ b/examples/gnrc_lorawan/Makefile @@ -7,6 +7,7 @@ USEMODULE += gnrc_netdev_default USEMODULE += auto_init_gnrc_netif USEMODULE += gnrc_lorawan USEMODULE += gnrc_pktdump +USEMODULE += gnrc_neterr BOARD ?= b-l072z-lrwan1 RIOTBASE ?= ../../ diff --git a/examples/gnrc_lorawan/main.c b/examples/gnrc_lorawan/main.c index 6e488d22c5..fa83bf0238 100644 --- a/examples/gnrc_lorawan/main.c +++ b/examples/gnrc_lorawan/main.c @@ -35,7 +35,8 @@ #include "net/gnrc/pktdump.h" #include "net/gnrc/netreg.h" -#define LORAWAN_PORT (2U) +#define LORAWAN_PORT (2U) +#define LORAWAN_QUEUE_SIZE (4U) static void _usage(void) { @@ -75,16 +76,17 @@ int tx_cmd(int argc, char **argv) gnrc_netapi_set(interface, NETOPT_LORAWAN_TX_PORT, 0, &port, sizeof(port)); gnrc_netif_send(gnrc_netif_get_by_pid(interface), pkt); - msg_t msg; /* wait for packet status and check */ + msg_t msg; msg_receive(&msg); if ((msg.type != GNRC_NETERR_MSG_TYPE) || (msg.content.value != GNRC_NETERR_SUCCESS)) { - puts("Error sending packet (not joined?)"); + printf("Error sending packet: (status: %d\n)", (int) msg.content.value); } else { puts("Successfully sent packet"); } + return 0; } diff --git a/sys/include/net/gnrc/lorawan.h b/sys/include/net/gnrc/lorawan.h index dd4cc5fc44..8bcbb74793 100644 --- a/sys/include/net/gnrc/lorawan.h +++ b/sys/include/net/gnrc/lorawan.h @@ -63,7 +63,6 @@ extern "C" { typedef enum { MCPS_EVENT_RX, /**< MCPS RX event */ MCPS_EVENT_NO_RX, /**< MCPS no RX event */ - MCPS_EVENT_ACK_TIMEOUT /**< MCPS retrans event */ } mcps_event_t; /** @@ -153,9 +152,9 @@ typedef struct { * @brief Mac Common Part Sublayer (MCPS) confirm representation */ typedef struct { - void *data; /**< data of the MCPS confirm */ int16_t status; /**< status of the MCPS confirm */ mcps_type_t type; /**< type of the MCPS confirm */ + iolist_t *msdu; /**< pointer to the msdu */ } mcps_confirm_t; /** @@ -230,9 +229,11 @@ void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_r * To be called on radio RX done event. * * @param[in] mac pointer to the MAC descriptor - * @param[in] pkt pointer to the packet + * @param[in] data pointer to the psdu. Pass NULL if the packet was wrong (or + * allocation failed) + * @param[in] size size of the PSDU */ -void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt); +void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, uint8_t *data, size_t size); /** * @brief MCPS indication callback diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c index 059d7ca6bc..fc134d7c0c 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c @@ -175,10 +175,8 @@ void gnrc_lorawan_radio_rx_timeout_cb(gnrc_lorawan_t *mac) mac->state = LORAWAN_STATE_RX_2; break; case LORAWAN_STATE_RX_2: - gnrc_lorawan_mlme_no_rx(mac); - gnrc_lorawan_mcps_event(mac, MCPS_EVENT_NO_RX, 0); + gnrc_lorawan_event_no_rx(mac); mac->state = LORAWAN_STATE_IDLE; - gnrc_lorawan_mac_release(mac); break; default: assert(false); @@ -222,57 +220,44 @@ static uint32_t lora_time_on_air(size_t payload_size, uint8_t dr, uint8_t cr) return t_preamble + t_payload; } -void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt, uint8_t dr) +void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, iolist_t *psdu, uint8_t dr) { netdev_t *dev = gnrc_lorawan_get_netdev(mac); mac->state = LORAWAN_STATE_TX; - iolist_t iolist = { - .iol_base = pkt->data, - .iol_len = pkt->size, - .iol_next = (iolist_t *) pkt->next - }; - uint32_t chan = gnrc_lorawan_pick_channel(mac); _config_radio(mac, chan, dr, false); - mac->last_dr = dr; - uint8_t cr; dev->driver->get(dev, NETOPT_CODING_RATE, &cr, sizeof(cr)); - mac->toa = lora_time_on_air(gnrc_pkt_len(pkt), dr, cr + 4); + mac->toa = lora_time_on_air(iolist_size(psdu), dr, cr + 4); - if (dev->driver->send(dev, &iolist) == -ENOTSUP) { + if (dev->driver->send(dev, psdu) == -ENOTSUP) { DEBUG("gnrc_lorawan: Cannot send: radio is still transmitting"); } } -void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt) +void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, uint8_t *psdu, size_t size) { _sleep_radio(mac); - if (pkt == NULL) { + if (psdu == NULL) { return; } mac->state = LORAWAN_STATE_IDLE; xtimer_remove(&mac->rx); - uint8_t *p = pkt->data; - - uint8_t mtype = (*p & MTYPE_MASK) >> 5; + uint8_t mtype = (*psdu & MTYPE_MASK) >> 5; switch (mtype) { case MTYPE_JOIN_ACCEPT: - gnrc_lorawan_mlme_process_join(mac, pkt); + gnrc_lorawan_mlme_process_join(mac, psdu, size); break; case MTYPE_CNF_DOWNLINK: case MTYPE_UNCNF_DOWNLINK: - gnrc_lorawan_mcps_process_downlink(mac, pkt); + gnrc_lorawan_mcps_process_downlink(mac, psdu, size); break; default: - gnrc_pktbuf_release(pkt); break; } - - gnrc_lorawan_mac_release(mac); } diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c index f6b74ca817..e0a2da03c6 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c @@ -45,20 +45,17 @@ typedef struct __attribute__((packed)) { uint8_t len; } lorawan_block_t; -void gnrc_lorawan_calculate_join_mic(const iolist_t *io, const uint8_t *key, le_uint32_t *out) +void gnrc_lorawan_calculate_join_mic(const uint8_t *buf, size_t len, const uint8_t *key, le_uint32_t *out) { cmac_init(&CmacContext, key, LORAMAC_APPKEY_LEN); - while (io != NULL) { - cmac_update(&CmacContext, io->iol_base, io->iol_len); - io = io->iol_next; - } + cmac_update(&CmacContext, buf, len); cmac_final(&CmacContext, digest); memcpy(out, digest, sizeof(le_uint32_t)); } void gnrc_lorawan_calculate_mic(const le_uint32_t *dev_addr, uint32_t fcnt, - uint8_t dir, iolist_t *pkt, const uint8_t *nwkskey, le_uint32_t *out) + uint8_t dir, iolist_t *frame, const uint8_t *nwkskey, le_uint32_t *out) { lorawan_block_t block; @@ -72,11 +69,16 @@ void gnrc_lorawan_calculate_mic(const le_uint32_t *dev_addr, uint32_t fcnt, block.u32_pad = 0; - block.len = iolist_size(pkt); + block.len = iolist_size(frame); - iolist_t io = { .iol_base = &block, .iol_len = sizeof(block), - .iol_next = pkt }; - gnrc_lorawan_calculate_join_mic(&io, nwkskey, out); + cmac_init(&CmacContext, nwkskey, LORAMAC_APPKEY_LEN); + cmac_update(&CmacContext, &block, sizeof(block)); + for (iolist_t *io = frame; io != NULL; io = io->iol_next) { + cmac_update(&CmacContext, io->iol_base, io->iol_len); + } + cmac_final(&CmacContext, digest); + + memcpy(out, digest, sizeof(le_uint32_t)); } void gnrc_lorawan_encrypt_payload(iolist_t *iolist, const le_uint32_t *dev_addr, uint32_t fcnt, uint8_t dir, const uint8_t *appskey) diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c index d689c70bad..fdbb857ab7 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c @@ -30,17 +30,19 @@ #define _16_UPPER_BITMASK 0xFFFF0000 #define _16_LOWER_BITMASK 0xFFFF -int gnrc_lorawan_mic_is_valid(gnrc_pktsnip_t *mic, uint8_t *nwkskey) +static void _end_of_tx(gnrc_lorawan_t *mac, int type, int status); + +static int gnrc_lorawan_mic_is_valid(uint8_t *buf, size_t len, uint8_t *nwkskey) { le_uint32_t calc_mic; - assert(mic->size == MIC_SIZE); - assert(mic->next->data); - lorawan_hdr_t *lw_hdr = (lorawan_hdr_t *) mic->next->data; + lorawan_hdr_t *lw_hdr = (lorawan_hdr_t *) buf; uint32_t fcnt = byteorder_ntohs(byteorder_ltobs(lw_hdr->fcnt)); - gnrc_lorawan_calculate_mic(&lw_hdr->addr, fcnt, GNRC_LORAWAN_DIR_DOWNLINK, (iolist_t *) mic->next, nwkskey, &calc_mic); - return calc_mic.u32 == ((le_uint32_t *) mic->data)->u32; + iolist_t iol = {.iol_base = buf, .iol_len = len - MIC_SIZE, .iol_next = NULL}; + gnrc_lorawan_calculate_mic(&lw_hdr->addr, fcnt, GNRC_LORAWAN_DIR_DOWNLINK, + &iol, nwkskey, &calc_mic); + return calc_mic.u32 == ((le_uint32_t *) (buf+len-MIC_SIZE))->u32; } uint32_t gnrc_lorawan_fcnt_stol(uint32_t fcnt_down, uint16_t s_fcnt) @@ -54,120 +56,139 @@ uint32_t gnrc_lorawan_fcnt_stol(uint32_t fcnt_down, uint16_t s_fcnt) return u32_fcnt; } -void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt) -{ - gnrc_pktsnip_t *hdr, *data, *fopts = NULL, *fport = NULL; - int release = true; - int error = true; +/** + * @brief holder of parsed packet + */ +struct parsed_packet { + uint32_t fcnt_down; /**< frame counter */ + lorawan_hdr_t *hdr; /**< pointer to the LoRaWAN header */ + bool ack_req; /**< whether an ACK was requested or not */ + iolist_t fopts; /**< iolist with Fopts information */ + iolist_t enc_payload; /**< iolist with encrypted payload */ + uint8_t port; /**< Fport of the packet */ + bool ack; /**< whether the ACK bit was set or not */ + bool frame_pending; /**< whether there's pending data or not */ +}; - /* mark MIC */ - if (!(data = gnrc_pktbuf_mark(pkt, (pkt->size - MIC_SIZE > 0) ? pkt->size - MIC_SIZE : 0, GNRC_NETTYPE_UNDEF))) { - DEBUG("gnrc_lorawan: failed to mark MIC\n"); - goto out; +int gnrc_lorawan_parse_dl(gnrc_lorawan_t *mac, uint8_t *buf, size_t len, + struct parsed_packet *pkt) +{ + memset(pkt, 0, sizeof(struct parsed_packet)); + + lorawan_hdr_t *_hdr = (lorawan_hdr_t*) buf; + uint8_t *p_mic = buf + len - MIC_SIZE; + + pkt->hdr = _hdr; + buf += sizeof(lorawan_hdr_t); + + /* Validate header */ + if (_hdr->addr.u32 != mac->dev_addr.u32) { + DEBUG("gnrc_lorawan: received packet with wrong dev addr. Drop\n"); + return -1; } + uint32_t _fcnt = gnrc_lorawan_fcnt_stol(mac->mcps.fcnt_down, _hdr->fcnt.u16); + if (mac->mcps.fcnt_down > _fcnt || mac->mcps.fcnt_down + + LORAMAC_DEFAULT_MAX_FCNT_GAP < _fcnt) { + DEBUG("gnrc_lorawan: wrong frame counter\n"); + return -1; + } + + pkt->fcnt_down = _fcnt; + + int fopts_length = lorawan_hdr_get_frame_opts_len(_hdr); + if(fopts_length) { + pkt->fopts.iol_base = buf; + pkt->fopts.iol_len = fopts_length; + buf += fopts_length; + } + + if(buf < p_mic) { + pkt->port = *(buf++); + + if (!pkt->port && fopts_length) { + DEBUG("gnrc_lorawan: packet with fopts and port == 0. Drop\n"); + return -1; + } + + if (buf < p_mic) { + pkt->enc_payload.iol_base = buf; + pkt->enc_payload.iol_len = p_mic - buf; + } + } + + pkt->ack_req = lorawan_hdr_get_mtype(_hdr) == MTYPE_CNF_DOWNLINK; + pkt->ack = lorawan_hdr_get_ack(_hdr); + pkt->frame_pending = lorawan_hdr_get_frame_pending(_hdr); + + return 0; +} + +void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, uint8_t *psdu, size_t size) +{ + struct parsed_packet _pkt; + /* NOTE: MIC is in pkt */ - if (!gnrc_lorawan_mic_is_valid(pkt, mac->nwkskey)) { + if (!gnrc_lorawan_mic_is_valid(psdu, size, mac->nwkskey)) { DEBUG("gnrc_lorawan: invalid MIC\n"); - goto out; + gnrc_lorawan_event_no_rx(mac); + return; } - /* remove snip */ - pkt = gnrc_pktbuf_remove_snip(pkt, pkt); - - if (!(hdr = gnrc_pktbuf_mark(pkt, sizeof(lorawan_hdr_t), GNRC_NETTYPE_UNDEF))) { - DEBUG("gnrc_lorawan: failed to allocate hdr\n"); - goto out; + if (gnrc_lorawan_parse_dl(mac, psdu, size, &_pkt) < 0) { + DEBUG("gnrc_lorawan: couldn't parse packet\n"); + gnrc_lorawan_event_no_rx(mac); + return; } - int _fopts_length = lorawan_hdr_get_frame_opts_len((lorawan_hdr_t *) hdr->data); - if (_fopts_length && !(fopts = gnrc_pktbuf_mark(pkt, _fopts_length, GNRC_NETTYPE_UNDEF))) { - DEBUG("gnrc_lorawan: failed to allocate fopts\n"); - goto out; + iolist_t *fopts = NULL; + if(_pkt.fopts.iol_base) { + fopts = &_pkt.fopts; } - assert(pkt != NULL); - - int fopts_in_payload = 0; - /* only for download frames with payload the FPort must be present */ - if (pkt->size) { - if ((fport = gnrc_pktbuf_mark(pkt, 1, GNRC_NETTYPE_UNDEF)) == NULL) { - DEBUG("gnrc_lorawan: failed to allocate fport\n"); - goto out; + if(_pkt.enc_payload.iol_base) { + uint8_t *key; + if(_pkt.port) { + key = mac->appskey; } - - assert(fport->data); - - fopts_in_payload = *((uint8_t *) fport->data) == 0; - if (fopts && fopts_in_payload) { - DEBUG("gnrc_lorawan: packet with fopts and port == 0. Drop\n"); - goto out; + else { + key = mac->nwkskey; + fopts = &_pkt.enc_payload; } + gnrc_lorawan_encrypt_payload(&_pkt.enc_payload, &_pkt.hdr->addr, byteorder_ntohs(byteorder_ltobs(_pkt.hdr->fcnt)), GNRC_LORAWAN_DIR_DOWNLINK, key); } - lorawan_hdr_t *lw_hdr = hdr->data; - - if (lw_hdr->addr.u32 != mac->dev_addr.u32) { - DEBUG("gnrc_lorawan: received packet with wrong dev addr. Drop\n"); - goto out; + mac->mcps.fcnt_down = _pkt.fcnt_down; + if (mac->mcps.waiting_for_ack && !_pkt.ack) { + DEBUG("gnrc_lorawan: expected ACK packet\n"); + gnrc_lorawan_event_no_rx(mac); + return; } - uint32_t fcnt = gnrc_lorawan_fcnt_stol(mac->mcps.fcnt_down, lw_hdr->fcnt.u16); - if (mac->mcps.fcnt_down > fcnt || mac->mcps.fcnt_down + - LORAMAC_DEFAULT_MAX_FCNT_GAP < fcnt) { - goto out; - } - - mac->mcps.fcnt_down = fcnt; - error = false; - - int ack_req = lorawan_hdr_get_mtype(lw_hdr) == MTYPE_CNF_DOWNLINK; - if (ack_req) { + if (_pkt.ack_req) { mac->mcps.ack_requested = true; } - iolist_t payload = { .iol_base = pkt->data, .iol_len = pkt->size }; - if (pkt->data) { - gnrc_lorawan_encrypt_payload(&payload, &lw_hdr->addr, - byteorder_ntohs(byteorder_ltobs(lw_hdr->fcnt)), - GNRC_LORAWAN_DIR_DOWNLINK, - fopts_in_payload ? mac->nwkskey : mac->appskey); - } - /* if there are fopts, it's either an empty packet or application payload */ if (fopts) { - gnrc_lorawan_process_fopts(mac, fopts->data, fopts->size); - } - else if (fopts_in_payload) { - gnrc_lorawan_process_fopts(mac, pkt->data, pkt->size); + DEBUG("gnrc_lorawan: processing fopts\n"); + gnrc_lorawan_process_fopts(mac, fopts->iol_base, fopts->iol_len); } - gnrc_lorawan_mcps_event(mac, MCPS_EVENT_RX, lorawan_hdr_get_ack(lw_hdr)); - if (pkt->data && fport && *((uint8_t *) fport->data) != 0) { - pkt->type = GNRC_NETTYPE_LORAWAN; - release = false; + _end_of_tx(mac, MCPS_CONFIRMED, GNRC_LORAWAN_REQ_STATUS_SUCCESS); - 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)) { + if (_pkt.frame_pending) { mlme_indication_t mlme_indication; mlme_indication.type = MLME_SCHEDULE_UPLINK; gnrc_lorawan_mlme_indication(mac, &mlme_indication); } -out: - if (error) { - gnrc_lorawan_mcps_event(mac, MCPS_EVENT_NO_RX, 0); - } - - if (release) { - DEBUG("gnrc_lorawan: release packet\n"); - gnrc_pktbuf_release(pkt); + if (_pkt.port) { + mcps_indication_t mcps_indication; + mcps_indication.type = _pkt.ack_req; + mcps_indication.data.pkt = &_pkt.enc_payload; + mcps_indication.data.port = _pkt.port; + gnrc_lorawan_mcps_indication(mac, &mcps_indication); } } @@ -193,95 +214,130 @@ size_t gnrc_lorawan_build_hdr(uint8_t mtype, le_uint32_t *dev_addr, uint32_t fcn return sizeof(lorawan_hdr_t); } -gnrc_pktsnip_t *gnrc_lorawan_build_uplink(gnrc_lorawan_t *mac, gnrc_pktsnip_t *payload, int confirmed_data, uint8_t port) +size_t gnrc_lorawan_build_uplink(gnrc_lorawan_t *mac, iolist_t *payload, int confirmed_data, uint8_t port) { - /* Encrypt payload (it's block encryption so we can use the same buffer!) */ - gnrc_lorawan_encrypt_payload((iolist_t *) payload, &mac->dev_addr, mac->mcps.fcnt, GNRC_LORAWAN_DIR_UPLINK, port ? mac->appskey : mac->nwkskey); - - /* We try to allocate the whole header with fopts at once */ - uint8_t fopts_length = gnrc_lorawan_build_options(mac, NULL); - - gnrc_pktsnip_t *mac_hdr = gnrc_pktbuf_add(payload, NULL, sizeof(lorawan_hdr_t) + fopts_length + 1, GNRC_NETTYPE_UNDEF); - - if (!mac_hdr) { - gnrc_pktbuf_release_error(payload, -ENOBUFS); - return NULL; - } - - gnrc_pktsnip_t *mic = gnrc_pktbuf_add(NULL, NULL, MIC_SIZE, GNRC_NETTYPE_UNDEF); - if (!mic) { - gnrc_pktbuf_release_error(mac_hdr, -ENOBUFS); - return NULL; - } - lorawan_buffer_t buf = { - .data = (uint8_t *) mac_hdr->data, - .size = mac_hdr->size, + .data = (uint8_t *) mac->mcps.mhdr_mic, + .size = sizeof(mac->mcps.mhdr_mic), .index = 0 }; + lorawan_hdr_t *lw_hdr = (lorawan_hdr_t *) buf.data; - gnrc_lorawan_build_hdr(confirmed_data ? MTYPE_CNF_UPLINK : MTYPE_UNCNF_UPLINK, - &mac->dev_addr, mac->mcps.fcnt, mac->mcps.ack_requested, fopts_length, &buf); + lw_hdr->mt_maj = 0; + lorawan_hdr_set_mtype(lw_hdr, confirmed_data ? MTYPE_CNF_UPLINK : MTYPE_UNCNF_UPLINK); + lorawan_hdr_set_maj(lw_hdr, MAJOR_LRWAN_R1); - gnrc_lorawan_build_options(mac, &buf); + lw_hdr->addr = mac->dev_addr; + lw_hdr->fctrl = 0; - assert(buf.index == mac_hdr->size - 1); + lorawan_hdr_set_ack(lw_hdr, mac->mcps.ack_requested); + + lw_hdr->fcnt = byteorder_btols(byteorder_htons(mac->mcps.fcnt)); + + buf.index += sizeof(lorawan_hdr_t); + + int fopts_length = gnrc_lorawan_build_options(mac, &buf); + assert(fopts_length < 16); + lorawan_hdr_set_frame_opts_len(lw_hdr, fopts_length); buf.data[buf.index++] = port; + gnrc_lorawan_encrypt_payload(payload, &mac->dev_addr, mac->mcps.fcnt, GNRC_LORAWAN_DIR_UPLINK, port ? mac->appskey : mac->nwkskey); + + iolist_t iol = {.iol_base = buf.data, .iol_len = buf.index, .iol_next = payload}; gnrc_lorawan_calculate_mic(&mac->dev_addr, mac->mcps.fcnt, GNRC_LORAWAN_DIR_UPLINK, - (iolist_t *) mac_hdr, mac->nwkskey, mic->data); + &iol, mac->nwkskey, (le_uint32_t*) &buf.data[buf.index]); - LL_APPEND(payload, mic); - - return mac_hdr; + return buf.index; } static void _end_of_tx(gnrc_lorawan_t *mac, int type, int status) { + mlme_confirm_t mlme_confirm; + mcps_confirm_t mcps_confirm; + mac->mcps.waiting_for_ack = false; - mcps_confirm_t mcps_confirm; + mac->mcps.fcnt++; + + gnrc_lorawan_mac_release(mac); + + if (mac->mlme.pending_mlme_opts & GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ) { + mlme_confirm.type = MLME_LINK_CHECK; + mlme_confirm.status = -ETIMEDOUT; + mac->mlme.pending_mlme_opts &= ~GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ; + gnrc_lorawan_mlme_confirm(mac, &mlme_confirm); + } mcps_confirm.type = type; mcps_confirm.status = status; + mcps_confirm.msdu = mac->mcps.msdu; + mac->mcps.msdu = NULL; gnrc_lorawan_mcps_confirm(mac, &mcps_confirm); - - mac->mcps.fcnt += 1; } -void gnrc_lorawan_mcps_event(gnrc_lorawan_t *mac, int event, int data) +static void _transmit_pkt(gnrc_lorawan_t *mac) { + size_t mhdr_size = sizeof(lorawan_hdr_t) + 1 + lorawan_hdr_get_frame_opts_len((void*) mac->mcps.mhdr_mic); + + iolist_t header = {.iol_base = mac->mcps.mhdr_mic, .iol_len = mhdr_size, .iol_next = mac->mcps.msdu}; + iolist_t footer = {.iol_base = mac->mcps.mhdr_mic + header.iol_len, .iol_len = MIC_SIZE, .iol_next = NULL}; + iolist_t *last_snip = mac->mcps.msdu; + while (last_snip->iol_next != NULL) { + last_snip = last_snip->iol_next; + } + + last_snip->iol_next = &footer; + gnrc_lorawan_send_pkt(mac, &header, mac->last_dr); + + /* cppcheck-suppress redundantAssignment + * (reason: cppcheck bug. The pointer is temporally modified to add a footer. + * The `gnrc_lorawan_send_pkt` function uses this hack to append + * the MIC independently of `gnrc_pktsnip_t` structures) */ + last_snip->iol_next = NULL; +} + +void gnrc_lorawan_event_ack_timeout(gnrc_lorawan_t *mac) +{ + _transmit_pkt(mac); +} + +static void _handle_retransmissions(gnrc_lorawan_t *mac) +{ + if (mac->mcps.nb_trials-- == 0) { + _end_of_tx(mac, MCPS_CONFIRMED, -ETIMEDOUT); + } else { + mac->msg.type = MSG_TYPE_MCPS_ACK_TIMEOUT; + xtimer_set_msg(&mac->rx, 1000000 + random_uint32_range(0, 2000000), &mac->msg, thread_getpid()); + } +} + +void gnrc_lorawan_event_no_rx(gnrc_lorawan_t *mac) +{ + mlme_confirm_t mlme_confirm; + if (mac->mlme.activation == MLME_ACTIVATION_NONE) { + /* This was a Join Request */ + mlme_confirm.type = MLME_JOIN; + mlme_confirm.status = -ETIMEDOUT; + gnrc_lorawan_mac_release(mac); + gnrc_lorawan_mlme_confirm(mac, &mlme_confirm); return; } - if (event == MCPS_EVENT_ACK_TIMEOUT) { - gnrc_lorawan_send_pkt(mac, mac->mcps.outgoing_pkt, mac->last_dr); + /* Otherwise check if retransmission should be handled */ + + if (mac->mcps.waiting_for_ack) { + _handle_retransmissions(mac); } else { - int state = mac->mcps.waiting_for_ack ? MCPS_CONFIRMED : MCPS_UNCONFIRMED; - if (state == MCPS_CONFIRMED && ((event == MCPS_EVENT_RX && !data) || - event == MCPS_EVENT_NO_RX)) { - if (mac->mcps.nb_trials-- == 0) { - _end_of_tx(mac, MCPS_CONFIRMED, -ETIMEDOUT); - } - } - else { - _end_of_tx(mac, state, GNRC_LORAWAN_REQ_STATUS_SUCCESS); - } - - mac->msg.type = MSG_TYPE_MCPS_ACK_TIMEOUT; - if (mac->mcps.outgoing_pkt) { - xtimer_set_msg(&mac->rx, 1000000 + random_uint32_range(0, 2000000), &mac->msg, thread_getpid()); - } + _end_of_tx(mac, MCPS_UNCONFIRMED, GNRC_LORAWAN_REQ_STATUS_SUCCESS); } } void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_request, mcps_confirm_t *mcps_confirm) { - int release = true; - gnrc_pktsnip_t *pkt = mcps_request->data.pkt; + iolist_t *pkt = mcps_request->data.pkt; if (mac->mlme.activation == MLME_ACTIVATION_NONE) { DEBUG("gnrc_lorawan_mcps: LoRaWAN not activated\n"); @@ -305,39 +361,35 @@ void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_r goto out; } - int waiting_for_ack = mcps_request->type == MCPS_CONFIRMED; - if (!(pkt = gnrc_lorawan_build_uplink(mac, pkt, waiting_for_ack, mcps_request->data.port))) { - /* This function releases the pkt if fails */ - release = false; - mcps_confirm->status = -ENOBUFS; - goto out; - } + uint8_t fopts_length = gnrc_lorawan_build_options(mac, NULL); + /* We don't include the port because `MACPayload` doesn't consider + * the MHDR...*/ + size_t mac_payload_size = sizeof(lorawan_hdr_t) + fopts_length + + iolist_size(pkt); - if ((gnrc_pkt_len(pkt) - MIC_SIZE - 1) > gnrc_lorawan_region_mac_payload_max(mcps_request->data.dr)) { + if (mac_payload_size > gnrc_lorawan_region_mac_payload_max(mcps_request->data.dr)) { mcps_confirm->status = -EMSGSIZE; goto out; } - release = false; + int waiting_for_ack = mcps_request->type == MCPS_CONFIRMED; + + gnrc_lorawan_build_uplink(mac, pkt, waiting_for_ack, mcps_request->data.port); + mac->mcps.waiting_for_ack = waiting_for_ack; mac->mcps.ack_requested = false; mac->mcps.nb_trials = LORAMAC_DEFAULT_RETX; - assert(mac->mcps.outgoing_pkt == NULL); - mac->mcps.outgoing_pkt = pkt; - - gnrc_lorawan_send_pkt(mac, pkt, mcps_request->data.dr); + mac->mcps.msdu = pkt; + mac->last_dr = mcps_request->data.dr; + _transmit_pkt(mac); mcps_confirm->status = GNRC_LORAWAN_REQ_STATUS_DEFERRED; out: if (mcps_confirm->status != GNRC_LORAWAN_REQ_STATUS_DEFERRED) { gnrc_lorawan_mac_release(mac); } - - if (release) { - gnrc_pktbuf_release_error(pkt, mcps_confirm->status); - } } /** @} */ diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mlme.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mlme.c index 48f46cd446..61e5e39432 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mlme.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mlme.c @@ -28,32 +28,24 @@ #define ENABLE_DEBUG (0) #include "debug.h" -static gnrc_pktsnip_t *_build_join_req_pkt(uint8_t *appeui, uint8_t *deveui, uint8_t *appkey, uint8_t *dev_nonce) +static void _build_join_req_pkt(uint8_t *appeui, uint8_t *deveui, uint8_t *appkey, uint8_t *dev_nonce, uint8_t *psdu) { - gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, sizeof(lorawan_join_request_t), GNRC_NETTYPE_UNDEF); + lorawan_join_request_t *hdr = (lorawan_join_request_t *) psdu; - if (pkt) { - lorawan_join_request_t *hdr = (lorawan_join_request_t *) pkt->data; + hdr->mt_maj = 0; + lorawan_hdr_set_mtype((lorawan_hdr_t *) hdr, MTYPE_JOIN_REQUEST); + lorawan_hdr_set_maj((lorawan_hdr_t *) hdr, MAJOR_LRWAN_R1); - hdr->mt_maj = 0; - lorawan_hdr_set_mtype((lorawan_hdr_t *) hdr, MTYPE_JOIN_REQUEST); - lorawan_hdr_set_maj((lorawan_hdr_t *) hdr, MAJOR_LRWAN_R1); + le_uint64_t l_appeui = *((le_uint64_t *) appeui); + le_uint64_t l_deveui = *((le_uint64_t *) deveui); - le_uint64_t l_appeui = *((le_uint64_t *) appeui); - le_uint64_t l_deveui = *((le_uint64_t *) deveui); + hdr->app_eui = l_appeui; + hdr->dev_eui = l_deveui; - hdr->app_eui = l_appeui; - hdr->dev_eui = l_deveui; + le_uint16_t l_dev_nonce = *((le_uint16_t *) dev_nonce); + hdr->dev_nonce = l_dev_nonce; - le_uint16_t l_dev_nonce = *((le_uint16_t *) dev_nonce); - hdr->dev_nonce = l_dev_nonce; - - iolist_t io = { .iol_base = pkt->data, .iol_len = JOIN_REQUEST_SIZE - MIC_SIZE, - .iol_next = NULL }; - gnrc_lorawan_calculate_join_mic(&io, appkey, &hdr->mic); - } - - return pkt; + gnrc_lorawan_calculate_join_mic(psdu, JOIN_REQUEST_SIZE - MIC_SIZE, appkey, &hdr->mic); } static int gnrc_lorawan_send_join_request(gnrc_lorawan_t *mac, uint8_t *deveui, @@ -69,56 +61,54 @@ static int gnrc_lorawan_send_join_request(gnrc_lorawan_t *mac, uint8_t *deveui, mac->mlme.dev_nonce[1] = (random_number >> 8) & 0xFF; /* build join request */ - gnrc_pktsnip_t *pkt = _build_join_req_pkt(appeui, deveui, appkey, mac->mlme.dev_nonce); - if (!pkt) { - return -ENOBUFS; - } + uint8_t psdu[sizeof(lorawan_join_request_t)]; + + iolist_t pkt = {.iol_base = &psdu, .iol_len = sizeof(psdu), .iol_next = NULL}; + _build_join_req_pkt(appeui, deveui, appkey, mac->mlme.dev_nonce, psdu); /* We need a random delay for join request. Otherwise there might be * network congestion if a group of nodes start at the same time */ xtimer_usleep(random_uint32() & GNRC_LORAWAN_JOIN_DELAY_U32_MASK); - gnrc_lorawan_send_pkt(mac, pkt, dr); + gnrc_lorawan_send_pkt(mac, &pkt, dr); mac->mlme.backoff_budget -= mac->toa; - gnrc_pktbuf_release(pkt); return GNRC_LORAWAN_REQ_STATUS_DEFERRED; } -void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt) +void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, uint8_t *data, size_t size) { int status; + mlme_confirm_t mlme_confirm; if (mac->mlme.activation != MLME_ACTIVATION_NONE) { status = -EBADMSG; goto out; } - if (pkt->size != GNRC_LORAWAN_JOIN_ACCEPT_MAX_SIZE - CFLIST_SIZE && - pkt->size != GNRC_LORAWAN_JOIN_ACCEPT_MAX_SIZE) { + if (size != GNRC_LORAWAN_JOIN_ACCEPT_MAX_SIZE - CFLIST_SIZE && + size != GNRC_LORAWAN_JOIN_ACCEPT_MAX_SIZE) { status = -EBADMSG; goto out; } /* 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, + uint8_t has_cflist = (size - 1) >= CFLIST_SIZE; + gnrc_lorawan_decrypt_join_accept(mac->appskey, data + 1, has_cflist, out); - memcpy(((uint8_t *) pkt->data) + 1, out, pkt->size - 1); + memcpy(data + 1, out, size - 1); - iolist_t io = { .iol_base = pkt->data, .iol_len = pkt->size - MIC_SIZE, - .iol_next = NULL }; le_uint32_t mic; - le_uint32_t *expected_mic = (le_uint32_t *) (((uint8_t *) pkt->data) + pkt->size - MIC_SIZE); - gnrc_lorawan_calculate_join_mic(&io, mac->appskey, &mic); + le_uint32_t *expected_mic = (le_uint32_t *) (data + size - MIC_SIZE); + gnrc_lorawan_calculate_join_mic(data, size - MIC_SIZE, mac->appskey, &mic); if (mic.u32 != expected_mic->u32) { DEBUG("gnrc_lorawan_mlme: wrong MIC.\n"); status = -EBADMSG; goto out; } - lorawan_join_accept_t *ja_hdr = (lorawan_join_accept_t *) pkt->data; + lorawan_join_accept_t *ja_hdr = (lorawan_join_accept_t *) data; gnrc_lorawan_generate_session_keys(ja_hdr->app_nonce, mac->mlme.dev_nonce, mac->appskey, mac->nwkskey, mac->appskey); le_uint32_t le_nid; @@ -138,11 +128,10 @@ void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt) status = GNRC_LORAWAN_REQ_STATUS_SUCCESS; out: - gnrc_pktbuf_release(pkt); - mlme_confirm_t mlme_confirm; mlme_confirm.type = MLME_JOIN; mlme_confirm.status = status; + gnrc_lorawan_mac_release(mac); gnrc_lorawan_mlme_confirm(mac, &mlme_confirm); } @@ -321,20 +310,3 @@ uint8_t gnrc_lorawan_build_options(gnrc_lorawan_t *mac, lorawan_buffer_t *buf) return size; } - -void gnrc_lorawan_mlme_no_rx(gnrc_lorawan_t *mac) -{ - mlme_confirm_t mlme_confirm; - - mlme_confirm.status = -ETIMEDOUT; - - if (mac->mlme.activation == MLME_ACTIVATION_NONE) { - 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; - gnrc_lorawan_mlme_confirm(mac, &mlme_confirm); - mac->mlme.pending_mlme_opts &= ~GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ; - } -} diff --git a/sys/net/gnrc/link_layer/lorawan/include/gnrc_lorawan_internal.h b/sys/net/gnrc/link_layer/lorawan/include/gnrc_lorawan_internal.h index 5e19c86099..167aea346a 100644 --- a/sys/net/gnrc/link_layer/lorawan/include/gnrc_lorawan_internal.h +++ b/sys/net/gnrc/link_layer/lorawan/include/gnrc_lorawan_internal.h @@ -99,6 +99,17 @@ extern "C" { #define GNRC_LORAWAN_NET_ID_SIZE (3U) /**< Net ID size */ #define GNRC_LORAWAN_DEV_NONCE_SIZE (2U) /**< Dev Nonce size */ +#define GNRC_LORAWAN_FOPTS_MAX_SIZE (15U) /**< Maximum size of Fopts field */ +#define GNRC_LORAWAN_FPORT_SIZE (1U) /**< Size of the Fport field */ + +/** + * @brief Size of the internal MHDR-MIC buffer + */ +#define MHDR_MIC_BUF_SIZE (sizeof(lorawan_hdr_t) + \ + GNRC_LORAWAN_FOPTS_MAX_SIZE + \ + GNRC_LORAWAN_FPORT_SIZE + \ + MIC_SIZE) + /** * @brief buffer helper for parsing and constructing LoRaWAN packets. */ @@ -130,7 +141,7 @@ typedef struct { * @brief MCPS data */ typedef struct { - gnrc_pktsnip_t *pkt; /**< packet of the request */ + iolist_t *pkt; /**< packet of the request */ uint8_t port; /**< port of the request */ uint8_t dr; /**< datarate of the request */ } mcps_data_t; @@ -141,10 +152,11 @@ typedef struct { typedef struct { uint32_t fcnt; /**< uplink framecounter */ uint32_t fcnt_down; /**< downlink frame counter */ - gnrc_pktsnip_t *outgoing_pkt; /**< holds the outgoing packet in case of retransmissions */ + iolist_t *msdu; /**< current MSDU */ int nb_trials; /**< holds the remaining number of retransmissions */ int ack_requested; /**< whether the network server requested an ACK */ int waiting_for_ack; /**< true if the MAC layer is waiting for an ACK */ + char mhdr_mic[MHDR_MIC_BUF_SIZE]; /**< internal retransmissions buffer */ } gnrc_lorawan_mcps_t; /** @@ -189,7 +201,7 @@ typedef struct { * * @note This function is also used for decrypting a LoRaWAN packet. The LoRaWAN server encrypts the packet using decryption, so the end device only needs to implement encryption * - * @param[in] iolist packet iolist representation + * @param[in] iolist pointer to the MSDU frame * @param[in] dev_addr device address * @param[in] fcnt frame counter * @param[in] dir direction of the packet (0 if uplink, 1 if downlink) @@ -243,7 +255,7 @@ int gnrc_lorawan_set_dr(gnrc_lorawan_t *mac, uint8_t datarate); * @return full LoRaWAN frame including payload * @return NULL if packet buffer is full. `payload` is released */ -gnrc_pktsnip_t *gnrc_lorawan_build_uplink(gnrc_lorawan_t *mac, gnrc_pktsnip_t *payload, int confirmed_data, uint8_t port); +size_t gnrc_lorawan_build_uplink(gnrc_lorawan_t *mac, iolist_t *payload, int confirmed_data, uint8_t port); /** * @brief pick a random available LoRaWAN channel @@ -277,11 +289,12 @@ void gnrc_lorawan_process_fopts(gnrc_lorawan_t *mac, uint8_t *fopts, size_t size /** * @brief calculate join Message Integrity Code * - * @param[in] io iolist representation of the packet + * @param[in] buf pointer to the frame + * @param[in] len length of the frame * @param[in] key key used to calculate the MIC * @param[out] out calculated MIC */ -void gnrc_lorawan_calculate_join_mic(const iolist_t *io, const uint8_t *key, le_uint32_t *out); +void gnrc_lorawan_calculate_join_mic(const uint8_t *buf, size_t len, const uint8_t *key, le_uint32_t *out); /** * @brief Calculate Message Integrity Code for a MCPS message @@ -289,13 +302,12 @@ void gnrc_lorawan_calculate_join_mic(const iolist_t *io, const uint8_t *key, le * @param[in] dev_addr the Device Address * @param[in] fcnt frame counter * @param[in] dir direction of the packet (0 is uplink, 1 is downlink) - * @param[in] pkt the pkt + * @param[in] frame pointer to the PSDU frame (witout MIC) * @param[in] nwkskey pointer to the Network Session Key * @param[out] out calculated MIC */ void gnrc_lorawan_calculate_mic(const le_uint32_t *dev_addr, uint32_t fcnt, - uint8_t dir, iolist_t *pkt, const uint8_t *nwkskey, le_uint32_t *out); - + uint8_t dir, iolist_t *frame, const uint8_t *nwkskey, le_uint32_t *out); /** * @brief Build a MCPS LoRaWAN header * @@ -314,9 +326,10 @@ size_t gnrc_lorawan_build_hdr(uint8_t mtype, le_uint32_t *dev_addr, uint32_t fcn * @brief Process an MCPS downlink message (confirmable or non comfirmable) * * @param[in] mac pointer to the MAC descriptor - * @param[in] pkt pointer to the downlink message + * @param[in] psdu pointer to the downlink PSDU + * @param[in] size size of the PSDU */ -void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt); +void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, uint8_t *psdu, size_t size); /** * @brief Init regional channel settings. @@ -340,18 +353,19 @@ void gnrc_lorawan_reset(gnrc_lorawan_t *mac); * @brief Send a LoRaWAN packet * * @param[in] mac pointer to the MAC descriptor - * @param[in] pkt the packet to be sent + * @param[in] psdu the psdu frame to be sent * @param[in] dr the datarate used for the transmission */ -void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt, uint8_t dr); +void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, iolist_t *psdu, uint8_t dr); /** * @brief Process join accept message * * @param[in] mac pointer to the MAC descriptor - * @param[in] pkt the Join Accept packet + * @param[in] data the Join Accept packet + * @param[in] size size of the Join Accept packet */ -void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt); +void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, uint8_t *data, size_t size); /** * @brief Inform the MAC layer that no packet was received during reception. @@ -364,13 +378,18 @@ void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt); void gnrc_lorawan_mlme_no_rx(gnrc_lorawan_t *mac); /** - * @brief Trigger a MCPS event + * @brief Mac callback for no RX * * @param[in] mac pointer to the MAC descriptor - * @param[in] event the event to be processed. - * @param[in] data set to true if the packet contains payload */ -void gnrc_lorawan_mcps_event(gnrc_lorawan_t *mac, int event, int data); +void gnrc_lorawan_event_no_rx(gnrc_lorawan_t *mac); + +/** + * @brief Mac callback for ACK timeout event + * + * @param[in] mac pointer to the MAC descriptor + */ +void gnrc_lorawan_event_ack_timeout(gnrc_lorawan_t *mac); /** * @brief Get the maximum MAC payload (M value) for a given datarate. @@ -400,7 +419,7 @@ void gnrc_lorawan_mlme_backoff_expire(gnrc_lorawan_t *mac); * @param[in] mac pointer to the MAC descriptor * @param[in] pkt the received packet */ -void gnrc_lorawan_process_pkt(gnrc_lorawan_t *mac, gnrc_pktsnip_t *pkt); +void gnrc_lorawan_process_pkt(gnrc_lorawan_t *mac, iolist_t *pkt); /** * @brief Open a reception window diff --git a/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c b/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c index 43e213282a..7f89896dcd 100644 --- a/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c +++ b/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c @@ -85,9 +85,10 @@ static inline void _set_be_addr(gnrc_lorawan_t *mac, uint8_t *be_addr) void gnrc_lorawan_mcps_indication(gnrc_lorawan_t *mac, mcps_indication_t *ind) { (void) mac; + gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, ind->data.pkt->iol_base, ind->data.pkt->iol_len, GNRC_NETTYPE_LORAWAN); if (!gnrc_netapi_dispatch_receive(GNRC_NETTYPE_LORAWAN, ind->data.port, - ind->data.pkt)) { - gnrc_pktbuf_release(ind->data.pkt); + pkt)) { + gnrc_pktbuf_release(pkt); } } @@ -99,13 +100,12 @@ void gnrc_lorawan_mlme_indication(gnrc_lorawan_t *mac, mlme_indication_t *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; + (void)mac; + + gnrc_pktbuf_release_error((gnrc_pktsnip_t *)confirm->msdu, confirm->status); + + DEBUG("gnrc_lorawan: transmission finished with status %i\n", + confirm->status); } static void _rx_done(gnrc_lorawan_t *mac) @@ -116,20 +116,21 @@ static void _rx_done(gnrc_lorawan_t *mac) 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"); + DEBUG("_recv_lorawan: cannot allocate pktsnip.\n"); /* Discard packet on netdev device */ dev->driver->recv(dev, NULL, bytes_expected, NULL); - gnrc_lorawan_radio_rx_done_cb(mac, NULL); + gnrc_lorawan_radio_rx_done_cb(mac, NULL, 0); return; } nread = dev->driver->recv(dev, pkt->data, bytes_expected, &rx_info); if (nread <= 0) { gnrc_pktbuf_release(pkt); - gnrc_lorawan_radio_rx_done_cb(mac, NULL); + gnrc_lorawan_radio_rx_done_cb(mac, NULL, 0); return; } - gnrc_lorawan_radio_rx_done_cb(mac, pkt); + gnrc_lorawan_radio_rx_done_cb(mac, pkt->data, pkt->size); + gnrc_pktbuf_release(pkt); } static void _driver_cb(netdev_t *dev, netdev_event_t event) @@ -229,10 +230,13 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *payload) gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, &mlme_confirm); } mcps_request_t req = { .type = netif->lorawan.ack_req ? MCPS_CONFIRMED : MCPS_UNCONFIRMED, - .data = { .pkt = payload, .port = netif->lorawan.port, + .data = { .pkt = (iolist_t*) payload, .port = netif->lorawan.port, .dr = netif->lorawan.datarate } }; mcps_confirm_t conf; gnrc_lorawan_mcps_request(&netif->lorawan.mac, &req, &conf); + if (conf.status < 0) { + gnrc_pktbuf_release_error(payload, conf.status); + } return conf.status; } @@ -245,7 +249,7 @@ static void _msg_handler(gnrc_netif_t *netif, msg_t *msg) gnrc_lorawan_open_rx_window(&netif->lorawan.mac); break; case MSG_TYPE_MCPS_ACK_TIMEOUT: - gnrc_lorawan_mcps_event(&netif->lorawan.mac, MCPS_EVENT_ACK_TIMEOUT, 0); + gnrc_lorawan_event_ack_timeout(&netif->lorawan.mac); break; case MSG_TYPE_MLME_BACKOFF_EXPIRE: gnrc_lorawan_mlme_backoff_expire(&netif->lorawan.mac); From fda73fdf0a2e5a3c8bfe7273c87ca079e3bf5027 Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Tue, 28 Jul 2020 15:05:04 +0200 Subject: [PATCH 5/5] gnrc_lorawan: uncrustify files --- examples/gnrc_lorawan/main.c | 5 +- sys/include/net/gnrc/lorawan.h | 67 ++++++----- .../gnrc/link_layer/lorawan/gnrc_lorawan.c | 55 ++++++--- .../link_layer/lorawan/gnrc_lorawan_crypto.c | 30 +++-- .../link_layer/lorawan/gnrc_lorawan_mcps.c | 98 +++++++++++----- .../link_layer/lorawan/gnrc_lorawan_mlme.c | 83 ++++++++----- .../lorawan/include/gnrc_lorawan_internal.h | 62 ++++++---- .../gnrc/netif/lorawan/gnrc_netif_lorawan.c | 111 +++++++++++------- 8 files changed, 324 insertions(+), 187 deletions(-) diff --git a/examples/gnrc_lorawan/main.c b/examples/gnrc_lorawan/main.c index fa83bf0238..42ed6a4210 100644 --- a/examples/gnrc_lorawan/main.c +++ b/examples/gnrc_lorawan/main.c @@ -49,7 +49,7 @@ int tx_cmd(int argc, char **argv) uint8_t port = LORAWAN_PORT; /* Default: 2 */ int interface; - if(argc < 3) { + if (argc < 3) { _usage(); return 1; } @@ -91,7 +91,7 @@ int tx_cmd(int argc, char **argv) } static const shell_command_t shell_commands[] = { - { "send", "Send LoRaWAN data", tx_cmd}, + { "send", "Send LoRaWAN data", tx_cmd }, { NULL, NULL, NULL } }; @@ -102,6 +102,7 @@ int main(void) puts("Initialization successful - starting the shell now"); gnrc_netreg_entry_t dump = GNRC_NETREG_ENTRY_INIT_PID(LORAWAN_PORT, gnrc_pktdump_pid); + gnrc_netreg_register(GNRC_NETTYPE_LORAWAN, &dump); char line_buf[SHELL_DEFAULT_BUFSIZE]; diff --git a/sys/include/net/gnrc/lorawan.h b/sys/include/net/gnrc/lorawan.h index 8bcbb74793..6a06ad32da 100644 --- a/sys/include/net/gnrc/lorawan.h +++ b/sys/include/net/gnrc/lorawan.h @@ -61,53 +61,53 @@ extern "C" { * @brief MCPS events */ typedef enum { - MCPS_EVENT_RX, /**< MCPS RX event */ - MCPS_EVENT_NO_RX, /**< MCPS no RX event */ + MCPS_EVENT_RX, /**< MCPS RX event */ + MCPS_EVENT_NO_RX, /**< MCPS no RX event */ } mcps_event_t; /** * @brief LoRaWAN activation mechanism */ typedef enum { - MLME_ACTIVATION_NONE, /**< MAC layer is not activated */ - MLME_ACTIVATION_ABP, /**< MAC layer activated by ABP */ - MLME_ACTIVATION_OTAA /**< MAC layer activated by OTAA */ + MLME_ACTIVATION_NONE, /**< MAC layer is not activated */ + MLME_ACTIVATION_ABP, /**< MAC layer activated by ABP */ + MLME_ACTIVATION_OTAA /**< MAC layer activated by OTAA */ } mlme_activation_t; /** * @brief MAC Information Base attributes */ typedef enum { - MIB_ACTIVATION_METHOD, /**< type is activation method */ - MIB_DEV_ADDR, /**< type is dev addr */ - MIB_RX2_DR, /**< type is rx2 DR */ + 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; /** * @brief MLME primitive types */ typedef enum { - MLME_JOIN, /**< join a LoRaWAN network */ - MLME_LINK_CHECK, /**< perform a Link Check */ - MLME_RESET, /**< reset the MAC layer */ - MLME_SET, /**< set the MIB */ - MLME_GET, /**< get the MIB */ - MLME_SCHEDULE_UPLINK /**< schedule uplink indication */ + MLME_JOIN, /**< join a LoRaWAN network */ + MLME_LINK_CHECK, /**< perform a Link Check */ + MLME_RESET, /**< reset the MAC layer */ + MLME_SET, /**< set the MIB */ + MLME_GET, /**< get the MIB */ + MLME_SCHEDULE_UPLINK /**< schedule uplink indication */ } mlme_type_t; /** * @brief MCPS primitive types */ typedef enum { - MCPS_CONFIRMED, /**< confirmed data */ - MCPS_UNCONFIRMED /**< unconfirmed data */ + MCPS_CONFIRMED, /**< confirmed data */ + MCPS_UNCONFIRMED /**< unconfirmed data */ } mcps_type_t; /** * @brief MAC Information Base descriptor for MLME Request-Confirm */ typedef struct { - mlme_mib_type_t type; /**< MIB attribute identifier */ + mlme_mib_type_t type; /**< MIB attribute identifier */ union { mlme_activation_t activation; /**< holds activation mechanism */ void *dev_addr; /**< pointer to the dev_addr */ @@ -120,10 +120,10 @@ typedef struct { */ typedef struct { union { - mlme_lorawan_join_t join; /**< Join Data holder */ - mlme_mib_t mib; /**< MIB holder */ + mlme_lorawan_join_t join; /**< Join Data holder */ + mlme_mib_t mib; /**< MIB holder */ }; - mlme_type_t type; /**< type of the MLME request */ + mlme_type_t type; /**< type of the MLME request */ } mlme_request_t; /** @@ -131,20 +131,20 @@ typedef struct { */ typedef struct { union { - mcps_data_t data; /**< MCPS data holder */ + mcps_data_t data; /**< MCPS data holder */ }; - mcps_type_t type; /**< type of the MCPS request */ + mcps_type_t type; /**< type of the MCPS request */ } mcps_request_t; /** * @brief MAC (sub) Layer Management Entity (MLME) confirm representation */ typedef struct { - int16_t status; /**< status of the MLME confirm */ - mlme_type_t type; /**< type of the MLME confirm */ + int16_t status; /**< status of the MLME confirm */ + mlme_type_t type; /**< type of the MLME confirm */ union { - mlme_link_req_confirm_t link_req; /**< Link Check confirmation data */ - mlme_mib_t mib; /**< MIB confirmation data */ + mlme_link_req_confirm_t link_req; /**< Link Check confirmation data */ + mlme_mib_t mib; /**< MIB confirmation data */ }; } mlme_confirm_t; @@ -152,7 +152,7 @@ typedef struct { * @brief Mac Common Part Sublayer (MCPS) confirm representation */ typedef struct { - int16_t status; /**< status of the MCPS confirm */ + int16_t status; /**< status of the MCPS confirm */ mcps_type_t type; /**< type of the MCPS confirm */ iolist_t *msdu; /**< pointer to the msdu */ } mcps_confirm_t; @@ -161,9 +161,9 @@ typedef struct { * @brief Mac Common Part Sublayer (MCPS) indication representation */ typedef struct { - mcps_type_t type; /**< type of the MCPS indication */ + mcps_type_t type; /**< type of the MCPS indication */ union { - mcps_data_t data; /**< MCPS Data holder */ + mcps_data_t data; /**< MCPS Data holder */ }; } mcps_indication_t; @@ -207,7 +207,8 @@ void gnrc_lorawan_init(gnrc_lorawan_t *mac, uint8_t *nwkskey, uint8_t *appskey); * GNRC_LORAWAN_REQ_STATUS_DEFERRED if the confirmation is deferred * or an standard error number */ -void gnrc_lorawan_mlme_request(gnrc_lorawan_t *mac, const mlme_request_t *mlme_request, +void gnrc_lorawan_mlme_request(gnrc_lorawan_t *mac, + const mlme_request_t *mlme_request, mlme_confirm_t *mlme_confirm); /** @@ -220,7 +221,8 @@ void gnrc_lorawan_mlme_request(gnrc_lorawan_t *mac, const mlme_request_t *mlme_r * GNRC_LORAWAN_REQ_STATUS_DEFERRED if the confirmation is deferred * or an standard error number */ -void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_request, +void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, + const mcps_request_t *mcps_request, mcps_confirm_t *mcps_confirm); /** @@ -233,7 +235,8 @@ void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_r * allocation failed) * @param[in] size size of the PSDU */ -void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, uint8_t *data, size_t size); +void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, uint8_t *data, + size_t size); /** * @brief MCPS indication callback diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c index fc134d7c0c..3674783c51 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c @@ -30,18 +30,19 @@ /* This factor is used for converting "real" seconds into microcontroller * microseconds. This is done in order to correct timer drift. */ -#define _DRIFT_FACTOR (int) (US_PER_SEC * 100 / (100 + (CONFIG_GNRC_LORAWAN_TIMER_DRIFT / 10.0))) +#define _DRIFT_FACTOR (int)(US_PER_SEC * 100 / \ + (100 + (CONFIG_GNRC_LORAWAN_TIMER_DRIFT / 10.0))) -#define GNRC_LORAWAN_DL_RX2_DR_MASK (0x0F) /**< DL Settings DR Offset mask */ -#define GNRC_LORAWAN_DL_RX2_DR_POS (0) /**< DL Settings DR Offset pos */ -#define GNRC_LORAWAN_DL_DR_OFFSET_MASK (0x70) /**< DL Settings RX2 DR mask */ -#define GNRC_LORAWAN_DL_DR_OFFSET_POS (4) /**< DL Settings RX2 DR pos */ +#define GNRC_LORAWAN_DL_RX2_DR_MASK (0x0F) /**< DL Settings DR Offset mask */ +#define GNRC_LORAWAN_DL_RX2_DR_POS (0) /**< DL Settings DR Offset pos */ +#define GNRC_LORAWAN_DL_DR_OFFSET_MASK (0x70) /**< DL Settings RX2 DR mask */ +#define GNRC_LORAWAN_DL_DR_OFFSET_POS (4) /**< DL Settings RX2 DR pos */ static inline void gnrc_lorawan_mlme_reset(gnrc_lorawan_t *mac) { mac->mlme.activation = MLME_ACTIVATION_NONE; mac->mlme.pending_mlme_opts = 0; - mac->rx_delay = (LORAMAC_DEFAULT_RX1_DELAY/MS_PER_SEC); + mac->rx_delay = (LORAMAC_DEFAULT_RX1_DELAY / MS_PER_SEC); mac->mlme.nid = LORAMAC_DEFAULT_NETID; } @@ -65,7 +66,7 @@ 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) & - GNRC_LORAWAN_DL_RX2_DR_MASK; + GNRC_LORAWAN_DL_RX2_DR_MASK; } static void _sleep_radio(gnrc_lorawan_t *mac) @@ -94,10 +95,12 @@ void gnrc_lorawan_reset(gnrc_lorawan_t *mac) uint8_t syncword = LORAMAC_DEFAULT_PUBLIC_NETWORK ? LORA_SYNCWORD_PUBLIC : LORA_SYNCWORD_PRIVATE; + dev->driver->set(dev, NETOPT_SYNCWORD, &syncword, sizeof(syncword)); /* Continuous reception */ uint32_t rx_timeout = 0; + dev->driver->set(dev, NETOPT_RX_TIMEOUT, &rx_timeout, sizeof(rx_timeout)); gnrc_lorawan_set_rx2_dr(mac, LORAMAC_DEFAULT_RX2_DR); @@ -108,15 +111,18 @@ void gnrc_lorawan_reset(gnrc_lorawan_t *mac) gnrc_lorawan_channels_init(mac); } -static void _config_radio(gnrc_lorawan_t *mac, uint32_t channel_freq, uint8_t dr, int rx) +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) { - dev->driver->set(dev, 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; + dev->driver->set(dev, NETOPT_IQ_INVERT, &iq_invert, sizeof(iq_invert)); gnrc_lorawan_set_dr(mac, dr); @@ -126,11 +132,13 @@ static void _config_radio(gnrc_lorawan_t *mac, uint32_t channel_freq, uint8_t dr const netopt_enable_t single = true; dev->driver->set(dev, NETOPT_SINGLE_RECEIVE, &single, sizeof(single)); const uint16_t timeout = CONFIG_GNRC_LORAWAN_MIN_SYMBOLS_TIMEOUT; - dev->driver->set(dev, NETOPT_RX_SYMBOL_TIMEOUT, &timeout, sizeof(timeout)); + dev->driver->set(dev, NETOPT_RX_SYMBOL_TIMEOUT, &timeout, + sizeof(timeout)); } } -static void _configure_rx_window(gnrc_lorawan_t *mac, uint32_t channel_freq, uint8_t dr) +static void _configure_rx_window(gnrc_lorawan_t *mac, uint32_t channel_freq, + uint8_t dr) { _config_radio(mac, channel_freq, dr, true); } @@ -138,12 +146,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()); } netopt_state_t state = NETOPT_STATE_RX; + dev->driver->set(dev, NETOPT_STATE, &state, sizeof(state)); } @@ -153,6 +163,7 @@ void gnrc_lorawan_radio_tx_done_cb(gnrc_lorawan_t *mac) mac->state = LORAWAN_STATE_RX_1; int rx_1; + /* if the MAC is not activated, then this is a Join Request */ rx_1 = mac->mlme.activation == MLME_ACTIVATION_NONE ? LORAMAC_DEFAULT_JOIN_DELAY1 : mac->rx_delay; @@ -160,18 +171,23 @@ void gnrc_lorawan_radio_tx_done_cb(gnrc_lorawan_t *mac) xtimer_set_msg(&mac->rx, rx_1 * _DRIFT_FACTOR, &mac->msg, thread_getpid()); uint8_t dr_offset = (mac->dl_settings & GNRC_LORAWAN_DL_DR_OFFSET_MASK) >> - GNRC_LORAWAN_DL_DR_OFFSET_POS; - _configure_rx_window(mac, 0, gnrc_lorawan_rx1_get_dr_offset(mac->last_dr, dr_offset)); + GNRC_LORAWAN_DL_DR_OFFSET_POS; + + _configure_rx_window(mac, 0, + gnrc_lorawan_rx1_get_dr_offset(mac->last_dr, + dr_offset)); _sleep_radio(mac); } void gnrc_lorawan_radio_rx_timeout_cb(gnrc_lorawan_t *mac) { - (void) mac; + (void)mac; switch (mac->state) { case LORAWAN_STATE_RX_1: - _configure_rx_window(mac, LORAMAC_DEFAULT_RX2_FREQ, mac->dl_settings & GNRC_LORAWAN_DL_RX2_DR_MASK); + _configure_rx_window(mac, LORAMAC_DEFAULT_RX2_FREQ, + mac->dl_settings & + GNRC_LORAWAN_DL_RX2_DR_MASK); mac->state = LORAWAN_STATE_RX_2; break; case LORAWAN_STATE_RX_2: @@ -205,6 +221,7 @@ static uint32_t lora_time_on_air(size_t payload_size, uint8_t dr, uint8_t cr) int nb_symbols; uint8_t offset = _K[index][1]; + if (payload_size < offset) { nb_symbols = 8 + n0 * cr; } @@ -217,18 +234,22 @@ static uint32_t lora_time_on_air(size_t payload_size, uint8_t dr, uint8_t cr) } uint32_t t_payload = t_sym * nb_symbols; + return t_preamble + t_payload; } void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, iolist_t *psdu, uint8_t dr) { netdev_t *dev = gnrc_lorawan_get_netdev(mac); + mac->state = LORAWAN_STATE_TX; uint32_t chan = gnrc_lorawan_pick_channel(mac); + _config_radio(mac, chan, dr, false); uint8_t cr; + dev->driver->get(dev, NETOPT_CODING_RATE, &cr, sizeof(cr)); mac->toa = lora_time_on_air(iolist_size(psdu), dr, cr + 4); @@ -239,7 +260,8 @@ void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, iolist_t *psdu, uint8_t dr) } -void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, uint8_t *psdu, size_t size) +void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, uint8_t *psdu, + size_t size) { _sleep_radio(mac); if (psdu == NULL) { @@ -249,6 +271,7 @@ void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, uint8_t *psdu, size_t si xtimer_remove(&mac->rx); uint8_t mtype = (*psdu & MTYPE_MASK) >> 5; + switch (mtype) { case MTYPE_JOIN_ACCEPT: gnrc_lorawan_mlme_process_join(mac, psdu, size); diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c index e0a2da03c6..535a483155 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c @@ -45,7 +45,8 @@ typedef struct __attribute__((packed)) { uint8_t len; } lorawan_block_t; -void gnrc_lorawan_calculate_join_mic(const uint8_t *buf, size_t len, const uint8_t *key, le_uint32_t *out) +void gnrc_lorawan_calculate_join_mic(const uint8_t *buf, size_t len, + const uint8_t *key, le_uint32_t *out) { cmac_init(&CmacContext, key, LORAMAC_APPKEY_LEN); cmac_update(&CmacContext, buf, len); @@ -55,7 +56,8 @@ void gnrc_lorawan_calculate_join_mic(const uint8_t *buf, size_t len, const uint8 } void gnrc_lorawan_calculate_mic(const le_uint32_t *dev_addr, uint32_t fcnt, - uint8_t dir, iolist_t *frame, const uint8_t *nwkskey, le_uint32_t *out) + uint8_t dir, iolist_t *frame, + const uint8_t *nwkskey, le_uint32_t *out) { lorawan_block_t block; @@ -81,7 +83,9 @@ void gnrc_lorawan_calculate_mic(const le_uint32_t *dev_addr, uint32_t fcnt, memcpy(out, digest, sizeof(le_uint32_t)); } -void gnrc_lorawan_encrypt_payload(iolist_t *iolist, const le_uint32_t *dev_addr, uint32_t fcnt, uint8_t dir, const uint8_t *appskey) +void gnrc_lorawan_encrypt_payload(iolist_t *iolist, const le_uint32_t *dev_addr, + uint32_t fcnt, uint8_t dir, + const uint8_t *appskey) { uint8_t s_block[16]; uint8_t a_block[16]; @@ -89,7 +93,7 @@ void gnrc_lorawan_encrypt_payload(iolist_t *iolist, const le_uint32_t *dev_addr, memset(s_block, 0, sizeof(s_block)); memset(a_block, 0, sizeof(a_block)); - lorawan_block_t *block = (lorawan_block_t *) a_block; + lorawan_block_t *block = (lorawan_block_t *)a_block; cipher_init(&AesContext, CIPHER_AES_128, appskey, LORAMAC_APPKEY_LEN); @@ -104,6 +108,7 @@ void gnrc_lorawan_encrypt_payload(iolist_t *iolist, const le_uint32_t *dev_addr, block->u32_pad = 0; int c = 0; + for (iolist_t *io = iolist; io != NULL; io = io->iol_next) { for (unsigned i = 0; i < io->iol_len; i++) { uint8_t *v = io->iol_base; @@ -119,17 +124,22 @@ void gnrc_lorawan_encrypt_payload(iolist_t *iolist, const le_uint32_t *dev_addr, } } -void gnrc_lorawan_decrypt_join_accept(const uint8_t *key, uint8_t *pkt, int has_clist, uint8_t *out) +void gnrc_lorawan_decrypt_join_accept(const uint8_t *key, uint8_t *pkt, + int has_clist, uint8_t *out) { cipher_init(&AesContext, CIPHER_AES_128, key, LORAMAC_APPKEY_LEN); cipher_encrypt(&AesContext, pkt, out); if (has_clist) { - cipher_encrypt(&AesContext, pkt + LORAMAC_APPKEY_LEN, out + LORAMAC_APPKEY_LEN); + cipher_encrypt(&AesContext, pkt + LORAMAC_APPKEY_LEN, + out + LORAMAC_APPKEY_LEN); } } -void gnrc_lorawan_generate_session_keys(const uint8_t *app_nonce, const uint8_t *dev_nonce, const uint8_t *appkey, uint8_t *nwkskey, uint8_t *appskey) +void gnrc_lorawan_generate_session_keys(const uint8_t *app_nonce, + const uint8_t *dev_nonce, + const uint8_t *appkey, uint8_t *nwkskey, + uint8_t *appskey) { uint8_t buf[LORAMAC_APPSKEY_LEN]; @@ -138,8 +148,10 @@ void gnrc_lorawan_generate_session_keys(const uint8_t *app_nonce, const uint8_t cipher_init(&AesContext, CIPHER_AES_128, appkey, LORAMAC_APPSKEY_LEN); /* net_id comes right after app_nonce */ - memcpy(buf + 1, app_nonce, GNRC_LORAWAN_APP_NONCE_SIZE + GNRC_LORAWAN_NET_ID_SIZE); - memcpy(buf + 1 + GNRC_LORAWAN_APP_NONCE_SIZE + GNRC_LORAWAN_NET_ID_SIZE, dev_nonce, GNRC_LORAWAN_DEV_NONCE_SIZE); + memcpy(buf + 1, app_nonce, + GNRC_LORAWAN_APP_NONCE_SIZE + GNRC_LORAWAN_NET_ID_SIZE); + memcpy(buf + 1 + GNRC_LORAWAN_APP_NONCE_SIZE + GNRC_LORAWAN_NET_ID_SIZE, + dev_nonce, GNRC_LORAWAN_DEV_NONCE_SIZE); /* Calculate Application Session Key */ buf[0] = APP_SKEY_B0_START; diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c index fdbb857ab7..35e0e1c5cf 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mcps.c @@ -36,13 +36,15 @@ static int gnrc_lorawan_mic_is_valid(uint8_t *buf, size_t len, uint8_t *nwkskey) { le_uint32_t calc_mic; - lorawan_hdr_t *lw_hdr = (lorawan_hdr_t *) buf; + lorawan_hdr_t *lw_hdr = (lorawan_hdr_t *)buf; uint32_t fcnt = byteorder_ntohs(byteorder_ltobs(lw_hdr->fcnt)); - iolist_t iol = {.iol_base = buf, .iol_len = len - MIC_SIZE, .iol_next = NULL}; + iolist_t iol = + { .iol_base = buf, .iol_len = len - MIC_SIZE, .iol_next = NULL }; + gnrc_lorawan_calculate_mic(&lw_hdr->addr, fcnt, GNRC_LORAWAN_DIR_DOWNLINK, &iol, nwkskey, &calc_mic); - return calc_mic.u32 == ((le_uint32_t *) (buf+len-MIC_SIZE))->u32; + return calc_mic.u32 == ((le_uint32_t *)(buf + len - MIC_SIZE))->u32; } uint32_t gnrc_lorawan_fcnt_stol(uint32_t fcnt_down, uint16_t s_fcnt) @@ -71,11 +73,11 @@ struct parsed_packet { }; int gnrc_lorawan_parse_dl(gnrc_lorawan_t *mac, uint8_t *buf, size_t len, - struct parsed_packet *pkt) + struct parsed_packet *pkt) { memset(pkt, 0, sizeof(struct parsed_packet)); - lorawan_hdr_t *_hdr = (lorawan_hdr_t*) buf; + lorawan_hdr_t *_hdr = (lorawan_hdr_t *)buf; uint8_t *p_mic = buf + len - MIC_SIZE; pkt->hdr = _hdr; @@ -87,7 +89,9 @@ int gnrc_lorawan_parse_dl(gnrc_lorawan_t *mac, uint8_t *buf, size_t len, return -1; } - uint32_t _fcnt = gnrc_lorawan_fcnt_stol(mac->mcps.fcnt_down, _hdr->fcnt.u16); + uint32_t _fcnt = + gnrc_lorawan_fcnt_stol(mac->mcps.fcnt_down, _hdr->fcnt.u16); + if (mac->mcps.fcnt_down > _fcnt || mac->mcps.fcnt_down + LORAMAC_DEFAULT_MAX_FCNT_GAP < _fcnt) { DEBUG("gnrc_lorawan: wrong frame counter\n"); @@ -97,13 +101,14 @@ int gnrc_lorawan_parse_dl(gnrc_lorawan_t *mac, uint8_t *buf, size_t len, pkt->fcnt_down = _fcnt; int fopts_length = lorawan_hdr_get_frame_opts_len(_hdr); - if(fopts_length) { + + if (fopts_length) { pkt->fopts.iol_base = buf; pkt->fopts.iol_len = fopts_length; buf += fopts_length; } - if(buf < p_mic) { + if (buf < p_mic) { pkt->port = *(buf++); if (!pkt->port && fopts_length) { @@ -124,7 +129,8 @@ int gnrc_lorawan_parse_dl(gnrc_lorawan_t *mac, uint8_t *buf, size_t len, return 0; } -void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, uint8_t *psdu, size_t size) +void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, uint8_t *psdu, + size_t size) { struct parsed_packet _pkt; @@ -142,20 +148,24 @@ void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, uint8_t *psdu, size } iolist_t *fopts = NULL; - if(_pkt.fopts.iol_base) { + + if (_pkt.fopts.iol_base) { fopts = &_pkt.fopts; } - if(_pkt.enc_payload.iol_base) { + if (_pkt.enc_payload.iol_base) { uint8_t *key; - if(_pkt.port) { + if (_pkt.port) { key = mac->appskey; } else { key = mac->nwkskey; fopts = &_pkt.enc_payload; } - gnrc_lorawan_encrypt_payload(&_pkt.enc_payload, &_pkt.hdr->addr, byteorder_ntohs(byteorder_ltobs(_pkt.hdr->fcnt)), GNRC_LORAWAN_DIR_DOWNLINK, key); + gnrc_lorawan_encrypt_payload(&_pkt.enc_payload, &_pkt.hdr->addr, + byteorder_ntohs(byteorder_ltobs( + _pkt.hdr->fcnt)), GNRC_LORAWAN_DIR_DOWNLINK, + key); } mac->mcps.fcnt_down = _pkt.fcnt_down; @@ -192,10 +202,12 @@ void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, uint8_t *psdu, size } } -size_t gnrc_lorawan_build_hdr(uint8_t mtype, le_uint32_t *dev_addr, uint32_t fcnt, uint8_t ack, uint8_t fopts_length, lorawan_buffer_t *buf) +size_t gnrc_lorawan_build_hdr(uint8_t mtype, le_uint32_t *dev_addr, + uint32_t fcnt, uint8_t ack, uint8_t fopts_length, + lorawan_buffer_t *buf) { assert(fopts_length < 16); - lorawan_hdr_t *lw_hdr = (lorawan_hdr_t *) buf->data; + lorawan_hdr_t *lw_hdr = (lorawan_hdr_t *)buf->data; lw_hdr->mt_maj = 0; lorawan_hdr_set_mtype(lw_hdr, mtype); @@ -214,17 +226,19 @@ size_t gnrc_lorawan_build_hdr(uint8_t mtype, le_uint32_t *dev_addr, uint32_t fcn return sizeof(lorawan_hdr_t); } -size_t gnrc_lorawan_build_uplink(gnrc_lorawan_t *mac, iolist_t *payload, int confirmed_data, uint8_t port) +size_t gnrc_lorawan_build_uplink(gnrc_lorawan_t *mac, iolist_t *payload, + int confirmed_data, uint8_t port) { lorawan_buffer_t buf = { - .data = (uint8_t *) mac->mcps.mhdr_mic, + .data = (uint8_t *)mac->mcps.mhdr_mic, .size = sizeof(mac->mcps.mhdr_mic), .index = 0 }; - lorawan_hdr_t *lw_hdr = (lorawan_hdr_t *) buf.data; + lorawan_hdr_t *lw_hdr = (lorawan_hdr_t *)buf.data; lw_hdr->mt_maj = 0; - lorawan_hdr_set_mtype(lw_hdr, confirmed_data ? MTYPE_CNF_UPLINK : MTYPE_UNCNF_UPLINK); + lorawan_hdr_set_mtype(lw_hdr, + confirmed_data ? MTYPE_CNF_UPLINK : MTYPE_UNCNF_UPLINK); lorawan_hdr_set_maj(lw_hdr, MAJOR_LRWAN_R1); lw_hdr->addr = mac->dev_addr; @@ -237,16 +251,23 @@ size_t gnrc_lorawan_build_uplink(gnrc_lorawan_t *mac, iolist_t *payload, int con buf.index += sizeof(lorawan_hdr_t); int fopts_length = gnrc_lorawan_build_options(mac, &buf); + assert(fopts_length < 16); lorawan_hdr_set_frame_opts_len(lw_hdr, fopts_length); buf.data[buf.index++] = port; - gnrc_lorawan_encrypt_payload(payload, &mac->dev_addr, mac->mcps.fcnt, GNRC_LORAWAN_DIR_UPLINK, port ? mac->appskey : mac->nwkskey); + gnrc_lorawan_encrypt_payload(payload, &mac->dev_addr, mac->mcps.fcnt, + GNRC_LORAWAN_DIR_UPLINK, + port ? mac->appskey : mac->nwkskey); - iolist_t iol = {.iol_base = buf.data, .iol_len = buf.index, .iol_next = payload}; - gnrc_lorawan_calculate_mic(&mac->dev_addr, mac->mcps.fcnt, GNRC_LORAWAN_DIR_UPLINK, - &iol, mac->nwkskey, (le_uint32_t*) &buf.data[buf.index]); + iolist_t iol = + { .iol_base = buf.data, .iol_len = buf.index, .iol_next = payload }; + + gnrc_lorawan_calculate_mic(&mac->dev_addr, mac->mcps.fcnt, + GNRC_LORAWAN_DIR_UPLINK, + &iol, mac->nwkskey, + (le_uint32_t *)&buf.data[buf.index]); return buf.index; } @@ -278,11 +299,17 @@ static void _end_of_tx(gnrc_lorawan_t *mac, int type, int status) static void _transmit_pkt(gnrc_lorawan_t *mac) { - size_t mhdr_size = sizeof(lorawan_hdr_t) + 1 + lorawan_hdr_get_frame_opts_len((void*) mac->mcps.mhdr_mic); + size_t mhdr_size = sizeof(lorawan_hdr_t) + 1 + + lorawan_hdr_get_frame_opts_len((void *)mac->mcps.mhdr_mic); - iolist_t header = {.iol_base = mac->mcps.mhdr_mic, .iol_len = mhdr_size, .iol_next = mac->mcps.msdu}; - iolist_t footer = {.iol_base = mac->mcps.mhdr_mic + header.iol_len, .iol_len = MIC_SIZE, .iol_next = NULL}; + iolist_t header = + { .iol_base = mac->mcps.mhdr_mic, .iol_len = mhdr_size, + .iol_next = mac->mcps.msdu }; + iolist_t footer = + { .iol_base = mac->mcps.mhdr_mic + header.iol_len, .iol_len = MIC_SIZE, + .iol_next = NULL }; iolist_t *last_snip = mac->mcps.msdu; + while (last_snip->iol_next != NULL) { last_snip = last_snip->iol_next; } @@ -306,9 +333,12 @@ static void _handle_retransmissions(gnrc_lorawan_t *mac) { if (mac->mcps.nb_trials-- == 0) { _end_of_tx(mac, MCPS_CONFIRMED, -ETIMEDOUT); - } else { + } + else { mac->msg.type = MSG_TYPE_MCPS_ACK_TIMEOUT; - xtimer_set_msg(&mac->rx, 1000000 + random_uint32_range(0, 2000000), &mac->msg, thread_getpid()); + xtimer_set_msg(&mac->rx, 1000000 + random_uint32_range(0, + 2000000), &mac->msg, + thread_getpid()); } } @@ -335,7 +365,9 @@ void gnrc_lorawan_event_no_rx(gnrc_lorawan_t *mac) } } -void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_request, mcps_confirm_t *mcps_confirm) +void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, + const mcps_request_t *mcps_request, + mcps_confirm_t *mcps_confirm) { iolist_t *pkt = mcps_request->data.pkt; @@ -365,16 +397,18 @@ void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_r /* We don't include the port because `MACPayload` doesn't consider * the MHDR...*/ size_t mac_payload_size = sizeof(lorawan_hdr_t) + fopts_length + - iolist_size(pkt); + iolist_size(pkt); - if (mac_payload_size > gnrc_lorawan_region_mac_payload_max(mcps_request->data.dr)) { + if (mac_payload_size > + gnrc_lorawan_region_mac_payload_max(mcps_request->data.dr)) { mcps_confirm->status = -EMSGSIZE; goto out; } int waiting_for_ack = mcps_request->type == MCPS_CONFIRMED; - gnrc_lorawan_build_uplink(mac, pkt, waiting_for_ack, mcps_request->data.port); + gnrc_lorawan_build_uplink(mac, pkt, waiting_for_ack, + mcps_request->data.port); mac->mcps.waiting_for_ack = waiting_for_ack; mac->mcps.ack_requested = false; diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mlme.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mlme.c index 61e5e39432..97fa98e2ba 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mlme.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_mlme.c @@ -28,33 +28,39 @@ #define ENABLE_DEBUG (0) #include "debug.h" -static void _build_join_req_pkt(uint8_t *appeui, uint8_t *deveui, uint8_t *appkey, uint8_t *dev_nonce, uint8_t *psdu) +static void _build_join_req_pkt(uint8_t *appeui, uint8_t *deveui, + uint8_t *appkey, uint8_t *dev_nonce, + uint8_t *psdu) { - lorawan_join_request_t *hdr = (lorawan_join_request_t *) psdu; + lorawan_join_request_t *hdr = (lorawan_join_request_t *)psdu; hdr->mt_maj = 0; - lorawan_hdr_set_mtype((lorawan_hdr_t *) hdr, MTYPE_JOIN_REQUEST); - lorawan_hdr_set_maj((lorawan_hdr_t *) hdr, MAJOR_LRWAN_R1); + lorawan_hdr_set_mtype((lorawan_hdr_t *)hdr, MTYPE_JOIN_REQUEST); + lorawan_hdr_set_maj((lorawan_hdr_t *)hdr, MAJOR_LRWAN_R1); - le_uint64_t l_appeui = *((le_uint64_t *) appeui); - le_uint64_t l_deveui = *((le_uint64_t *) deveui); + le_uint64_t l_appeui = *((le_uint64_t *)appeui); + le_uint64_t l_deveui = *((le_uint64_t *)deveui); hdr->app_eui = l_appeui; hdr->dev_eui = l_deveui; - le_uint16_t l_dev_nonce = *((le_uint16_t *) dev_nonce); + le_uint16_t l_dev_nonce = *((le_uint16_t *)dev_nonce); + hdr->dev_nonce = l_dev_nonce; - gnrc_lorawan_calculate_join_mic(psdu, JOIN_REQUEST_SIZE - MIC_SIZE, appkey, &hdr->mic); + gnrc_lorawan_calculate_join_mic(psdu, JOIN_REQUEST_SIZE - MIC_SIZE, appkey, + &hdr->mic); } static int gnrc_lorawan_send_join_request(gnrc_lorawan_t *mac, uint8_t *deveui, - uint8_t *appeui, uint8_t *appkey, uint8_t dr) + uint8_t *appeui, uint8_t *appkey, + uint8_t dr) { netdev_t *dev = gnrc_lorawan_get_netdev(mac); /* Dev Nonce */ uint32_t random_number; + dev->driver->get(dev, NETOPT_RANDOM, &random_number, sizeof(random_number)); mac->mlme.dev_nonce[0] = random_number & 0xFF; @@ -63,7 +69,9 @@ static int gnrc_lorawan_send_join_request(gnrc_lorawan_t *mac, uint8_t *deveui, /* build join request */ uint8_t psdu[sizeof(lorawan_join_request_t)]; - iolist_t pkt = {.iol_base = &psdu, .iol_len = sizeof(psdu), .iol_next = NULL}; + iolist_t pkt = + { .iol_base = &psdu, .iol_len = sizeof(psdu), .iol_next = NULL }; + _build_join_req_pkt(appeui, deveui, appkey, mac->mlme.dev_nonce, psdu); /* We need a random delay for join request. Otherwise there might be @@ -76,7 +84,8 @@ static int gnrc_lorawan_send_join_request(gnrc_lorawan_t *mac, uint8_t *deveui, return GNRC_LORAWAN_REQ_STATUS_DEFERRED; } -void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, uint8_t *data, size_t size) +void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, uint8_t *data, + size_t size) { int status; mlme_confirm_t mlme_confirm; @@ -95,12 +104,14 @@ void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, uint8_t *data, size_t s /* 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 = (size - 1) >= CFLIST_SIZE; + gnrc_lorawan_decrypt_join_accept(mac->appskey, data + 1, has_cflist, out); memcpy(data + 1, out, size - 1); le_uint32_t mic; - le_uint32_t *expected_mic = (le_uint32_t *) (data + size - MIC_SIZE); + le_uint32_t *expected_mic = (le_uint32_t *)(data + size - MIC_SIZE); + gnrc_lorawan_calculate_join_mic(data, size - MIC_SIZE, mac->appskey, &mic); if (mic.u32 != expected_mic->u32) { DEBUG("gnrc_lorawan_mlme: wrong MIC.\n"); @@ -108,10 +119,14 @@ void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, uint8_t *data, size_t s goto out; } - lorawan_join_accept_t *ja_hdr = (lorawan_join_accept_t *) data; - gnrc_lorawan_generate_session_keys(ja_hdr->app_nonce, mac->mlme.dev_nonce, mac->appskey, mac->nwkskey, mac->appskey); + lorawan_join_accept_t *ja_hdr = (lorawan_join_accept_t *)data; + + gnrc_lorawan_generate_session_keys(ja_hdr->app_nonce, mac->mlme.dev_nonce, + mac->appskey, mac->nwkskey, + mac->appskey); le_uint32_t le_nid; + le_nid.u32 = 0; memcpy(&le_nid, ja_hdr->net_id, 3); mac->mlme.nid = byteorder_ntohl(byteorder_ltobl(le_nid)); @@ -168,19 +183,20 @@ void gnrc_lorawan_mlme_backoff_expire(gnrc_lorawan_t *mac) } static void _mlme_set(gnrc_lorawan_t *mac, const mlme_request_t *mlme_request, - mlme_confirm_t *mlme_confirm) + mlme_confirm_t *mlme_confirm) { mlme_confirm->status = -EINVAL; - switch(mlme_request->mib.type) { + switch (mlme_request->mib.type) { case MIB_ACTIVATION_METHOD: - if(mlme_request->mib.activation != MLME_ACTIVATION_OTAA) { + if (mlme_request->mib.activation != MLME_ACTIVATION_OTAA) { mlme_confirm->status = GNRC_LORAWAN_REQ_STATUS_SUCCESS; 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)); + 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; @@ -192,9 +208,9 @@ static void _mlme_set(gnrc_lorawan_t *mac, const mlme_request_t *mlme_request, } static void _mlme_get(gnrc_lorawan_t *mac, const mlme_request_t *mlme_request, - mlme_confirm_t *mlme_confirm) + mlme_confirm_t *mlme_confirm) { - switch(mlme_request->mib.type) { + switch (mlme_request->mib.type) { case MIB_ACTIVATION_METHOD: mlme_confirm->status = GNRC_LORAWAN_REQ_STATUS_SUCCESS; mlme_confirm->mib.activation = mac->mlme.activation; @@ -209,12 +225,13 @@ static void _mlme_get(gnrc_lorawan_t *mac, const mlme_request_t *mlme_request, } } -void gnrc_lorawan_mlme_request(gnrc_lorawan_t *mac, const mlme_request_t *mlme_request, +void gnrc_lorawan_mlme_request(gnrc_lorawan_t *mac, + const mlme_request_t *mlme_request, mlme_confirm_t *mlme_confirm) { switch (mlme_request->type) { case MLME_JOIN: - if(mac->mlme.activation != MLME_ACTIVATION_NONE) { + if (mac->mlme.activation != MLME_ACTIVATION_NONE) { mlme_confirm->status = -EINVAL; break; } @@ -228,11 +245,14 @@ void gnrc_lorawan_mlme_request(gnrc_lorawan_t *mac, const mlme_request_t *mlme_r break; } memcpy(mac->appskey, mlme_request->join.appkey, LORAMAC_APPKEY_LEN); - mlme_confirm->status = gnrc_lorawan_send_join_request(mac, mlme_request->join.deveui, - mlme_request->join.appeui, mlme_request->join.appkey, mlme_request->join.dr); + mlme_confirm->status = gnrc_lorawan_send_join_request(mac, + mlme_request->join.deveui, + mlme_request->join.appeui, mlme_request->join.appkey, + mlme_request->join.dr); break; case MLME_LINK_CHECK: - mac->mlme.pending_mlme_opts |= GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ; + mac->mlme.pending_mlme_opts |= + GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ; mlme_confirm->status = GNRC_LORAWAN_REQ_STATUS_DEFERRED; break; case MLME_SET: @@ -263,6 +283,7 @@ 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; + mlme_confirm.link_req.margin = p[1]; mlme_confirm.link_req.num_gateways = p[2]; @@ -273,16 +294,18 @@ static void _mlme_link_check_ans(gnrc_lorawan_t *mac, uint8_t *p) mac->mlme.pending_mlme_opts &= ~GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ; } -void gnrc_lorawan_process_fopts(gnrc_lorawan_t *mac, uint8_t *fopts, size_t size) +void gnrc_lorawan_process_fopts(gnrc_lorawan_t *mac, uint8_t *fopts, + size_t size) { if (!fopts || !size) { return; } uint8_t ret = 0; - void (*cb)(gnrc_lorawan_t*, uint8_t *p) = NULL; - for(uint8_t pos = 0; pos < size; pos += ret) { + void (*cb)(gnrc_lorawan_t *, uint8_t *p) = NULL; + + for (uint8_t pos = 0; pos < size; pos += ret) { switch (fopts[pos]) { case GNRC_LORAWAN_CID_LINK_CHECK_ANS: ret += GNRC_LORAWAN_FOPT_LINK_CHECK_ANS_SIZE; @@ -292,7 +315,7 @@ void gnrc_lorawan_process_fopts(gnrc_lorawan_t *mac, uint8_t *fopts, size_t size return; } - if(pos + ret > size) { + if (pos + ret > size) { return; } @@ -304,7 +327,7 @@ uint8_t gnrc_lorawan_build_options(gnrc_lorawan_t *mac, lorawan_buffer_t *buf) { size_t size = 0; - if(mac->mlme.pending_mlme_opts & GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ) { + if (mac->mlme.pending_mlme_opts & GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ) { size += _fopts_mlme_link_check_req(buf); } diff --git a/sys/net/gnrc/link_layer/lorawan/include/gnrc_lorawan_internal.h b/sys/net/gnrc/link_layer/lorawan/include/gnrc_lorawan_internal.h index 167aea346a..663a2a0751 100644 --- a/sys/net/gnrc/link_layer/lorawan/include/gnrc_lorawan_internal.h +++ b/sys/net/gnrc/link_layer/lorawan/include/gnrc_lorawan_internal.h @@ -150,27 +150,27 @@ typedef struct { * @brief MCPS service access point descriptor */ typedef struct { - uint32_t fcnt; /**< uplink framecounter */ - uint32_t fcnt_down; /**< downlink frame counter */ - iolist_t *msdu; /**< current MSDU */ - int nb_trials; /**< holds the remaining number of retransmissions */ - int ack_requested; /**< whether the network server requested an ACK */ - int waiting_for_ack; /**< true if the MAC layer is waiting for an ACK */ - char mhdr_mic[MHDR_MIC_BUF_SIZE]; /**< internal retransmissions buffer */ + uint32_t fcnt; /**< uplink framecounter */ + uint32_t fcnt_down; /**< downlink frame counter */ + iolist_t *msdu; /**< current MSDU */ + int nb_trials; /**< holds the remaining number of retransmissions */ + int ack_requested; /**< whether the network server requested an ACK */ + int waiting_for_ack; /**< true if the MAC layer is waiting for an ACK */ + char mhdr_mic[MHDR_MIC_BUF_SIZE]; /**< internal retransmissions buffer */ } gnrc_lorawan_mcps_t; /** * @brief MLME service access point descriptor */ typedef struct { - xtimer_t backoff_timer; /**< timer used for backoff expiration */ - msg_t backoff_msg; /**< msg for backoff expiration */ - uint8_t activation; /**< Activation mechanism of the MAC layer */ + xtimer_t backoff_timer; /**< timer used for backoff expiration */ + msg_t backoff_msg; /**< msg for backoff expiration */ + uint8_t activation; /**< Activation mechanism of the MAC layer */ int pending_mlme_opts; /**< holds pending mlme opts */ - uint32_t nid; /**< current Network ID */ - int32_t backoff_budget; /**< remaining Time On Air budget */ - uint8_t dev_nonce[2]; /**< Device Nonce */ - uint8_t backoff_state; /**< state in the backoff state machine */ + uint32_t nid; /**< current Network ID */ + int32_t backoff_budget; /**< remaining Time On Air budget */ + uint8_t dev_nonce[2]; /**< Device Nonce */ + uint8_t backoff_state; /**< state in the backoff state machine */ } gnrc_lorawan_mlme_t; /** @@ -207,7 +207,9 @@ typedef struct { * @param[in] dir direction of the packet (0 if uplink, 1 if downlink) * @param[in] appskey pointer to the Application Session Key */ -void gnrc_lorawan_encrypt_payload(iolist_t *iolist, const le_uint32_t *dev_addr, uint32_t fcnt, uint8_t dir, const uint8_t *appskey); +void gnrc_lorawan_encrypt_payload(iolist_t *iolist, const le_uint32_t *dev_addr, + uint32_t fcnt, uint8_t dir, + const uint8_t *appskey); /** * @brief Decrypts join accept message @@ -217,7 +219,8 @@ void gnrc_lorawan_encrypt_payload(iolist_t *iolist, const le_uint32_t *dev_addr, * @param[in] has_clist true if the Join Accept frame has CFList * @param[out] out buffer where the decryption is stored */ -void gnrc_lorawan_decrypt_join_accept(const uint8_t *key, uint8_t *pkt, int has_clist, uint8_t *out); +void gnrc_lorawan_decrypt_join_accept(const uint8_t *key, uint8_t *pkt, + int has_clist, uint8_t *out); /** * @brief Generate LoRaWAN session keys @@ -231,7 +234,10 @@ void gnrc_lorawan_decrypt_join_accept(const uint8_t *key, uint8_t *pkt, int has_ * @param[out] nwkskey pointer to the NwkSKey * @param[out] appskey pointer to the AppSKey */ -void gnrc_lorawan_generate_session_keys(const uint8_t *app_nonce, const uint8_t *dev_nonce, const uint8_t *appkey, uint8_t *nwkskey, uint8_t *appskey); +void gnrc_lorawan_generate_session_keys(const uint8_t *app_nonce, + const uint8_t *dev_nonce, + const uint8_t *appkey, uint8_t *nwkskey, + uint8_t *appskey); /** * @brief Set datarate for the next transmission @@ -255,7 +261,8 @@ int gnrc_lorawan_set_dr(gnrc_lorawan_t *mac, uint8_t datarate); * @return full LoRaWAN frame including payload * @return NULL if packet buffer is full. `payload` is released */ -size_t gnrc_lorawan_build_uplink(gnrc_lorawan_t *mac, iolist_t *payload, int confirmed_data, uint8_t port); +size_t gnrc_lorawan_build_uplink(gnrc_lorawan_t *mac, iolist_t *payload, + int confirmed_data, uint8_t port); /** * @brief pick a random available LoRaWAN channel @@ -284,7 +291,8 @@ uint8_t gnrc_lorawan_build_options(gnrc_lorawan_t *mac, lorawan_buffer_t *buf); * @param[in] fopts pointer to fopts frame * @param[in] size size of fopts frame */ -void gnrc_lorawan_process_fopts(gnrc_lorawan_t *mac, uint8_t *fopts, size_t size); +void gnrc_lorawan_process_fopts(gnrc_lorawan_t *mac, uint8_t *fopts, + size_t size); /** * @brief calculate join Message Integrity Code @@ -294,7 +302,8 @@ void gnrc_lorawan_process_fopts(gnrc_lorawan_t *mac, uint8_t *fopts, size_t size * @param[in] key key used to calculate the MIC * @param[out] out calculated MIC */ -void gnrc_lorawan_calculate_join_mic(const uint8_t *buf, size_t len, const uint8_t *key, le_uint32_t *out); +void gnrc_lorawan_calculate_join_mic(const uint8_t *buf, size_t len, + const uint8_t *key, le_uint32_t *out); /** * @brief Calculate Message Integrity Code for a MCPS message @@ -307,7 +316,8 @@ void gnrc_lorawan_calculate_join_mic(const uint8_t *buf, size_t len, const uint8 * @param[out] out calculated MIC */ void gnrc_lorawan_calculate_mic(const le_uint32_t *dev_addr, uint32_t fcnt, - uint8_t dir, iolist_t *frame, const uint8_t *nwkskey, le_uint32_t *out); + uint8_t dir, iolist_t *frame, + const uint8_t *nwkskey, le_uint32_t *out); /** * @brief Build a MCPS LoRaWAN header * @@ -320,7 +330,9 @@ void gnrc_lorawan_calculate_mic(const le_uint32_t *dev_addr, uint32_t fcnt, * * @return the size of the header */ -size_t gnrc_lorawan_build_hdr(uint8_t mtype, le_uint32_t *dev_addr, uint32_t fcnt, uint8_t ack, uint8_t fopts_length, lorawan_buffer_t *buf); +size_t gnrc_lorawan_build_hdr(uint8_t mtype, le_uint32_t *dev_addr, + uint32_t fcnt, uint8_t ack, uint8_t fopts_length, + lorawan_buffer_t *buf); /** * @brief Process an MCPS downlink message (confirmable or non comfirmable) @@ -329,7 +341,8 @@ size_t gnrc_lorawan_build_hdr(uint8_t mtype, le_uint32_t *dev_addr, uint32_t fcn * @param[in] psdu pointer to the downlink PSDU * @param[in] size size of the PSDU */ -void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, uint8_t *psdu, size_t size); +void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, uint8_t *psdu, + size_t size); /** * @brief Init regional channel settings. @@ -365,7 +378,8 @@ void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, iolist_t *psdu, uint8_t dr); * @param[in] data the Join Accept packet * @param[in] size size of the Join Accept packet */ -void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, uint8_t *data, size_t size); +void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, uint8_t *data, + size_t size); /** * @brief Inform the MAC layer that no packet was received during reception. diff --git a/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c b/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c index 7f89896dcd..a6715523af 100644 --- a/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c +++ b/sys/net/gnrc/netif/lorawan/gnrc_netif_lorawan.c @@ -51,7 +51,9 @@ static const gnrc_netif_ops_t lorawan_ops = { 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); + 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"); @@ -84,18 +86,21 @@ static inline void _set_be_addr(gnrc_lorawan_t *mac, uint8_t *be_addr) void gnrc_lorawan_mcps_indication(gnrc_lorawan_t *mac, mcps_indication_t *ind) { - (void) mac; - gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, ind->data.pkt->iol_base, ind->data.pkt->iol_len, GNRC_NETTYPE_LORAWAN); + (void)mac; + gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, ind->data.pkt->iol_base, + ind->data.pkt->iol_len, + GNRC_NETTYPE_LORAWAN); + if (!gnrc_netapi_dispatch_receive(GNRC_NETTYPE_LORAWAN, ind->data.port, - pkt)) { + pkt)) { gnrc_pktbuf_release(pkt); } } void gnrc_lorawan_mlme_indication(gnrc_lorawan_t *mac, mlme_indication_t *ind) { - (void) mac; - (void) ind; + (void)mac; + (void)ind; } void gnrc_lorawan_mcps_confirm(gnrc_lorawan_t *mac, mcps_confirm_t *confirm) @@ -114,7 +119,9 @@ static void _rx_done(gnrc_lorawan_t *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); + gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, bytes_expected, + GNRC_NETTYPE_UNDEF); + if (pkt == NULL) { DEBUG("_recv_lorawan: cannot allocate pktsnip.\n"); /* Discard packet on netdev device */ @@ -167,7 +174,8 @@ static void _driver_cb(netdev_t *dev, netdev_event_t event) static void _reset(gnrc_netif_t *netif) { - netif->lorawan.otaa = LORAMAC_DEFAULT_JOIN_PROCEDURE == LORAMAC_JOIN_OTAA ? NETOPT_ENABLE : NETOPT_DISABLE; + netif->lorawan.otaa = LORAMAC_DEFAULT_JOIN_PROCEDURE == + LORAMAC_JOIN_OTAA ? NETOPT_ENABLE : NETOPT_DISABLE; netif->lorawan.datarate = LORAMAC_DEFAULT_DR; netif->lorawan.demod_margin = 0; netif->lorawan.num_gateways = 0; @@ -178,14 +186,15 @@ static void _reset(gnrc_netif_t *netif) static void _memcpy_reversed(uint8_t *dst, uint8_t *src, size_t size) { - for(size_t i=0;idev; } @@ -203,7 +212,8 @@ static void _init(gnrc_netif_t *netif) _memcpy_reversed(netif->lorawan.appeui, _appeui, sizeof(_appeui)); _set_be_addr(&netif->lorawan.mac, _devaddr); - gnrc_lorawan_init(&netif->lorawan.mac, netif->lorawan.nwkskey, netif->lorawan.appskey); + gnrc_lorawan_init(&netif->lorawan.mac, netif->lorawan.nwkskey, + netif->lorawan.appskey); } int gnrc_netif_lorawan_create(gnrc_netif_t *netif, char *stack, int stacksize, @@ -215,7 +225,7 @@ int gnrc_netif_lorawan_create(gnrc_netif_t *netif, char *stack, int stacksize, static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) { - (void) netif; + (void)netif; /* Unused */ return 0; } @@ -227,12 +237,16 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *payload) if (netif->lorawan.flags & GNRC_NETIF_LORAWAN_FLAGS_LINK_CHECK) { mlme_request.type = MLME_LINK_CHECK; - gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, &mlme_confirm); + gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, + &mlme_confirm); } - mcps_request_t req = { .type = netif->lorawan.ack_req ? MCPS_CONFIRMED : MCPS_UNCONFIRMED, - .data = { .pkt = (iolist_t*) payload, .port = netif->lorawan.port, - .dr = netif->lorawan.datarate } }; + mcps_request_t req = + { .type = netif->lorawan.ack_req ? MCPS_CONFIRMED : MCPS_UNCONFIRMED, + .data = + { .pkt = (iolist_t *)payload, .port = netif->lorawan.port, + .dr = netif->lorawan.datarate } }; mcps_confirm_t conf; + gnrc_lorawan_mcps_request(&netif->lorawan.mac, &req, &conf); if (conf.status < 0) { gnrc_pktbuf_release_error(payload, conf.status); @@ -242,8 +256,8 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *payload) static void _msg_handler(gnrc_netif_t *netif, msg_t *msg) { - (void) netif; - (void) msg; + (void)netif; + (void)msg; switch (msg->type) { case MSG_TYPE_TIMEOUT: gnrc_lorawan_open_rx_window(&netif->lorawan.mac); @@ -265,42 +279,48 @@ static int _get(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt) mlme_confirm_t mlme_confirm; mlme_request_t mlme_request; + switch (opt->opt) { case NETOPT_OTAA: assert(opt->data_len >= sizeof(netopt_enable_t)); - *((netopt_enable_t *) opt->data) = netif->lorawan.otaa; + *((netopt_enable_t *)opt->data) = netif->lorawan.otaa; break; case NETOPT_LINK: mlme_request.type = MLME_GET; mlme_request.mib.type = MIB_ACTIVATION_METHOD; - gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, &mlme_confirm); - *((netopt_enable_t *) opt->data) = mlme_confirm.mib.activation != MLME_ACTIVATION_NONE; + gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, + &mlme_confirm); + *((netopt_enable_t *)opt->data) = mlme_confirm.mib.activation != + MLME_ACTIVATION_NONE; break; case NETOPT_LINK_CHECK: assert(opt->data_len == sizeof(netopt_enable_t)); - *((netopt_enable_t *) opt->data) = (netif->lorawan.flags & GNRC_NETIF_LORAWAN_FLAGS_LINK_CHECK) ? - NETOPT_ENABLE : NETOPT_DISABLE; + *((netopt_enable_t *)opt->data) = + (netif->lorawan.flags & GNRC_NETIF_LORAWAN_FLAGS_LINK_CHECK) ? + NETOPT_ENABLE : NETOPT_DISABLE; break; case NETOPT_NUM_GATEWAYS: assert(opt->data_len == sizeof(uint8_t)); - *((uint8_t *) opt->data) = netif->lorawan.num_gateways; + *((uint8_t *)opt->data) = netif->lorawan.num_gateways; break; case NETOPT_DEMOD_MARGIN: assert(opt->data_len == sizeof(uint8_t)); - *((uint8_t *) opt->data) = netif->lorawan.demod_margin; + *((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); + 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->dev->driver->get(netif->dev, opt->opt, opt->data, opt->data_len); + res = netif->dev->driver->get(netif->dev, opt->opt, opt->data, + opt->data_len); break; } return res; @@ -316,15 +336,15 @@ static int _set(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt) switch (opt->opt) { case NETOPT_LORAWAN_DR: assert(opt->data_len == sizeof(uint8_t)); - netif->lorawan.datarate = *((uint8_t *) opt->data); + netif->lorawan.datarate = *((uint8_t *)opt->data); break; case NETOPT_LORAWAN_TX_PORT: assert(opt->data_len == sizeof(uint8_t)); - netif->lorawan.port = *((uint8_t *) opt->data); + netif->lorawan.port = *((uint8_t *)opt->data); break; case NETOPT_ACK_REQ: assert(opt->data_len == sizeof(netopt_enable_t)); - netif->lorawan.ack_req = *((netopt_enable_t *) opt->data); + netif->lorawan.ack_req = *((netopt_enable_t *)opt->data); break; case NETOPT_LORAWAN_APPKEY: assert(opt->data_len == LORAMAC_APPKEY_LEN); @@ -332,15 +352,17 @@ static int _set(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt) break; case NETOPT_ADDRESS_LONG: assert(opt->data_len == LORAMAC_DEVEUI_LEN); - _memcpy_reversed(netif->lorawan.deveui, opt->data, LORAMAC_DEVEUI_LEN); + _memcpy_reversed(netif->lorawan.deveui, opt->data, + LORAMAC_DEVEUI_LEN); break; case NETOPT_LORAWAN_APPEUI: assert(opt->data_len == LORAMAC_APPEUI_LEN); - _memcpy_reversed(netif->lorawan.appeui, opt->data, LORAMAC_APPEUI_LEN); + _memcpy_reversed(netif->lorawan.appeui, opt->data, + LORAMAC_APPEUI_LEN); break; case NETOPT_OTAA: assert(opt->data_len == sizeof(netopt_enable_t)); - netif->lorawan.otaa = *((netopt_enable_t *) opt->data); + netif->lorawan.otaa = *((netopt_enable_t *)opt->data); break; case NETOPT_LORAWAN_APPSKEY: assert(opt->data_len >= LORAMAC_APPSKEY_LEN); @@ -352,26 +374,29 @@ static int _set(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt) break; case NETOPT_LINK: { - netopt_enable_t en = *((netopt_enable_t *) opt->data); + netopt_enable_t en = *((netopt_enable_t *)opt->data); if (en) { - if(netif->lorawan.otaa) { + if (netif->lorawan.otaa) { mlme_request.type = MLME_JOIN; mlme_request.join.deveui = netif->lorawan.deveui; mlme_request.join.appeui = netif->lorawan.appeui; mlme_request.join.appkey = netif->lorawan.appkey; mlme_request.join.dr = netif->lorawan.datarate; - gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, &mlme_confirm); + gnrc_lorawan_mlme_request(&netif->lorawan.mac, + &mlme_request, &mlme_confirm); } else { mlme_request.type = MLME_SET; mlme_request.mib.type = MIB_ACTIVATION_METHOD; mlme_request.mib.activation = MLME_ACTIVATION_ABP; - gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, &mlme_confirm); + gnrc_lorawan_mlme_request(&netif->lorawan.mac, + &mlme_request, &mlme_confirm); } } else { mlme_request.type = MLME_RESET; - gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, &mlme_confirm); + gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, + &mlme_confirm); res = mlme_confirm.status; if (mlme_confirm.status == 0) { /* reset netif as well */ @@ -391,11 +416,13 @@ static int _set(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt) 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); + mlme_request.mib.rx2_dr = *((uint8_t *)opt->data); + gnrc_lorawan_mlme_request(&netif->lorawan.mac, &mlme_request, + &mlme_confirm); break; default: - res = netif->dev->driver->set(netif->dev, 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);