Skip to content
Snippets Groups Projects
Unverified Commit fd2ffd9e authored by Alexandre Abadie's avatar Alexandre Abadie Committed by GitHub
Browse files

Merge pull request #10903 from aabadie/pr/pkg/semtech-loramac_improve_send

pkg/semtech-loramac: improve TX status management after sending a message
parents cc144bfb bb8bdadd
No related branches found
No related tags found
No related merge requests found
...@@ -67,9 +67,15 @@ static void _prepare_next_alarm(void) ...@@ -67,9 +67,15 @@ static void _prepare_next_alarm(void)
static void _send_message(void) static void _send_message(void)
{ {
printf("Sending: %s\n", message); printf("Sending: %s\n", message);
/* The send call blocks until done */ /* Try to send the message */
semtech_loramac_send(&loramac, (uint8_t *)message, strlen(message)); uint8_t ret = semtech_loramac_send(&loramac,
/* Wait until the send cycle has completed */ (uint8_t *)message, strlen(message));
if (ret != SEMTECH_LORAMAC_TX_OK) {
printf("Cannot send message '%s', ret code: %d\n", message, ret);
return;
}
/* The send was successfully scheduled, now wait until the send cycle has
completed and a reply is received from the MAC */
semtech_loramac_recv(&loramac); semtech_loramac_recv(&loramac);
} }
......
...@@ -239,6 +239,7 @@ static void mcps_indication(McpsIndication_t *indication) ...@@ -239,6 +239,7 @@ static void mcps_indication(McpsIndication_t *indication)
msg.content.ptr = indication; msg.content.ptr = indication;
} }
else { else {
DEBUG("[semtech-loramac] MCPS indication: TX done\n");
msg.type = MSG_TYPE_LORAMAC_TX_STATUS; msg.type = MSG_TYPE_LORAMAC_TX_STATUS;
msg.content.value = SEMTECH_LORAMAC_TX_DONE; msg.content.value = SEMTECH_LORAMAC_TX_DONE;
} }
...@@ -552,18 +553,16 @@ static void _send(semtech_loramac_t *mac, void *arg) ...@@ -552,18 +553,16 @@ static void _send(semtech_loramac_t *mac, void *arg)
{ {
loramac_send_params_t params = *(loramac_send_params_t *)arg; loramac_send_params_t params = *(loramac_send_params_t *)arg;
uint8_t status = _semtech_loramac_send(mac, params.payload, params.len); uint8_t status = _semtech_loramac_send(mac, params.payload, params.len);
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);
}
#ifdef MODULE_PERIPH_EEPROM #ifdef MODULE_PERIPH_EEPROM
else { if (status == SEMTECH_LORAMAC_TX_OK) {
/* save the uplink counter */ /* save the uplink counter */
_save_uplink_counter(mac); _save_uplink_counter(mac);
} }
#endif #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) static void _semtech_loramac_call(semtech_loramac_func_t func, void *arg)
...@@ -708,7 +707,7 @@ void *_semtech_loramac_event_loop(void *arg) ...@@ -708,7 +707,7 @@ void *_semtech_loramac_event_loop(void *arg)
} }
case MSG_TYPE_LORAMAC_TX_STATUS: case MSG_TYPE_LORAMAC_TX_STATUS:
{ {
DEBUG("[semtech-loramac] loramac TX status msg\n"); DEBUG("[semtech-loramac] received TX status\n");
if (msg.content.value == SEMTECH_LORAMAC_TX_SCHEDULE) { if (msg.content.value == SEMTECH_LORAMAC_TX_SCHEDULE) {
DEBUG("[semtech-loramac] schedule immediate TX\n"); DEBUG("[semtech-loramac] schedule immediate TX\n");
uint8_t prev_port = mac->port; uint8_t prev_port = mac->port;
...@@ -717,6 +716,7 @@ void *_semtech_loramac_event_loop(void *arg) ...@@ -717,6 +716,7 @@ void *_semtech_loramac_event_loop(void *arg)
mac->port = prev_port; mac->port = prev_port;
} }
else { else {
DEBUG("[semtech-loramac] forward TX status to caller thread\n");
msg_t msg_ret; msg_t msg_ret;
msg_ret.type = msg.type; msg_ret.type = msg.type;
msg_ret.content.value = msg.content.value; msg_ret.content.value = msg.content.value;
...@@ -828,13 +828,23 @@ uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len) ...@@ -828,13 +828,23 @@ uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len)
return SEMTECH_LORAMAC_NOT_JOINED; return SEMTECH_LORAMAC_NOT_JOINED;
} }
/* Correctly set the caller pid */
mac->caller_pid = thread_getpid();
loramac_send_params_t params; loramac_send_params_t params;
params.payload = data; params.payload = data;
params.len = len; params.len = len;
_semtech_loramac_call(_send, &params); _semtech_loramac_call(_send, &params);
return SEMTECH_LORAMAC_TX_SCHEDULE; /* 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) uint8_t semtech_loramac_recv(semtech_loramac_t *mac)
......
...@@ -149,17 +149,22 @@ uint8_t semtech_loramac_join(semtech_loramac_t *mac, uint8_t type); ...@@ -149,17 +149,22 @@ uint8_t semtech_loramac_join(semtech_loramac_t *mac, uint8_t type);
/** /**
* @brief Sends data to the LoRaWAN network * @brief Sends data to the LoRaWAN network
* *
* This function returns immediately and leave the mac in busy state until a * This function returns after TX status is replied from the MAC. To receive
* message is received from the network (with RX1 and RX2 receive windows). * potential messages sent from the network an explicit call to
* @ref semtech_loramac_recv must be done after this function if it returned
* @ref SEMTECH_LORAMAC_TX_OK and within the RX windows delays.
*
* @see semtech_loramac_recv * @see semtech_loramac_recv
* *
* @param[in] mac Pointer to the mac * @param[in] mac Pointer to the mac
* @param[in] data The TX data * @param[in] data The TX data
* @param[in] len The length of the TX data * @param[in] len The length of the TX data
* *
* @return SEMTECH_LORAMAC_TX_OK when the message can be transmitted
* @return SEMTECH_LORAMAC_NOT_JOINED when the network is not joined * @return SEMTECH_LORAMAC_NOT_JOINED when the network is not joined
* @return SEMTECH_LORAMAC_BUSY when the mac is already active (join or tx in progress) * @return SEMTECH_LORAMAC_BUSY when the mac is already active (join or tx in progress)
* @return SEMTECH_LORAMAC_TX_SCHEDULED when the TX is scheduled in the mac * @return SEMTECH_LORAMAC_DUTYCYCLE_RESTRICTED when the send is rejected because of dutycycle restriction
* @return SEMTECH_LORAMAC_TX_ERROR when an invalid parameter is given
*/ */
uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len); uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len);
...@@ -172,6 +177,9 @@ uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len) ...@@ -172,6 +177,9 @@ uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len)
* class C device, a message can be received at any time. In this case, this * class C device, a message can be received at any time. In this case, this
* function can be used in a dedicated listener thread. * function can be used in a dedicated listener thread.
* *
* Be sure to call this function before the end of the RX windows otherwise it
* may block the calling thread.
*
* @see semtech_loramac_send * @see semtech_loramac_send
* *
* @param[in] mac Pointer to the mac * @param[in] mac Pointer to the mac
......
...@@ -414,15 +414,23 @@ static int _cmd_loramac(int argc, char **argv) ...@@ -414,15 +414,23 @@ static int _cmd_loramac(int argc, char **argv)
switch (semtech_loramac_send(&loramac, switch (semtech_loramac_send(&loramac,
(uint8_t *)argv[2], strlen(argv[2]))) { (uint8_t *)argv[2], strlen(argv[2]))) {
case SEMTECH_LORAMAC_NOT_JOINED: case SEMTECH_LORAMAC_NOT_JOINED:
puts("Failed: not joined"); puts("Cannot send: not joined");
return 1;
case SEMTECH_LORAMAC_DUTYCYCLE_RESTRICTED:
puts("Cannot send: dutycycle restriction");
return 1; return 1;
case SEMTECH_LORAMAC_BUSY: case SEMTECH_LORAMAC_BUSY:
puts("Failed: mac is busy"); puts("Cannot send: MAC is busy");
return 1;
case SEMTECH_LORAMAC_TX_ERROR:
puts("Cannot send: error");
return 1; return 1;
} }
/* clear the rx buffer of the mac */ /* wait for receive windows */
switch (semtech_loramac_recv(&loramac)) { switch (semtech_loramac_recv(&loramac)) {
case SEMTECH_LORAMAC_DATA_RECEIVED: case SEMTECH_LORAMAC_DATA_RECEIVED:
loramac.rx_data.payload[loramac.rx_data.payload_len] = 0; loramac.rx_data.payload[loramac.rx_data.payload_len] = 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment