Skip to content

Commit

Permalink
Indicate an errors if payload is too long
Browse files Browse the repository at this point in the history
When the payload supplied by the application does not fit into the
uplink message at the requested data rate, the modem internally performs
a MAC "flush", i.e., it sends an empty uplink to send any pending MAC
commands to the network server. Previous modem versions returned +OK in
this case, incorrectly indicating to the caller that the message was sent.

Since the uplink wasn't really sent, the followup +ACK/+NOACK was not
emitted.

This patch modifies the modem to correctly return +ERR=-12 if the
payload is too big to fit into the uplink message.

Closes #98
  • Loading branch information
janakj committed Aug 25, 2022
1 parent 5e6703d commit c5f0315
Showing 1 changed file with 32 additions and 28 deletions.
60 changes: 32 additions & 28 deletions src/lrw.c
Original file line number Diff line number Diff line change
Expand Up @@ -806,36 +806,40 @@ int lrw_send(uint8_t port, void *buffer, uint8_t length, bool confirmed)
LoRaMacMibGetRequestConfirm(&r);

rc = LoRaMacQueryTxPossible(length, &txi);
if (rc == LORAMAC_STATUS_LENGTH_ERROR) {
log_info("Payload too long. Sending empty frame to flush MAC commands");

// This branch may be triggered when the caller attempts to send a
// packet with the slowest spreading factor and there are some MAC
// commands that need to be transmitted via the FOpts header field.
// Since the minimum payload size with the slowest spreading factor is
// about 11 bytes (without MAC commands), it is easy for the optional
// MAC commands to exhaust most of the available space.
//
// Sertting the port to 0, the payload buffer to NULL, and buffer size
// to 0 will send an uplink message with FOpts but no port or payload.

// Disable retransmissions for the internally generated flush uplink
// message.
r.Type = MIB_CHANNELS_NB_TRANS;
r.Param.ChannelsNbTrans = 1;
rc = LoRaMacMibSetRequestConfirm(&r);
if (rc != LORAMAC_STATUS_OK) {
log_debug("Could not configure retransmissions: %d", rc);
return rc;
if (rc != LORAMAC_STATUS_OK) {
if (rc == LORAMAC_STATUS_LENGTH_ERROR) {
log_info("Payload too long. Sending empty frame to flush MAC commands");

// This branch may be triggered when the caller attempts to send a
// packet with the slowest spreading factor and there are some MAC
// commands that need to be transmitted via the FOpts header field.
// Since the minimum payload size with the slowest spreading factor is
// about 11 bytes (without MAC commands), it is easy for the optional
// MAC commands to exhaust most of the available space.
//
// Sertting the port to 0, the payload buffer to NULL, and buffer size
// to 0 will send an uplink message with FOpts but no port or payload.

// Disable retransmissions for the internally generated flush uplink
// message.
r.Type = MIB_CHANNELS_NB_TRANS;
r.Param.ChannelsNbTrans = 1;
LoRaMacStatus_t rv = LoRaMacMibSetRequestConfirm(&r);
if (rv != LORAMAC_STATUS_OK) {
log_debug("Could not configure retransmissions: %d", rv);
return rv;
}

mr.Type = MCPS_UNCONFIRMED;
mr.Req.Unconfirmed.fPort = 0;
mr.Req.Unconfirmed.fBuffer = NULL;
mr.Req.Unconfirmed.fBufferSize = 0;
mr.Req.Unconfirmed.Datarate = r.Param.ChannelsDatarate;

// Intentionally ignore any errors generated by the flush command
lrw_mcps_request(&mr);
}

mr.Type = MCPS_UNCONFIRMED;
mr.Req.Unconfirmed.fPort = 0;
mr.Req.Unconfirmed.fBuffer = NULL;
mr.Req.Unconfirmed.fBufferSize = 0;
mr.Req.Unconfirmed.Datarate = r.Param.ChannelsDatarate;
lrw_mcps_request(&mr);

// Return the original status to the caller to indicate that we haven't
// sent the requested payload.
return rc;
Expand Down

0 comments on commit c5f0315

Please sign in to comment.