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

pkg/semtech-loramac: refactor send and recv interactions with the MAC

Now TX notification messages are only sent after mcps confirm event. RX message notification message is sent after mcps indication
This commit is contained in:
Alexandre Abadie 2019-05-17 11:32:30 +02:00
parent d1798375e0
commit b7890b3031
No known key found for this signature in database
GPG Key ID: 1C919A403CAE1405
2 changed files with 220 additions and 229 deletions

View File

@ -146,105 +146,19 @@ static uint8_t _semtech_loramac_send(semtech_loramac_t *mac,
static void mcps_confirm(McpsConfirm_t *confirm)
{
DEBUG("[semtech-loramac] MCPS confirm event\n");
if (confirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) {
DEBUG("[semtech-loramac] MCPS confirm event OK\n");
switch (confirm->McpsRequest) {
case MCPS_UNCONFIRMED:
{
/* Check Datarate
Check TxPower */
DEBUG("[semtech-loramac] MCPS confirm event: UNCONFIRMED\n");
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_TX_STATUS;
msg.content.value = SEMTECH_LORAMAC_TX_DONE;
msg_send(&msg, semtech_loramac_pid);
break;
}
case MCPS_CONFIRMED:
/* Check Datarate
Check TxPower
Check AckReceived
Check NbTrials */
DEBUG("[semtech-loramac] MCPS confirm event: CONFIRMED\n");
break;
case MCPS_PROPRIETARY:
DEBUG("[semtech-loramac] MCPS confirm event: PROPRIETARY\n");
break;
default:
DEBUG("[semtech-loramac] MCPS confirm event: UNKNOWN\n");
break;
}
}
else {
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_TX_STATUS;
msg.content.value = SEMTECH_LORAMAC_TX_CNF_FAILED;
msg_send(&msg, semtech_loramac_pid);
}
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_MCPS_CONFIRM;
msg.content.ptr = confirm;
msg_send(&msg, semtech_loramac_pid);
}
/* MCPS-Indication event function */
static void mcps_indication(McpsIndication_t *indication)
{
DEBUG("[semtech-loramac] MCPS indication event\n");
if (indication->Status != LORAMAC_EVENT_INFO_STATUS_OK) {
DEBUG("[semtech-loramac] MCPS indication no OK\n");
return;
}
if (ENABLE_DEBUG) {
switch (indication->McpsIndication) {
case MCPS_UNCONFIRMED:
DEBUG("[semtech-loramac] MCPS indication Unconfirmed\n");
break;
case MCPS_CONFIRMED:
DEBUG("[semtech-loramac] MCPS indication Confirmed\n");
break;
case MCPS_PROPRIETARY:
DEBUG("[semtech-loramac] MCPS indication Proprietary\n");
break;
case MCPS_MULTICAST:
DEBUG("[semtech-loramac] MCPS indication Multicast\n");
break;
default:
break;
}
}
/* Check Multicast
Check Port
Check Datarate
Check FramePending */
if (indication->FramePending == true) {
/* The server signals that it has pending data to be sent.
We schedule an uplink as soon as possible to flush the server. */
DEBUG("[semtech-loramac] MCPS indication: pending data, schedule an "
"uplink\n");
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_TX_STATUS;
msg.content.value = SEMTECH_LORAMAC_TX_SCHEDULE;
msg_send(&msg, semtech_loramac_pid);
}
msg_t msg;
if (indication->RxData) {
DEBUG("[semtech-loramac] MCPS indication: data received\n");
msg.type = MSG_TYPE_LORAMAC_RX;
msg.content.ptr = indication;
}
else {
DEBUG("[semtech-loramac] MCPS indication: TX done\n");
msg.type = MSG_TYPE_LORAMAC_TX_STATUS;
msg.content.value = SEMTECH_LORAMAC_TX_DONE;
}
msg.type = MSG_TYPE_LORAMAC_MCPS_INDICATION;
msg.content.ptr = indication;
msg_send(&msg, semtech_loramac_pid);
}
@ -252,56 +166,20 @@ static void mcps_indication(McpsIndication_t *indication)
static void mlme_confirm(MlmeConfirm_t *confirm)
{
DEBUG("[semtech-loramac] MLME confirm event\n");
switch (confirm->MlmeRequest) {
case MLME_JOIN:
if (confirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) {
/* Status is OK, node has joined the network */
DEBUG("[semtech-loramac] join succeeded\n");
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_JOIN;
msg.content.value = SEMTECH_LORAMAC_JOIN_SUCCEEDED;
msg_send(&msg, semtech_loramac_pid);
}
else {
DEBUG("[semtech-loramac] join not successful\n");
/* Join was not successful. */
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_JOIN;
msg.content.value = SEMTECH_LORAMAC_JOIN_FAILED;
msg_send(&msg, semtech_loramac_pid);
}
break;
case MLME_LINK_CHECK:
if (confirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) {
DEBUG("[semtech-loramac] link check received\n");
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_LINK_CHECK;
msg.content.ptr = confirm;
msg_send(&msg, semtech_loramac_pid);
}
default:
break;
}
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_MLME_CONFIRM;
msg.content.ptr = confirm;
msg_send(&msg, semtech_loramac_pid);
}
/* MLME-Indication event function */
static void mlme_indication(MlmeIndication_t *indication)
{
switch (indication->MlmeIndication) {
case MLME_SCHEDULE_UPLINK:
/* The MAC signals that we shall provide an uplink
as soon as possible */
DEBUG("[semtech-loramac] MLME indication: schedule an uplink\n");
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_TX_STATUS;
msg.content.value = SEMTECH_LORAMAC_TX_SCHEDULE;
msg_send(&msg, semtech_loramac_pid);
break;
default:
break;
}
DEBUG("[semtech-loramac] MLME indication event\n");
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_MLME_INDICATION;
msg.content.ptr = indication;
msg_send(&msg, semtech_loramac_pid);
}
#ifdef MODULE_PERIPH_EEPROM
@ -442,7 +320,6 @@ void _init_loramac(semtech_loramac_t *mac,
semtech_loramac_set_system_max_rx_error(mac,
LORAMAC_DEFAULT_SYSTEM_MAX_RX_ERROR);
semtech_loramac_set_min_rx_symbols(mac, LORAMAC_DEFAULT_MIN_RX_SYMBOLS);
mac->link_chk.available = false;
#ifdef MODULE_PERIPH_EEPROM
_read_loramac_config(mac);
#endif
@ -478,7 +355,7 @@ static void _join_otaa(semtech_loramac_t *mac)
DEBUG("[semtech-loramac] join otaa: duty cycle restricted\n");
/* Cannot join. */
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_JOIN;
msg.type = MSG_TYPE_LORAMAC_JOIN_STATUS;
msg.content.value = SEMTECH_LORAMAC_DUTYCYCLE_RESTRICTED;
msg_send(&msg, semtech_loramac_pid);
return;
@ -488,7 +365,7 @@ static void _join_otaa(semtech_loramac_t *mac)
DEBUG("[semtech-loramac] join otaa: mac is busy\n");
/* Cannot join. */
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_JOIN;
msg.type = MSG_TYPE_LORAMAC_JOIN_STATUS;
msg.content.value = SEMTECH_LORAMAC_BUSY;
msg_send(&msg, semtech_loramac_pid);
return;
@ -498,7 +375,7 @@ static void _join_otaa(semtech_loramac_t *mac)
DEBUG("[semtech-loramac] join otaa: failed with status %d\n", ret);
/* Cannot join. */
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_JOIN;
msg.type = MSG_TYPE_LORAMAC_JOIN_STATUS;
msg.content.value = SEMTECH_LORAMAC_JOIN_FAILED;
msg_send(&msg, semtech_loramac_pid);
return;
@ -558,16 +435,12 @@ static void _send(semtech_loramac_t *mac, void *arg)
{
loramac_send_params_t params = *(loramac_send_params_t *)arg;
uint8_t status = _semtech_loramac_send(mac, params.payload, params.len);
#ifdef MODULE_PERIPH_EEPROM
if (status == SEMTECH_LORAMAC_TX_OK) {
/* save the uplink counter */
_save_uplink_counter(mac);
if (status != SEMTECH_LORAMAC_TX_OK) {
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_TX_STATUS;
msg.content.value = (uint8_t)status;
msg_send(&msg, semtech_loramac_pid);
}
#endif
msg_t msg;
msg.type = MSG_TYPE_LORAMAC_TX_STATUS;
msg.content.value = (uint8_t)status;
msg_send(&msg, semtech_loramac_pid);
}
static void _semtech_loramac_call(semtech_loramac_func_t func, void *arg)
@ -695,63 +568,194 @@ void *_semtech_loramac_event_loop(void *arg)
msg_reply(&msg, &msg_resp);
break;
}
case MSG_TYPE_LORAMAC_JOIN:
case MSG_TYPE_LORAMAC_JOIN_STATUS:
{
DEBUG("[semtech-loramac] loramac join notification msg\n");
DEBUG("[semtech-loramac] join status msg received\n");
msg_t msg_ret;
msg_ret.content.value = msg.content.value;
msg_send(&msg_ret, mac->caller_pid);
break;
}
case MSG_TYPE_LORAMAC_LINK_CHECK:
{
MlmeConfirm_t *confirm = (MlmeConfirm_t *)msg.content.ptr;
mac->link_chk.demod_margin = confirm->DemodMargin;
mac->link_chk.nb_gateways = confirm->NbGateways;
mac->link_chk.available = true;
DEBUG("[semtech-loramac] link check info received:\n"
" - Demodulation marging: %d\n"
" - Number of gateways: %d\n",
mac->link_chk.demod_margin,
mac->link_chk.nb_gateways);
msg_send(&msg_ret, mac->tx_pid);
break;
}
case MSG_TYPE_LORAMAC_TX_STATUS:
{
DEBUG("[semtech-loramac] received TX status\n");
if (msg.content.value == SEMTECH_LORAMAC_TX_SCHEDULE) {
DEBUG("[semtech-loramac] schedule immediate TX\n");
DEBUG("[semtech-loramac] TX status msg received\n");
msg_t msg_ret;
msg_ret.content.value = msg.content.value;
msg_send(&msg_ret, mac->tx_pid);
break;
}
case MSG_TYPE_LORAMAC_MLME_CONFIRM:
{
DEBUG("[semtech-loramac] MLME confirm msg received\n");
MlmeConfirm_t *confirm = (MlmeConfirm_t *)msg.content.ptr;
switch (confirm->MlmeRequest) {
case MLME_JOIN:
{
msg_t msg_ret;
msg_ret.type = MSG_TYPE_LORAMAC_JOIN_STATUS;
if (confirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) {
/* Status is OK, node has joined the network */
DEBUG("[semtech-loramac] join succeeded\n");
msg_ret.content.value = SEMTECH_LORAMAC_JOIN_SUCCEEDED;
}
else {
DEBUG("[semtech-loramac] join not successful\n");
/* Join was not successful. */
msg_ret.content.value = SEMTECH_LORAMAC_JOIN_FAILED;
}
msg_send(&msg_ret, mac->tx_pid);
break;
}
case MLME_LINK_CHECK:
if (confirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) {
mac->link_chk.demod_margin = confirm->DemodMargin;
mac->link_chk.nb_gateways = confirm->NbGateways;
DEBUG("[semtech-loramac] link check info received:\n"
" - Demodulation marging: %d\n"
" - Number of gateways: %d\n",
mac->link_chk.demod_margin,
mac->link_chk.nb_gateways);
msg_t msg_ret;
msg_ret.content.value = SEMTECH_LORAMAC_RX_LINK_CHECK;
msg_send(&msg_ret, mac->rx_pid);
}
default:
break;
}
break;
}
case MSG_TYPE_LORAMAC_MLME_INDICATION:
{
DEBUG("[semtech-loramac] MLME indication msg received\n");
MlmeIndication_t *indication = (MlmeIndication_t *)msg.content.ptr;
if (indication->MlmeIndication == MLME_SCHEDULE_UPLINK) {
DEBUG("[semtech-loramac] MLME indication: schedule an uplink\n");
uint8_t prev_port = mac->port;
mac->port = 0;
_semtech_loramac_send(mac, NULL, 0);
mac->port = prev_port;
}
else {
DEBUG("[semtech-loramac] forward TX status to caller thread\n");
msg_t msg_ret;
msg_ret.type = msg.type;
msg_ret.content.value = msg.content.value;
msg_send(&msg_ret, mac->caller_pid);
}
break;
}
case MSG_TYPE_LORAMAC_RX:
case MSG_TYPE_LORAMAC_MCPS_CONFIRM:
{
DEBUG("[semtech-loramac] MCPS confirm msg received\n");
McpsConfirm_t *confirm = (McpsConfirm_t *)msg.content.ptr;
msg_t msg_ret;
msg_ret.type = MSG_TYPE_LORAMAC_RX;
msg_ret.type = MSG_TYPE_LORAMAC_TX_STATUS;
uint8_t status = SEMTECH_LORAMAC_TX_CNF_FAILED;
if (confirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) {
DEBUG("[semtech-loramac] MCPS confirm event OK\n");
status = SEMTECH_LORAMAC_TX_DONE;
#ifdef MODULE_PERIPH_EEPROM
/* save the uplink counter */
_save_uplink_counter(mac);
#endif
if (ENABLE_DEBUG) {
switch (confirm->McpsRequest) {
case MCPS_UNCONFIRMED:
{
/* Check Datarate
Check TxPower */
DEBUG("[semtech-loramac] MCPS confirm event: UNCONFIRMED\n");
break;
}
case MCPS_CONFIRMED:
/* Check Datarate
Check TxPower
Check AckReceived
Check NbTrials */
DEBUG("[semtech-loramac] MCPS confirm event: CONFIRMED\n");
break;
case MCPS_PROPRIETARY:
DEBUG("[semtech-loramac] MCPS confirm event: PROPRIETARY\n");
break;
default:
DEBUG("[semtech-loramac] MCPS confirm event: UNKNOWN\n");
break;
}
}
}
DEBUG("[semtech-loramac] forward TX status to sender thread\n");
msg_ret.content.value = status;
msg_send(&msg_ret, mac->tx_pid);
break;
}
case MSG_TYPE_LORAMAC_MCPS_INDICATION:
{
DEBUG("[semtech-loramac] MCPS indication msg received\n");
McpsIndication_t *indication = (McpsIndication_t *)msg.content.ptr;
memcpy(mac->rx_data.payload,
indication->Buffer, indication->BufferSize);
mac->rx_data.payload_len = indication->BufferSize;
mac->rx_data.port = indication->Port;
DEBUG("[semtech-loramac] loramac RX data:\n"
" - Payload: %s\n"
" - Size: %d\n"
" - Port: %d\n",
(char *)mac->rx_data.payload,
mac->rx_data.payload_len,
mac->rx_data.port);
msg_send(&msg_ret, mac->caller_pid);
if (indication->Status != LORAMAC_EVENT_INFO_STATUS_OK) {
DEBUG("[semtech-loramac] MCPS indication no OK\n");
break;
}
if (ENABLE_DEBUG) {
switch (indication->McpsIndication) {
case MCPS_UNCONFIRMED:
DEBUG("[semtech-loramac] MCPS indication Unconfirmed\n");
break;
case MCPS_CONFIRMED:
DEBUG("[semtech-loramac] MCPS indication Confirmed\n");
break;
case MCPS_PROPRIETARY:
DEBUG("[semtech-loramac] MCPS indication Proprietary\n");
break;
case MCPS_MULTICAST:
DEBUG("[semtech-loramac] MCPS indication Multicast\n");
break;
default:
break;
}
}
/* Check Multicast
Check Port
Check Datarate
Check FramePending */
if (indication->FramePending) {
/* The server signals that it has pending data to be sent.
We schedule an uplink as soon as possible to flush the server. */
DEBUG("[semtech-loramac] MCPS indication: pending data, schedule an "
"uplink\n");
uint8_t prev_port = mac->port;
mac->port = 0;
_semtech_loramac_send(mac, NULL, 0);
mac->port = prev_port;
}
if (indication->RxData) {
DEBUG("[semtech-loramac] MCPS indication: data received\n");
memcpy(mac->rx_data.payload,
indication->Buffer, indication->BufferSize);
mac->rx_data.payload_len = indication->BufferSize;
mac->rx_data.port = indication->Port;
DEBUG("[semtech-loramac] loramac RX data:\n"
" - Payload: %s\n"
" - Size: %d\n"
" - Port: %d\n",
(char *)mac->rx_data.payload,
mac->rx_data.payload_len,
mac->rx_data.port);
msg_t msg_ret;
msg_ret.content.value = SEMTECH_LORAMAC_RX_DATA;
msg_send(&msg_ret, mac->rx_pid);
}
if (indication->AckReceived) {
DEBUG("[semtech-loramac] MCPS indication: ACK received\n");
msg_t msg_ret;
msg_ret.content.value = SEMTECH_LORAMAC_RX_CONFIRMED;
msg_send(&msg_ret, mac->rx_pid);
}
break;
}
default:
@ -806,7 +810,7 @@ uint8_t semtech_loramac_join(semtech_loramac_t *mac, uint8_t type)
return SEMTECH_LORAMAC_ALREADY_JOINED;
}
mac->caller_pid = thread_getpid();
mac->tx_pid = thread_getpid();
_semtech_loramac_call(_join, &type);
@ -824,7 +828,6 @@ uint8_t semtech_loramac_join(semtech_loramac_t *mac, uint8_t type)
void semtech_loramac_request_link_check(semtech_loramac_t *mac)
{
mutex_lock(&mac->lock);
mac->link_chk.available = false;
MlmeReq_t mlmeReq;
mlmeReq.Type = MLME_LINK_CHECK;
LoRaMacMlmeRequest(&mlmeReq);
@ -833,14 +836,13 @@ void semtech_loramac_request_link_check(semtech_loramac_t *mac)
uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len)
{
mac->link_chk.available = false;
if (!_is_mac_joined(mac)) {
DEBUG("[semtech-loramac] network is not joined\n");
return SEMTECH_LORAMAC_NOT_JOINED;
}
/* Correctly set the caller pid */
mac->caller_pid = thread_getpid();
/* Correctly set the sender thread pid */
mac->tx_pid = thread_getpid();
loramac_send_params_t params;
params.payload = data;
@ -851,34 +853,18 @@ uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len)
/* Wait for TX status information from the MAC */
msg_t msg;
msg_receive(&msg);
if (msg.type != MSG_TYPE_LORAMAC_TX_STATUS) {
return SEMTECH_LORAMAC_TX_ERROR;
}
return (uint8_t)msg.content.value;
}
uint8_t semtech_loramac_recv(semtech_loramac_t *mac)
{
mac->caller_pid = thread_getpid();
/* Correctly set the receiver thread pid */
mac->rx_pid = thread_getpid();
/* Wait until the mac receive some information */
msg_t msg;
msg_receive(&msg);
uint8_t ret;
switch (msg.type) {
case MSG_TYPE_LORAMAC_RX:
ret = SEMTECH_LORAMAC_DATA_RECEIVED;
break;
case MSG_TYPE_LORAMAC_TX_STATUS:
ret = (uint8_t)msg.content.value;
break;
default:
ret = SEMTECH_LORAMAC_TX_ERROR;
break;
}
DEBUG("[semtech-loramac] received something\n");
DEBUG("[semtech-loramac] MAC reply received: %d\n", ret);
return ret;
return (uint8_t)msg.content.value;
}

View File

@ -36,15 +36,17 @@ extern "C" {
* @name Definitions for messages exchanged between the MAC and call threads
* @{
*/
#define MSG_TYPE_ISR (0x3456) /**< radio device ISR */
#define MSG_TYPE_RX_TIMEOUT (0x3457) /**< radio driver RX timeout */
#define MSG_TYPE_TX_TIMEOUT (0x3458) /**< radio driver TX timeout */
#define MSG_TYPE_MAC_TIMEOUT (0x3459) /**< MAC timers timeout */
#define MSG_TYPE_LORAMAC_CMD (0x3460) /**< Command sent to the MAC */
#define MSG_TYPE_LORAMAC_JOIN (0x3461) /**< MAC join event */
#define MSG_TYPE_LORAMAC_TX_STATUS (0x3462) /**< MAC TX status */
#define MSG_TYPE_LORAMAC_RX (0x3463) /**< Some data received */
#define MSG_TYPE_LORAMAC_LINK_CHECK (0x3464) /**< Link check info received */
#define MSG_TYPE_ISR (0x3456) /**< radio device ISR */
#define MSG_TYPE_RX_TIMEOUT (0x3457) /**< radio driver RX timeout */
#define MSG_TYPE_TX_TIMEOUT (0x3458) /**< radio driver TX timeout */
#define MSG_TYPE_MAC_TIMEOUT (0x3459) /**< MAC timers timeout */
#define MSG_TYPE_LORAMAC_CMD (0x3460) /**< Command sent to the MAC */
#define MSG_TYPE_LORAMAC_JOIN_STATUS (0x3461) /**< Join status */
#define MSG_TYPE_LORAMAC_TX_STATUS (0x3462) /**< Uplink status */
#define MSG_TYPE_LORAMAC_MLME_CONFIRM (0x3463) /**< MAC MLME confirm event */
#define MSG_TYPE_LORAMAC_MLME_INDICATION (0x3464) /**< MAC MLME indication event */
#define MSG_TYPE_LORAMAC_MCPS_CONFIRM (0x3465) /**< MAC MCPS confirm event */
#define MSG_TYPE_LORAMAC_MCPS_INDICATION (0x3466) /**< MAC MCPS indication event */
/** @} */
/**
@ -65,7 +67,9 @@ enum {
SEMTECH_LORAMAC_TX_DONE, /**< Transmission completed */
SEMTECH_LORAMAC_TX_CNF_FAILED, /**< Confirmable transmission failed */
SEMTECH_LORAMAC_TX_ERROR, /**< Error in TX (invalid param, unknown service) */
SEMTECH_LORAMAC_DATA_RECEIVED, /**< Data received */
SEMTECH_LORAMAC_RX_DATA, /**< Data received */
SEMTECH_LORAMAC_RX_LINK_CHECK, /**< Link check info received */
SEMTECH_LORAMAC_RX_CONFIRMED, /**< Confirmed ACK received */
SEMTECH_LORAMAC_BUSY, /**< Internal MAC is busy */
SEMTECH_LORAMAC_DUTYCYCLE_RESTRICTED /**< Restricted access to channels */
};
@ -101,7 +105,6 @@ typedef struct {
typedef struct {
uint8_t demod_margin; /**< Demodulation margin */
uint8_t nb_gateways; /**< number of LoRa gateways found */
bool available; /**< new link check information avalable */
} semtech_loramac_link_check_info_t;
/**
@ -109,7 +112,8 @@ typedef struct {
*/
typedef struct {
mutex_t lock; /**< loramac access lock */
uint8_t caller_pid; /**< pid of caller thread */
uint8_t tx_pid; /**< pid of sender thread */
uint8_t rx_pid; /**< pid of receiver thread */
uint8_t port; /**< application TX port */
uint8_t cnf; /**< enable/disable confirmable messages */
uint8_t deveui[LORAMAC_DEVEUI_LEN]; /**< device EUI */
@ -184,8 +188,9 @@ uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len)
*
* @param[in] mac Pointer to the mac
*
* @return SEMTECH_LORAMAC_TX_DONE when TX has completed, no data received
* @return SEMTECH_LORAMAC_DATA_RECEIVED when TX has completed and data is received
* @return SEMTECH_LORAMAC_RX_DATA when data is received
* @return SEMTECH_LORAMAC_RX_LINK_CHECK when link check information is received
* @return SEMTECH_LORAMAC_RX_CONFIRMED when an ACK is received from the network
*/
uint8_t semtech_loramac_recv(semtech_loramac_t *mac);