Making cancel_sending() API robust

If the packet is already handed over to the PHY layer, we shouldn't be
able to cancel that particular transmission. In addition to that if the
backoff timer is either not applied or has been deactivated, should end
up in no-op rather than having normal termination. A new error code has
been introduced to cover no-op cases. This error code replaces the
compliance test related error code which is no longer relevant.
clear_tx_pipe() does nothing if:
	- The stack cannot cancel TX (already handed over to PHY)
        - The backoff timer is not active at all
        - The event is disaptched to schedule

stop_sending() will only post process ongoin TX if the pipe was
definitely cleared.
pull/8299/head
Hasnain Virk 2018-10-02 12:28:48 +03:00
parent 232543ac4b
commit 603ee28098
5 changed files with 25 additions and 14 deletions

View File

@ -493,6 +493,7 @@ public:
* other negative error code if request failed:
* LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(),
* LORAWAN_STATUS_BUSY if the send cannot be canceled
* LORAWAN_STATUS_NO_OP if the operation cannot be completed (nothing to cancel)
*/
virtual lorawan_status_t cancel_sending(void) = 0;
};

View File

@ -272,7 +272,9 @@ lorawan_status_t LoRaWANStack::stop_sending(void)
return LORAWAN_STATUS_NOT_INITIALIZED;
}
if (_loramac.clear_tx_pipe() == LORAWAN_STATUS_OK) {
lorawan_status_t status = _loramac.clear_tx_pipe();
if (status == LORAWAN_STATUS_OK) {
_ctrl_flags &= ~TX_DONE_FLAG;
_ctrl_flags &= ~TX_ONGOING_FLAG;
_loramac.set_tx_ongoing(false);
@ -280,7 +282,7 @@ lorawan_status_t LoRaWANStack::stop_sending(void)
return LORAWAN_STATUS_OK;
}
return LORAWAN_STATUS_BUSY;
return status;
}
int16_t LoRaWANStack::handle_tx(const uint8_t port, const uint8_t *data,
@ -294,11 +296,6 @@ int16_t LoRaWANStack::handle_tx(const uint8_t port, const uint8_t *data,
if (!null_allowed && !data) {
return LORAWAN_STATUS_PARAMETER_INVALID;
}
// add a link check request with normal data, until the application
// explicitly removes it.
if (_link_check_requested) {
_loramac.setup_link_check_request();
}
if (!_lw_session.active) {
return LORAWAN_STATUS_NO_ACTIVE_SESSIONS;
@ -308,6 +305,12 @@ int16_t LoRaWANStack::handle_tx(const uint8_t port, const uint8_t *data,
return LORAWAN_STATUS_WOULD_BLOCK;
}
// add a link check request with normal data, until the application
// explicitly removes it.
if (_link_check_requested) {
_loramac.setup_link_check_request();
}
lorawan_status_t status;
if (_loramac.nwk_joined() == false) {

View File

@ -77,6 +77,7 @@ LoRaMac::LoRaMac()
_mlme_indication(),
_mlme_confirmation(),
_is_nwk_joined(false),
_can_cancel_tx(true),
_continuous_rx2_window_open(false),
_device_class(CLASS_A)
{
@ -1030,11 +1031,16 @@ int LoRaMac::get_backoff_timer_event_id(void)
lorawan_status_t LoRaMac::clear_tx_pipe(void)
{
if (!_can_cancel_tx) {
return LORAWAN_STATUS_BUSY;
}
// check if the event is not already queued
const int id = get_backoff_timer_event_id();
if (id == 0) {
// No queued send request
return LORAWAN_STATUS_OK;
return LORAWAN_STATUS_NO_OP;
}
if (_ev_queue->time_left(id) > 0) {
@ -1092,6 +1098,7 @@ lorawan_status_t LoRaMac::schedule_tx()
case LORAWAN_STATUS_DUTYCYCLE_RESTRICTED:
if (backoff_time != 0) {
tr_debug("DC enforced: Transmitting in %lu ms", backoff_time);
_can_cancel_tx = true;
_lora_time.start(_params.timers.backoff_timer, backoff_time);
}
return LORAWAN_STATUS_OK;
@ -1154,6 +1161,7 @@ lorawan_status_t LoRaMac::schedule_tx()
_params.is_srv_ack_requested = false;
}
_can_cancel_tx = false;
return send_frame_on_channel(_params.channel);
}
@ -1238,6 +1246,7 @@ bool LoRaMac::tx_ongoing()
void LoRaMac::set_tx_ongoing(bool ongoing)
{
_can_cancel_tx = true;
_ongoing_tx_msg.tx_ongoing = ongoing;
}

View File

@ -669,6 +669,8 @@ private:
bool _is_nwk_joined;
bool _can_cancel_tx;
bool _continuous_rx2_window_open;
device_class_t _device_class;

View File

@ -98,13 +98,9 @@ typedef enum lorawan_status {
LORAWAN_STATUS_CRYPTO_FAIL = -1014, /**< Service not started - crypto failure */
LORAWAN_STATUS_PORT_INVALID = -1015, /**< Invalid port */
LORAWAN_STATUS_CONNECT_IN_PROGRESS = -1016, /**< Services started - Connection in progress */
LORAWAN_STATUS_NO_ACTIVE_SESSIONS = -1017, /**< Services not started - No active session */
LORAWAN_STATUS_NO_ACTIVE_SESSIONS = -1017, /**< Services not started - No active session */
LORAWAN_STATUS_IDLE = -1018, /**< Services started - Idle at the moment */
#if defined(LORAWAN_COMPLIANCE_TEST)
//Deprecated - will replace the code -1019 with something
//else in future.
LORAWAN_STATUS_COMPLIANCE_TEST_ON = -1019, /**< Compliance test - is on-going */
#endif
LORAWAN_STATUS_NO_OP = -1019, /**< Cannot perform requested operation */
LORAWAN_STATUS_DUTYCYCLE_RESTRICTED = -1020, /**< Transmission will continue after duty cycle backoff*/
LORAWAN_STATUS_NO_CHANNEL_FOUND = -1021, /**< None of the channels is enabled at the moment*/
LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND = -1022, /**< None of the enabled channels is ready for another TX (duty cycle limited)*/