Skip to content

LoRaWAN: Incorrect Handling of Repeated Calls of 'send' and 'cancel_sending' #8285

@mattbrown015

Description

@mattbrown015

Description

We managed to generate the following assertion from the LoRaWAN stack:

mbed assertation failed: obj.timer_id != 0, file: .\mbed-os\features\lorawan\system\LoRaWANTimer.cpp, line 57þ

We use a sensor to trigger samples and a small problem with a sensor resulted in many events occurring in quick succession. While I appreciate we probably should guard against this in our app I feel the LoRaWAN stack should have handled it better.

We call LoRaWANInterface::send at regular intervals or after an event. Most of the time the interval or events should be easily handled by LoRaWAN and just sent.

We've tried to anticipate what might happen if LoRaWANInterface::send is called while the previous sample is still being sent and we may call LoRaWANInterface::cancel_sending if LoRaWANInterface::send returns LORAWAN_STATUS_WOULD_BLOCK. In other words, attempt to cancel the previous sample so that the latest can be sent.

My feeling is that LoRaWANInterface::send and LoRaWANInterface::cancel_sending is not robust in the face of all possible situations. I think perhaps calling LoRaWANInterface::cancel_sending at just the wrong time allows another TX to be scheduled while waiting for the receive window to expire.

I believe the following debug shows shows something incorrect happening i.e. multiple Opening RX1 Window:

[2018-10-01 09:27:57.718] [INFO][LMAC]: RTS = 10 bytes, PEND = 0, Port: 15
[2018-10-01 09:27:57.718] [DBG ][LMAC]: Frame prepared to send at port 15
[2018-10-01 09:27:57.718] [DBG ][LMAC]: TX: Channel=1, TX DR=5, RX1 DR=5
[2018-10-01 09:27:57.718] [DBG ][asrv]: immediate send
[2018-10-01 09:27:57.718] [WARN][asrv]: LoRaWANInterface::send returned LORAWAN_STATUS_WOULD_BLOCK
[2018-10-01 09:27:57.718] [DBG ][asrv]: try to cancel message
[2018-10-01 09:27:57.718] [INFO][LMAC]: RTS = 10 bytes, PEND = 0, Port: 15
[2018-10-01 09:27:57.718] [DBG ][LMAC]: Frame prepared to send at port 15
[2018-10-01 09:27:57.718] [DBG ][LMAC]: TX: Channel=6, TX DR=5, RX1 DR=5
[2018-10-01 09:27:57.742] [DBG ][asrv]: immediate send
[2018-10-01 09:27:57.742] [WARN][asrv]: LoRaWANInterface::send returned LORAWAN_STATUS_WOULD_BLOCK
[2018-10-01 09:27:57.742] [DBG ][asrv]: try to cancel message
[2018-10-01 09:27:57.742] [INFO][LMAC]: RTS = 10 bytes, PEND = 0, Port: 15
[2018-10-01 09:27:57.742] [DBG ][LMAC]: Frame prepared to send at port 15
[2018-10-01 09:27:57.742] [DBG ][LMAC]: TX: Channel=3, TX DR=5, RX1 DR=5
[2018-10-01 09:27:57.742] [DBG ][asrv]: immediate send
[2018-10-01 09:27:57.742] [WARN][asrv]: LoRaWANInterface::send returned LORAWAN_STATUS_WOULD_BLOCK
[2018-10-01 09:27:57.742] [DBG ][asrv]: try to cancel message
[2018-10-01 09:27:57.742] [INFO][LMAC]: RTS = 10 bytes, PEND = 0, Port: 15
[2018-10-01 09:27:57.742] [DBG ][LMAC]: Frame prepared to send at port 15
[2018-10-01 09:27:57.742] [DBG ][LMAC]: TX: Channel=7, TX DR=5, RX1 DR=5
[2018-10-01 09:27:57.742] [DBG ][asrv]: immediate send
[2018-10-01 09:27:57.742] [WARN][asrv]: LoRaWANInterface::send returned LORAWAN_STATUS_WOULD_BLOCK
[2018-10-01 09:27:57.754] [DBG ][asrv]: try to cancel message
[2018-10-01 09:27:57.754] [INFO][LMAC]: RTS = 10 bytes, PEND = 0, Port: 15
[2018-10-01 09:27:57.754] [DBG ][LMAC]: Frame prepared to send at port 15
[2018-10-01 09:27:57.754] [DBG ][LMAC]: TX: Channel=3, TX DR=5, RX1 DR=5
[2018-10-01 09:27:57.754] [DBG ][asrv]: immediate send
[2018-10-01 09:27:57.754] [DBG ][LSTK]: Transmission completed
[2018-10-01 09:27:57.754] [DBG ][LSTK]: Transmission completed
[2018-10-01 09:27:57.754] [DBG ][LSTK]: Transmission completed
[2018-10-01 09:27:58.636] [DBG ][LMAC]: Opening RX1 Window
[2018-10-01 09:27:58.650] [DBG ][LMAC]: Opening RX1 Window
[2018-10-01 09:27:59.637] [DBG ][LMAC]: Opening RX2 Window, Frequency = 869525000
[2018-10-01 09:27:59.663] [DBG ][LMAC]: Opening RX2 Window, Frequency = 869525000

I think the problem might be in LoRaWANStack::stop_sending and LoRaMac::clear_tx_pipe. LoRaMac::clear_tx_pipe will return LORAWAN_STATUS_OK if there is no message queued but I think it can also return LORAWAN_STATUS_OK if we're waiting for the RX windows to expire.

SHA 37654e5
cc @hasnainvirk

Issue request type

[ ] Question
[ ] Enhancement
[X] Bug

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions