diff --git a/pkg/semtech-loramac/contrib/semtech_loramac.c b/pkg/semtech-loramac/contrib/semtech_loramac.c index 51af9addde..722e09be90 100644 --- a/pkg/semtech-loramac/contrib/semtech_loramac.c +++ b/pkg/semtech-loramac/contrib/semtech_loramac.c @@ -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; } diff --git a/pkg/semtech-loramac/include/semtech_loramac.h b/pkg/semtech-loramac/include/semtech_loramac.h index 69c7ad398d..479b9c7e03 100644 --- a/pkg/semtech-loramac/include/semtech_loramac.h +++ b/pkg/semtech-loramac/include/semtech_loramac.h @@ -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);