mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #8393 from cmonr/unittest-fix
Revert "Merge pull request #8183 from hasnainvirk/QOS_impl"pull/8301/merge
commit
5e4b8723a6
|
@ -40,7 +40,7 @@ SPDX-License-Identifier: BSD-3-Clause
|
||||||
* Control flags for transient states
|
* Control flags for transient states
|
||||||
*/
|
*/
|
||||||
#define IDLE_FLAG 0x00000000
|
#define IDLE_FLAG 0x00000000
|
||||||
#define RETRY_EXHAUSTED_FLAG 0x00000001
|
#define TX_ONGOING_FLAG 0x00000001
|
||||||
#define MSG_RECVD_FLAG 0x00000002
|
#define MSG_RECVD_FLAG 0x00000002
|
||||||
#define CONNECTED_FLAG 0x00000004
|
#define CONNECTED_FLAG 0x00000004
|
||||||
#define USING_OTAA_FLAG 0x00000008
|
#define USING_OTAA_FLAG 0x00000008
|
||||||
|
@ -68,7 +68,6 @@ LoRaWANStack::LoRaWANStack()
|
||||||
_tx_metadata(),
|
_tx_metadata(),
|
||||||
_rx_metadata(),
|
_rx_metadata(),
|
||||||
_num_retry(1),
|
_num_retry(1),
|
||||||
_qos_cnt(1),
|
|
||||||
_ctrl_flags(IDLE_FLAG),
|
_ctrl_flags(IDLE_FLAG),
|
||||||
_app_port(INVALID_PORT),
|
_app_port(INVALID_PORT),
|
||||||
_link_check_requested(false),
|
_link_check_requested(false),
|
||||||
|
@ -275,6 +274,7 @@ lorawan_status_t LoRaWANStack::stop_sending(void)
|
||||||
|
|
||||||
if (_loramac.clear_tx_pipe() == LORAWAN_STATUS_OK) {
|
if (_loramac.clear_tx_pipe() == LORAWAN_STATUS_OK) {
|
||||||
_ctrl_flags &= ~TX_DONE_FLAG;
|
_ctrl_flags &= ~TX_DONE_FLAG;
|
||||||
|
_ctrl_flags &= ~TX_ONGOING_FLAG;
|
||||||
_loramac.set_tx_ongoing(false);
|
_loramac.set_tx_ongoing(false);
|
||||||
_device_current_state = DEVICE_STATE_IDLE;
|
_device_current_state = DEVICE_STATE_IDLE;
|
||||||
return LORAWAN_STATUS_OK;
|
return LORAWAN_STATUS_OK;
|
||||||
|
@ -449,8 +449,7 @@ lorawan_status_t LoRaWANStack::set_device_class(const device_class_t &device_cla
|
||||||
if (device_class == CLASS_B) {
|
if (device_class == CLASS_B) {
|
||||||
return LORAWAN_STATUS_UNSUPPORTED;
|
return LORAWAN_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
_loramac.set_device_class(device_class,
|
_loramac.set_device_class(device_class, mbed::callback(this, &LoRaWANStack::handle_ack_expiry_for_class_c));
|
||||||
mbed::callback(this, &LoRaWANStack::post_process_tx_no_reception));
|
|
||||||
return LORAWAN_STATUS_OK;
|
return LORAWAN_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,6 +559,7 @@ void LoRaWANStack::process_transmission_timeout()
|
||||||
// this is a fatal error and should not happen
|
// this is a fatal error and should not happen
|
||||||
tr_debug("TX Timeout");
|
tr_debug("TX Timeout");
|
||||||
_loramac.on_radio_tx_timeout();
|
_loramac.on_radio_tx_timeout();
|
||||||
|
_ctrl_flags &= ~TX_ONGOING_FLAG;
|
||||||
_ctrl_flags &= ~TX_DONE_FLAG;
|
_ctrl_flags &= ~TX_DONE_FLAG;
|
||||||
if (_device_current_state == DEVICE_STATE_JOINING) {
|
if (_device_current_state == DEVICE_STATE_JOINING) {
|
||||||
mlme_confirm_handler();
|
mlme_confirm_handler();
|
||||||
|
@ -573,6 +573,9 @@ void LoRaWANStack::process_transmission_timeout()
|
||||||
void LoRaWANStack::process_transmission(void)
|
void LoRaWANStack::process_transmission(void)
|
||||||
{
|
{
|
||||||
tr_debug("Transmission completed");
|
tr_debug("Transmission completed");
|
||||||
|
_loramac.on_radio_tx_done(_tx_timestamp);
|
||||||
|
|
||||||
|
make_tx_metadata_available();
|
||||||
|
|
||||||
if (_device_current_state == DEVICE_STATE_JOINING) {
|
if (_device_current_state == DEVICE_STATE_JOINING) {
|
||||||
_device_current_state = DEVICE_STATE_AWAITING_JOIN_ACCEPT;
|
_device_current_state = DEVICE_STATE_AWAITING_JOIN_ACCEPT;
|
||||||
|
@ -580,103 +583,31 @@ void LoRaWANStack::process_transmission(void)
|
||||||
|
|
||||||
if (_device_current_state == DEVICE_STATE_SENDING) {
|
if (_device_current_state == DEVICE_STATE_SENDING) {
|
||||||
if (_loramac.get_mcps_confirmation()->req_type == MCPS_CONFIRMED) {
|
if (_loramac.get_mcps_confirmation()->req_type == MCPS_CONFIRMED) {
|
||||||
|
_ctrl_flags |= TX_ONGOING_FLAG;
|
||||||
|
_ctrl_flags &= ~TX_DONE_FLAG;
|
||||||
tr_debug("Awaiting ACK");
|
tr_debug("Awaiting ACK");
|
||||||
_device_current_state = DEVICE_STATE_AWAITING_ACK;
|
_device_current_state = DEVICE_STATE_AWAITING_ACK;
|
||||||
}
|
} else if (_loramac.get_device_class() == CLASS_A) {
|
||||||
}
|
// Class A unconfirmed message sent, TX_DONE event will be sent to
|
||||||
|
// application when RX2 windows is elapsed, i.e., in process_reception_timeout()
|
||||||
_loramac.on_radio_tx_done(_tx_timestamp);
|
_ctrl_flags &= ~TX_ONGOING_FLAG;
|
||||||
}
|
|
||||||
|
|
||||||
void LoRaWANStack::post_process_tx_with_reception()
|
|
||||||
{
|
|
||||||
if (_loramac.get_mcps_confirmation()->req_type == MCPS_CONFIRMED) {
|
|
||||||
// if ack was not received, we will try retransmission after
|
|
||||||
// ACK_TIMEOUT. handle_data_frame() already disables ACK_TIMEOUT timer
|
|
||||||
// if ack was received. Otherwise, following method will be called in
|
|
||||||
// LoRaMac.cpp, on_ack_timeout_timer_event().
|
|
||||||
if (_loramac.get_mcps_indication()->is_ack_recvd) {
|
|
||||||
_ctrl_flags |= TX_DONE_FLAG;
|
_ctrl_flags |= TX_DONE_FLAG;
|
||||||
_ctrl_flags &= ~RETRY_EXHAUSTED_FLAG;
|
} else if (_loramac.get_device_class() == CLASS_C) {
|
||||||
tr_debug("Ack=OK, NbTrials=%d",
|
// In Class C, reception timeout never happens, so we handle the state
|
||||||
_loramac.get_mcps_confirmation()->nb_retries);
|
// progression for TX_DONE in UNCONFIRMED case here
|
||||||
_loramac.post_process_mcps_req();
|
_loramac.post_process_mcps_req();
|
||||||
make_tx_metadata_available();
|
|
||||||
state_controller(DEVICE_STATE_STATUS_CHECK);
|
|
||||||
} else {
|
|
||||||
if (!_loramac.continue_sending_process()
|
|
||||||
&& _loramac.get_current_slot() != RX_SLOT_WIN_1) {
|
|
||||||
tr_error("Retries exhausted for Class %s device",
|
|
||||||
_loramac.get_device_class() == CLASS_A ? "A" : "C");
|
|
||||||
_ctrl_flags &= ~TX_DONE_FLAG;
|
|
||||||
_ctrl_flags |= RETRY_EXHAUSTED_FLAG;
|
|
||||||
state_controller(DEVICE_STATE_STATUS_CHECK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// handle UNCONFIRMED case here, RX slots were turned off due to
|
|
||||||
// valid packet reception.
|
|
||||||
uint8_t prev_QOS_level = _loramac.get_prev_QOS_level();
|
|
||||||
uint8_t QOS_level = _loramac.get_QOS_level();
|
|
||||||
|
|
||||||
// We will not apply QOS on the post-processing of the previous
|
|
||||||
// outgoing message as we would have received QOS instruction in response
|
|
||||||
// to that particular message
|
|
||||||
if (QOS_level > LORAWAN_DEFAULT_QOS && _qos_cnt < QOS_level
|
|
||||||
&& (prev_QOS_level == QOS_level)) {
|
|
||||||
_ctrl_flags &= ~TX_DONE_FLAG;
|
|
||||||
const int ret = _queue->call(this, &LoRaWANStack::state_controller,
|
|
||||||
DEVICE_STATE_SCHEDULING);
|
|
||||||
MBED_ASSERT(ret != 0);
|
|
||||||
(void) ret;
|
|
||||||
_qos_cnt++;
|
|
||||||
tr_info("QOS: repeated transmission #%d queued", _qos_cnt);
|
|
||||||
} else {
|
|
||||||
_loramac.post_process_mcps_req();
|
|
||||||
_ctrl_flags |= TX_DONE_FLAG;
|
|
||||||
make_tx_metadata_available();
|
|
||||||
state_controller(DEVICE_STATE_STATUS_CHECK);
|
state_controller(DEVICE_STATE_STATUS_CHECK);
|
||||||
|
state_machine_run_to_completion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoRaWANStack::post_process_tx_no_reception()
|
void LoRaWANStack::handle_ack_expiry_for_class_c(void)
|
||||||
{
|
{
|
||||||
if (_loramac.get_mcps_confirmation()->req_type == MCPS_CONFIRMED) {
|
_ctrl_flags &= ~TX_DONE_FLAG;
|
||||||
if (_loramac.continue_sending_process()) {
|
_ctrl_flags |= TX_ONGOING_FLAG;
|
||||||
_ctrl_flags &= ~TX_DONE_FLAG;
|
tr_error("Retries exhausted for Class C device");
|
||||||
_ctrl_flags &= ~RETRY_EXHAUSTED_FLAG;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr_error("Retries exhausted for Class %s device",
|
|
||||||
_loramac.get_device_class() == CLASS_A ? "A" : "C");
|
|
||||||
_ctrl_flags &= ~TX_DONE_FLAG;
|
|
||||||
_ctrl_flags |= RETRY_EXHAUSTED_FLAG;
|
|
||||||
} else {
|
|
||||||
_ctrl_flags |= TX_DONE_FLAG;
|
|
||||||
|
|
||||||
uint8_t prev_QOS_level = _loramac.get_prev_QOS_level();
|
|
||||||
uint8_t QOS_level = _loramac.get_QOS_level();
|
|
||||||
|
|
||||||
if (QOS_level > LORAWAN_DEFAULT_QOS && (prev_QOS_level == QOS_level)) {
|
|
||||||
if (_qos_cnt < QOS_level) {
|
|
||||||
const int ret = _queue->call(this, &LoRaWANStack::state_controller,
|
|
||||||
DEVICE_STATE_SCHEDULING);
|
|
||||||
MBED_ASSERT(ret != 0);
|
|
||||||
(void)ret;
|
|
||||||
_qos_cnt++;
|
|
||||||
tr_info("QOS: repeated transmission #%d queued", _qos_cnt);
|
|
||||||
state_machine_run_to_completion();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_loramac.post_process_mcps_req();
|
|
||||||
make_tx_metadata_available();
|
|
||||||
state_controller(DEVICE_STATE_STATUS_CHECK);
|
state_controller(DEVICE_STATE_STATUS_CHECK);
|
||||||
state_machine_run_to_completion();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoRaWANStack::handle_scheduling_failure(void)
|
void LoRaWANStack::handle_scheduling_failure(void)
|
||||||
|
@ -686,18 +617,16 @@ void LoRaWANStack::handle_scheduling_failure(void)
|
||||||
state_machine_run_to_completion();
|
state_machine_run_to_completion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LoRaWANStack::process_reception(const uint8_t *const payload, uint16_t size,
|
void LoRaWANStack::process_reception(const uint8_t *const payload, uint16_t size,
|
||||||
int16_t rssi, int8_t snr)
|
int16_t rssi, int8_t snr)
|
||||||
{
|
{
|
||||||
_device_current_state = DEVICE_STATE_RECEIVING;
|
_device_current_state = DEVICE_STATE_RECEIVING;
|
||||||
|
|
||||||
_ctrl_flags &= ~MSG_RECVD_FLAG;
|
_ctrl_flags &= ~MSG_RECVD_FLAG;
|
||||||
_ctrl_flags &= ~TX_DONE_FLAG;
|
|
||||||
_ctrl_flags &= ~RETRY_EXHAUSTED_FLAG;
|
|
||||||
|
|
||||||
_loramac.on_radio_rx_done(payload, size, rssi, snr);
|
_loramac.on_radio_rx_done(payload, size, rssi, snr);
|
||||||
|
|
||||||
|
make_rx_metadata_available();
|
||||||
|
|
||||||
if (_loramac.get_mlme_confirmation()->pending) {
|
if (_loramac.get_mlme_confirmation()->pending) {
|
||||||
_loramac.post_process_mlme_request();
|
_loramac.post_process_mlme_request();
|
||||||
mlme_confirm_handler();
|
mlme_confirm_handler();
|
||||||
|
@ -713,10 +642,36 @@ void LoRaWANStack::process_reception(const uint8_t *const payload, uint16_t size
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
make_rx_metadata_available();
|
// if the outgoing message was of CONFIRMED type
|
||||||
|
if (_loramac.get_mcps_confirmation()->req_type == MCPS_CONFIRMED) {
|
||||||
// Post process transmission in response to the reception
|
// if ack was not received, we will try retransmission after
|
||||||
post_process_tx_with_reception();
|
// ACK_TIMEOUT. handle_data_frame() already disables ACK_TIMEOUT timer
|
||||||
|
// if ack was received. Otherwise, following method will be called in
|
||||||
|
// LoRaMac.cpp, on_ack_timeout_timer_event().
|
||||||
|
if (_loramac.get_mcps_indication()->is_ack_recvd) {
|
||||||
|
tr_debug("Ack=OK, NbTrials=%d",
|
||||||
|
_loramac.get_mcps_confirmation()->nb_retries);
|
||||||
|
_loramac.post_process_mcps_req();
|
||||||
|
_ctrl_flags |= TX_DONE_FLAG;
|
||||||
|
_ctrl_flags &= ~TX_ONGOING_FLAG;
|
||||||
|
state_controller(DEVICE_STATE_STATUS_CHECK);
|
||||||
|
} else {
|
||||||
|
if (!_loramac.continue_sending_process() &&
|
||||||
|
_loramac.get_current_slot() != RX_SLOT_WIN_1) {
|
||||||
|
tr_error("Retries exhausted for Class A device");
|
||||||
|
_ctrl_flags &= ~TX_DONE_FLAG;
|
||||||
|
_ctrl_flags |= TX_ONGOING_FLAG;
|
||||||
|
state_controller(DEVICE_STATE_STATUS_CHECK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (_loramac.get_device_class() == CLASS_A) {
|
||||||
|
// handle UNCONFIRMED case here, RX slots were turned off due to
|
||||||
|
// valid packet reception. For Class C, an outgoing UNCONFIRMED message
|
||||||
|
// gets its handling in process_transmission.
|
||||||
|
_loramac.post_process_mcps_req();
|
||||||
|
_ctrl_flags |= TX_DONE_FLAG;
|
||||||
|
state_controller(DEVICE_STATE_STATUS_CHECK);
|
||||||
|
}
|
||||||
|
|
||||||
// handle any pending MCPS indication
|
// handle any pending MCPS indication
|
||||||
if (_loramac.get_mcps_indication()->pending) {
|
if (_loramac.get_mcps_indication()->pending) {
|
||||||
|
@ -725,13 +680,15 @@ void LoRaWANStack::process_reception(const uint8_t *const payload, uint16_t size
|
||||||
state_controller(DEVICE_STATE_STATUS_CHECK);
|
state_controller(DEVICE_STATE_STATUS_CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// complete the cycle only if TX_DONE_FLAG is set
|
// change the state only if a TX cycle completes for Class A
|
||||||
if (_ctrl_flags & TX_DONE_FLAG) {
|
// For class C it's not needed as it will already be in receiving
|
||||||
|
// state, no matter if the TX cycle completed or not.
|
||||||
|
if (!(_ctrl_flags & TX_ONGOING_FLAG)) {
|
||||||
|
// we are done here, update the state
|
||||||
state_machine_run_to_completion();
|
state_machine_run_to_completion();
|
||||||
}
|
}
|
||||||
|
|
||||||
// suppress auto uplink if another auto-uplink is in AWAITING_ACK state
|
if (_loramac.get_mlme_indication()->pending) {
|
||||||
if (_loramac.get_mlme_indication()->pending && !_automatic_uplink_ongoing) {
|
|
||||||
tr_debug("MLME Indication pending");
|
tr_debug("MLME Indication pending");
|
||||||
_loramac.post_process_mlme_ind();
|
_loramac.post_process_mlme_ind();
|
||||||
tr_debug("Immediate Uplink requested");
|
tr_debug("Immediate Uplink requested");
|
||||||
|
@ -767,7 +724,18 @@ void LoRaWANStack::process_reception_timeout(bool is_timeout)
|
||||||
* never occurs.
|
* never occurs.
|
||||||
*/
|
*/
|
||||||
if (slot == RX_SLOT_WIN_2) {
|
if (slot == RX_SLOT_WIN_2) {
|
||||||
post_process_tx_no_reception();
|
_loramac.post_process_mcps_req();
|
||||||
|
|
||||||
|
if (_loramac.get_mcps_confirmation()->req_type == MCPS_CONFIRMED) {
|
||||||
|
if (_loramac.continue_sending_process()) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
tr_error("Retries exhausted for Class A device");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state_controller(DEVICE_STATE_STATUS_CHECK);
|
||||||
|
state_machine_run_to_completion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1056,15 +1024,11 @@ void LoRaWANStack::mcps_indication_handler()
|
||||||
|| (_loramac.get_device_class() == CLASS_C
|
|| (_loramac.get_device_class() == CLASS_C
|
||||||
&& mcps_indication->type == MCPS_CONFIRMED)) {
|
&& mcps_indication->type == MCPS_CONFIRMED)) {
|
||||||
#if (MBED_CONF_LORA_AUTOMATIC_UPLINK_MESSAGE)
|
#if (MBED_CONF_LORA_AUTOMATIC_UPLINK_MESSAGE)
|
||||||
// Do not queue an automatic uplink of there is one already outgoing
|
tr_debug("Sending empty uplink message...");
|
||||||
// This means we have not received an ack for the previous automatic uplink
|
_automatic_uplink_ongoing = true;
|
||||||
if (!_automatic_uplink_ongoing) {
|
const int ret = _queue->call(this, &LoRaWANStack::send_automatic_uplink_message, mcps_indication->port);
|
||||||
tr_debug("Sending empty uplink message...");
|
MBED_ASSERT(ret != 0);
|
||||||
_automatic_uplink_ongoing = true;
|
(void)ret;
|
||||||
const int ret = _queue->call(this, &LoRaWANStack::send_automatic_uplink_message, mcps_indication->port);
|
|
||||||
MBED_ASSERT(ret != 0);
|
|
||||||
(void)ret;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
send_event_to_application(UPLINK_REQUIRED);
|
send_event_to_application(UPLINK_REQUIRED);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1118,7 +1082,8 @@ void LoRaWANStack::process_shutdown_state(lorawan_status_t &op_status)
|
||||||
_lw_session.active = false;
|
_lw_session.active = false;
|
||||||
_device_current_state = DEVICE_STATE_SHUTDOWN;
|
_device_current_state = DEVICE_STATE_SHUTDOWN;
|
||||||
op_status = LORAWAN_STATUS_DEVICE_OFF;
|
op_status = LORAWAN_STATUS_DEVICE_OFF;
|
||||||
_ctrl_flags = 0;
|
_ctrl_flags &= ~CONNECTED_FLAG;
|
||||||
|
_ctrl_flags &= ~CONN_IN_PROGRESS_FLAG;
|
||||||
send_event_to_application(DISCONNECTED);
|
send_event_to_application(DISCONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1134,15 +1099,20 @@ void LoRaWANStack::process_status_check_state()
|
||||||
// Another possibility is the case when the stack fails to schedule a
|
// Another possibility is the case when the stack fails to schedule a
|
||||||
// deferred transmission and a scheduling failure handler is invoked.
|
// deferred transmission and a scheduling failure handler is invoked.
|
||||||
_ctrl_flags &= ~TX_DONE_FLAG;
|
_ctrl_flags &= ~TX_DONE_FLAG;
|
||||||
|
_ctrl_flags &= ~TX_ONGOING_FLAG;
|
||||||
_loramac.set_tx_ongoing(false);
|
_loramac.set_tx_ongoing(false);
|
||||||
_loramac.reset_ongoing_tx();
|
_loramac.reset_ongoing_tx();
|
||||||
mcps_confirm_handler();
|
mcps_confirm_handler();
|
||||||
|
|
||||||
} else if (_device_current_state == DEVICE_STATE_RECEIVING) {
|
} else if (_device_current_state == DEVICE_STATE_RECEIVING) {
|
||||||
|
|
||||||
if ((_ctrl_flags & TX_DONE_FLAG) || (_ctrl_flags & RETRY_EXHAUSTED_FLAG)) {
|
if ((_ctrl_flags & TX_DONE_FLAG) || (_ctrl_flags & TX_ONGOING_FLAG)) {
|
||||||
|
// for CONFIRMED case, ack validity is already checked
|
||||||
|
// If it was a successful transmission, TX_ONGOING_FLAG will not be set.
|
||||||
|
// If it was indeed set, that means the device was in Class C mode and
|
||||||
|
// CONFIRMED transmission was in place and the ack retries maxed out.
|
||||||
_ctrl_flags &= ~TX_DONE_FLAG;
|
_ctrl_flags &= ~TX_DONE_FLAG;
|
||||||
_ctrl_flags &= ~RETRY_EXHAUSTED_FLAG;
|
_ctrl_flags &= ~TX_ONGOING_FLAG;
|
||||||
_loramac.set_tx_ongoing(false);
|
_loramac.set_tx_ongoing(false);
|
||||||
_loramac.reset_ongoing_tx();
|
_loramac.reset_ongoing_tx();
|
||||||
// if an automatic uplink is ongoing, we should not send a TX_DONE
|
// if an automatic uplink is ongoing, we should not send a TX_DONE
|
||||||
|
@ -1174,6 +1144,7 @@ void LoRaWANStack::process_scheduling_state(lorawan_status_t &op_status)
|
||||||
|
|
||||||
op_status = _loramac.send_ongoing_tx();
|
op_status = _loramac.send_ongoing_tx();
|
||||||
if (op_status == LORAWAN_STATUS_OK) {
|
if (op_status == LORAWAN_STATUS_OK) {
|
||||||
|
_ctrl_flags |= TX_ONGOING_FLAG;
|
||||||
_ctrl_flags &= ~TX_DONE_FLAG;
|
_ctrl_flags &= ~TX_DONE_FLAG;
|
||||||
_loramac.set_tx_ongoing(true);
|
_loramac.set_tx_ongoing(true);
|
||||||
_device_current_state = DEVICE_STATE_SENDING;
|
_device_current_state = DEVICE_STATE_SENDING;
|
||||||
|
|
|
@ -483,11 +483,9 @@ private:
|
||||||
void make_tx_metadata_available(void);
|
void make_tx_metadata_available(void);
|
||||||
void make_rx_metadata_available(void);
|
void make_rx_metadata_available(void);
|
||||||
|
|
||||||
|
void handle_ack_expiry_for_class_c(void);
|
||||||
void handle_scheduling_failure(void);
|
void handle_scheduling_failure(void);
|
||||||
|
|
||||||
void post_process_tx_with_reception(void);
|
|
||||||
void post_process_tx_no_reception(void);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LoRaMac _loramac;
|
LoRaMac _loramac;
|
||||||
radio_events_t radio_events;
|
radio_events_t radio_events;
|
||||||
|
@ -499,7 +497,6 @@ private:
|
||||||
lorawan_tx_metadata _tx_metadata;
|
lorawan_tx_metadata _tx_metadata;
|
||||||
lorawan_rx_metadata _rx_metadata;
|
lorawan_rx_metadata _rx_metadata;
|
||||||
uint8_t _num_retry;
|
uint8_t _num_retry;
|
||||||
uint8_t _qos_cnt;
|
|
||||||
uint32_t _ctrl_flags;
|
uint32_t _ctrl_flags;
|
||||||
uint8_t _app_port;
|
uint8_t _app_port;
|
||||||
bool _link_check_requested;
|
bool _link_check_requested;
|
||||||
|
|
|
@ -78,8 +78,7 @@ LoRaMac::LoRaMac()
|
||||||
_mlme_confirmation(),
|
_mlme_confirmation(),
|
||||||
_is_nwk_joined(false),
|
_is_nwk_joined(false),
|
||||||
_continuous_rx2_window_open(false),
|
_continuous_rx2_window_open(false),
|
||||||
_device_class(CLASS_A),
|
_device_class(CLASS_A)
|
||||||
_prev_qos_level(LORAWAN_DEFAULT_QOS)
|
|
||||||
{
|
{
|
||||||
_params.keys.dev_eui = NULL;
|
_params.keys.dev_eui = NULL;
|
||||||
_params.keys.app_eui = NULL;
|
_params.keys.app_eui = NULL;
|
||||||
|
@ -174,9 +173,6 @@ void LoRaMac::post_process_mcps_req()
|
||||||
if (_params.is_ul_frame_counter_fixed == false) {
|
if (_params.is_ul_frame_counter_fixed == false) {
|
||||||
_params.ul_frame_counter++;
|
_params.ul_frame_counter++;
|
||||||
_params.adr_ack_counter++;
|
_params.adr_ack_counter++;
|
||||||
if (_params.sys_params.nb_trans > 1) {
|
|
||||||
_mcps_confirmation.nb_retries = _params.ul_nb_rep_counter;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -518,6 +514,10 @@ void LoRaMac::handle_data_frame(const uint8_t *const payload,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// message is intended for us and MIC have passed, stop RX2 Window
|
||||||
|
// Spec: 3.3.4 Receiver Activity during the receive windows
|
||||||
|
_lora_time.stop(_params.timers.rx_window2_timer);
|
||||||
|
|
||||||
_mcps_confirmation.ack_received = false;
|
_mcps_confirmation.ack_received = false;
|
||||||
_mcps_indication.is_ack_recvd = false;
|
_mcps_indication.is_ack_recvd = false;
|
||||||
_mcps_indication.pending = true;
|
_mcps_indication.pending = true;
|
||||||
|
@ -567,8 +567,6 @@ void LoRaMac::handle_data_frame(const uint8_t *const payload,
|
||||||
tr_debug("Discarding duplicate frame");
|
tr_debug("Discarding duplicate frame");
|
||||||
_mcps_indication.pending = false;
|
_mcps_indication.pending = false;
|
||||||
_mcps_indication.status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED;
|
_mcps_indication.status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else if (msg_type == FRAME_TYPE_DATA_UNCONFIRMED_DOWN) {
|
} else if (msg_type == FRAME_TYPE_DATA_UNCONFIRMED_DOWN) {
|
||||||
_params.is_srv_ack_requested = false;
|
_params.is_srv_ack_requested = false;
|
||||||
|
@ -586,19 +584,6 @@ void LoRaMac::handle_data_frame(const uint8_t *const payload,
|
||||||
_params.dl_frame_counter = downlink_counter;
|
_params.dl_frame_counter = downlink_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
// message is intended for us and MIC have passed, stop RX2 Window
|
|
||||||
// Spec: 3.3.4 Receiver Activity during the receive windows
|
|
||||||
if (get_current_slot() == RX_SLOT_WIN_1) {
|
|
||||||
_lora_time.stop(_params.timers.rx_window2_timer);
|
|
||||||
} else {
|
|
||||||
_lora_time.stop(_params.timers.rx_window1_timer);
|
|
||||||
_lora_time.stop(_params.timers.rx_window2_timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_device_class == CLASS_C) {
|
|
||||||
_lora_time.stop(_rx2_closure_timer_for_class_c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_params.is_node_ack_requested && fctrl.bits.ack) {
|
if (_params.is_node_ack_requested && fctrl.bits.ack) {
|
||||||
_mcps_confirmation.ack_received = fctrl.bits.ack;
|
_mcps_confirmation.ack_received = fctrl.bits.ack;
|
||||||
_mcps_indication.is_ack_recvd = fctrl.bits.ack;
|
_mcps_indication.is_ack_recvd = fctrl.bits.ack;
|
||||||
|
@ -644,32 +629,17 @@ void LoRaMac::on_radio_tx_done(lorawan_time_t timestamp)
|
||||||
_lora_phy->put_radio_to_sleep();
|
_lora_phy->put_radio_to_sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_mcps_confirmation.req_type == MCPS_UNCONFIRMED)
|
|
||||||
&& (_params.sys_params.nb_trans > 1)) {
|
|
||||||
_params.ul_nb_rep_counter++;
|
|
||||||
MBED_ASSERT(_params.ul_nb_rep_counter <= _params.sys_params.nb_trans);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_params.is_rx_window_enabled == true) {
|
if (_params.is_rx_window_enabled == true) {
|
||||||
lorawan_time_t time_diff = _lora_time.get_current_time() - timestamp;
|
lorawan_time_t time_diff = _lora_time.get_current_time() - timestamp;
|
||||||
// start timer after which rx1_window will get opened
|
// start timer after which rx1_window will get opened
|
||||||
_lora_time.start(_params.timers.rx_window1_timer,
|
_lora_time.start(_params.timers.rx_window1_timer,
|
||||||
_params.rx_window1_delay - time_diff);
|
_params.rx_window1_delay - time_diff);
|
||||||
|
|
||||||
// start timer after which rx2_window will get opened
|
if (_device_class != CLASS_C) {
|
||||||
_lora_time.start(_params.timers.rx_window2_timer,
|
_lora_time.start(_params.timers.rx_window2_timer,
|
||||||
_params.rx_window2_delay - time_diff);
|
_params.rx_window2_delay - time_diff);
|
||||||
|
|
||||||
// If class C and an Unconfirmed messgae is outgoing,
|
|
||||||
// this will start a timer which will invoke rx2 would be
|
|
||||||
// closure handler
|
|
||||||
if (get_device_class() == CLASS_C) {
|
|
||||||
_lora_time.start(_rx2_closure_timer_for_class_c,
|
|
||||||
(_params.rx_window2_delay - time_diff) +
|
|
||||||
_params.rx_window2_config.window_timeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// start timer after which ack wait will timeout (for Confirmed messages)
|
|
||||||
if (_params.is_node_ack_requested) {
|
if (_params.is_node_ack_requested) {
|
||||||
_lora_time.start(_params.timers.ack_timeout_timer,
|
_lora_time.start(_params.timers.ack_timeout_timer,
|
||||||
(_params.rx_window2_delay - time_diff) +
|
(_params.rx_window2_delay - time_diff) +
|
||||||
|
@ -693,7 +663,6 @@ void LoRaMac::on_radio_rx_done(const uint8_t *const payload, uint16_t size,
|
||||||
int16_t rssi, int8_t snr)
|
int16_t rssi, int8_t snr)
|
||||||
{
|
{
|
||||||
if (_device_class == CLASS_C && !_continuous_rx2_window_open) {
|
if (_device_class == CLASS_C && !_continuous_rx2_window_open) {
|
||||||
_lora_time.stop(_rx2_closure_timer_for_class_c);
|
|
||||||
open_rx2_window();
|
open_rx2_window();
|
||||||
} else if (_device_class != CLASS_C){
|
} else if (_device_class != CLASS_C){
|
||||||
_lora_time.stop(_params.timers.rx_window1_timer);
|
_lora_time.stop(_params.timers.rx_window1_timer);
|
||||||
|
@ -735,7 +704,6 @@ void LoRaMac::on_radio_tx_timeout(void)
|
||||||
{
|
{
|
||||||
_lora_time.stop(_params.timers.rx_window1_timer);
|
_lora_time.stop(_params.timers.rx_window1_timer);
|
||||||
_lora_time.stop(_params.timers.rx_window2_timer);
|
_lora_time.stop(_params.timers.rx_window2_timer);
|
||||||
_lora_time.stop(_rx2_closure_timer_for_class_c);
|
|
||||||
_lora_time.stop(_params.timers.ack_timeout_timer);
|
_lora_time.stop(_params.timers.ack_timeout_timer);
|
||||||
|
|
||||||
if (_device_class == CLASS_C) {
|
if (_device_class == CLASS_C) {
|
||||||
|
@ -749,19 +717,16 @@ void LoRaMac::on_radio_tx_timeout(void)
|
||||||
|
|
||||||
_mac_commands.clear_command_buffer();
|
_mac_commands.clear_command_buffer();
|
||||||
|
|
||||||
if (_mcps_confirmation.req_type == MCPS_CONFIRMED) {
|
_mcps_confirmation.nb_retries = _params.ack_timeout_retry_counter;
|
||||||
_mcps_confirmation.nb_retries = _params.ack_timeout_retry_counter;
|
|
||||||
} else {
|
|
||||||
_mcps_confirmation.nb_retries = _params.ul_nb_rep_counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
_mcps_confirmation.ack_received = false;
|
_mcps_confirmation.ack_received = false;
|
||||||
_mcps_confirmation.tx_toa = 0;
|
_mcps_confirmation.tx_toa = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoRaMac::on_radio_rx_timeout(bool is_timeout)
|
void LoRaMac::on_radio_rx_timeout(bool is_timeout)
|
||||||
{
|
{
|
||||||
if (_device_class == CLASS_A) {
|
if (_device_class == CLASS_C && !_continuous_rx2_window_open) {
|
||||||
|
open_rx2_window();
|
||||||
|
} else {
|
||||||
_lora_phy->put_radio_to_sleep();
|
_lora_phy->put_radio_to_sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,7 +868,7 @@ void LoRaMac::open_rx1_window(void)
|
||||||
_lora_phy->rx_config(&_params.rx_window1_config);
|
_lora_phy->rx_config(&_params.rx_window1_config);
|
||||||
_lora_phy->handle_receive();
|
_lora_phy->handle_receive();
|
||||||
|
|
||||||
tr_debug("RX1 slot open, Freq = %lu", _params.rx_window1_config.frequency);
|
tr_debug("Opening RX1 Window");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoRaMac::open_rx2_window()
|
void LoRaMac::open_rx2_window()
|
||||||
|
@ -932,7 +897,7 @@ void LoRaMac::open_rx2_window()
|
||||||
_lora_phy->handle_receive();
|
_lora_phy->handle_receive();
|
||||||
_params.rx_slot = _params.rx_window2_config.rx_slot;
|
_params.rx_slot = _params.rx_window2_config.rx_slot;
|
||||||
|
|
||||||
tr_debug("RX2 slot open, Freq = %lu", _params.rx_window2_config.frequency);
|
tr_debug("Opening RX2 Window, Frequency = %lu", _params.rx_window2_config.frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoRaMac::on_ack_timeout_timer_event(void)
|
void LoRaMac::on_ack_timeout_timer_event(void)
|
||||||
|
@ -940,6 +905,12 @@ void LoRaMac::on_ack_timeout_timer_event(void)
|
||||||
Lock lock(*this);
|
Lock lock(*this);
|
||||||
|
|
||||||
if (_params.ack_timeout_retry_counter > _params.max_ack_timeout_retries) {
|
if (_params.ack_timeout_retry_counter > _params.max_ack_timeout_retries) {
|
||||||
|
if (get_device_class() == CLASS_C) {
|
||||||
|
// no need to use EventQueue as LoRaWANStack and LoRaMac are always
|
||||||
|
// in same context
|
||||||
|
_mcps_confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
|
||||||
|
_ack_expiry_handler_for_class_c.call();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1309,7 +1280,7 @@ int16_t LoRaMac::prepare_ongoing_tx(const uint8_t port,
|
||||||
if (flags & MSG_PROPRIETARY_FLAG) {
|
if (flags & MSG_PROPRIETARY_FLAG) {
|
||||||
_ongoing_tx_msg.type = MCPS_PROPRIETARY;
|
_ongoing_tx_msg.type = MCPS_PROPRIETARY;
|
||||||
_ongoing_tx_msg.fport = port;
|
_ongoing_tx_msg.fport = port;
|
||||||
_ongoing_tx_msg.nb_trials = _params.sys_params.nb_trans;
|
_ongoing_tx_msg.nb_trials = 1;
|
||||||
// a proprietary frame only includes an MHDR field which contains MTYPE field.
|
// a proprietary frame only includes an MHDR field which contains MTYPE field.
|
||||||
// Everything else is at the discretion of the implementer
|
// Everything else is at the discretion of the implementer
|
||||||
fopts_len = 0;
|
fopts_len = 0;
|
||||||
|
@ -1394,12 +1365,10 @@ device_class_t LoRaMac::get_device_class() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoRaMac::set_device_class(const device_class_t &device_class,
|
void LoRaMac::set_device_class(const device_class_t &device_class,
|
||||||
mbed::Callback<void(void)>rx2_would_be_closure_handler)
|
mbed::Callback<void(void)>ack_expiry_handler)
|
||||||
{
|
{
|
||||||
_device_class = device_class;
|
_device_class = device_class;
|
||||||
_rx2_would_be_closure_for_class_c = rx2_would_be_closure_handler;
|
_ack_expiry_handler_for_class_c = ack_expiry_handler;
|
||||||
|
|
||||||
_lora_time.init(_rx2_closure_timer_for_class_c, _rx2_would_be_closure_for_class_c);
|
|
||||||
|
|
||||||
if (CLASS_A == _device_class) {
|
if (CLASS_A == _device_class) {
|
||||||
tr_debug("Changing device class to -> CLASS_A");
|
tr_debug("Changing device class to -> CLASS_A");
|
||||||
|
@ -1760,8 +1729,6 @@ lorawan_status_t LoRaMac::initialize(EventQueue *queue,
|
||||||
|
|
||||||
_ev_queue = queue;
|
_ev_queue = queue;
|
||||||
_scheduling_failure_handler = scheduling_failure_handler;
|
_scheduling_failure_handler = scheduling_failure_handler;
|
||||||
_rx2_closure_timer_for_class_c.callback = NULL;
|
|
||||||
_rx2_closure_timer_for_class_c.timer_id = -1;
|
|
||||||
|
|
||||||
_channel_plan.activate_channelplan_subsystem(_lora_phy);
|
_channel_plan.activate_channelplan_subsystem(_lora_phy);
|
||||||
|
|
||||||
|
@ -1775,7 +1742,7 @@ lorawan_status_t LoRaMac::initialize(EventQueue *queue,
|
||||||
_params.timers.aggregated_timeoff = 0;
|
_params.timers.aggregated_timeoff = 0;
|
||||||
|
|
||||||
_lora_phy->reset_to_default_values(&_params, true);
|
_lora_phy->reset_to_default_values(&_params, true);
|
||||||
_params.sys_params.nb_trans = 1;
|
_params.sys_params.retry_num = 1;
|
||||||
|
|
||||||
reset_mac_parameters();
|
reset_mac_parameters();
|
||||||
|
|
||||||
|
@ -1847,6 +1814,7 @@ uint8_t LoRaMac::get_max_possible_tx_size(uint8_t fopts_len)
|
||||||
max_possible_payload_size = allowed_frm_payload_size - fopts_len;
|
max_possible_payload_size = allowed_frm_payload_size - fopts_len;
|
||||||
} else {
|
} else {
|
||||||
max_possible_payload_size = allowed_frm_payload_size;
|
max_possible_payload_size = allowed_frm_payload_size;
|
||||||
|
fopts_len = 0;
|
||||||
_mac_commands.clear_command_buffer();
|
_mac_commands.clear_command_buffer();
|
||||||
_mac_commands.clear_repeat_buffer();
|
_mac_commands.clear_repeat_buffer();
|
||||||
}
|
}
|
||||||
|
@ -1954,18 +1922,3 @@ void LoRaMac::bind_phy(LoRaPHY &phy)
|
||||||
{
|
{
|
||||||
_lora_phy = &phy;
|
_lora_phy = &phy;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t LoRaMac::get_QOS_level()
|
|
||||||
{
|
|
||||||
if (_prev_qos_level != _params.sys_params.nb_trans) {
|
|
||||||
_prev_qos_level = _params.sys_params.nb_trans;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _params.sys_params.nb_trans;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t LoRaMac::get_prev_QOS_level()
|
|
||||||
{
|
|
||||||
return _prev_qos_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -295,11 +295,10 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief set_device_class Sets active device class.
|
* @brief set_device_class Sets active device class.
|
||||||
* @param device_class Device class to use.
|
* @param device_class Device class to use.
|
||||||
* @param rx2_would_be_closure_handler callback function to inform about
|
* @param ack_expiry_handler callback function to inform about ack expiry
|
||||||
* would be closure of RX2 window
|
|
||||||
*/
|
*/
|
||||||
void set_device_class(const device_class_t &device_class,
|
void set_device_class(const device_class_t &device_class,
|
||||||
mbed::Callback<void(void)>rx2_would_be_closure_handler);
|
mbed::Callback<void(void)>ack_expiry_handler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief setup_link_check_request Adds link check request command
|
* @brief setup_link_check_request Adds link check request command
|
||||||
|
@ -405,17 +404,6 @@ public:
|
||||||
*/
|
*/
|
||||||
rx_slot_t get_current_slot(void);
|
rx_slot_t get_current_slot(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates what level of QOS is set by network server. QOS level is set
|
|
||||||
* in response to a LinkADRReq for UNCONFIRMED messages
|
|
||||||
*/
|
|
||||||
uint8_t get_QOS_level(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
*Indicates level of QOS used for the previous outgoing message
|
|
||||||
*/
|
|
||||||
uint8_t get_prev_QOS_level(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These locks trample through to the upper layers and make
|
* These locks trample through to the upper layers and make
|
||||||
* the stack thread safe.
|
* the stack thread safe.
|
||||||
|
@ -644,16 +632,10 @@ private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class C doesn't timeout in RX2 window as it is a continuous window.
|
* Class C doesn't timeout in RX2 window as it is a continuous window.
|
||||||
* We use this callback to inform the LoRaWANStack controller that we did
|
* We use this callback to inform the LoRaWANStack controller that the
|
||||||
* not receive a downlink in a time equal to normal Class A type RX2
|
* system cannot do more retries.
|
||||||
* window timeout. This marks a 'would-be' closure for RX2, actual RX2 is
|
|
||||||
* not closed. Mostly network servers will send right at the beginning of
|
|
||||||
* RX2 window if they have something to send. So if we didn't receive anything
|
|
||||||
* in the time period equal to would be RX2 delay (which is a function of
|
|
||||||
* uplink message length and data rate), we will invoke this callback to let
|
|
||||||
* the upper layer know.
|
|
||||||
*/
|
*/
|
||||||
mbed::Callback<void(void)> _rx2_would_be_closure_for_class_c;
|
mbed::Callback<void(void)> _ack_expiry_handler_for_class_c;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transmission is async, i.e., a call to schedule_tx() may be deferred to
|
* Transmission is async, i.e., a call to schedule_tx() may be deferred to
|
||||||
|
@ -663,8 +645,6 @@ private:
|
||||||
*/
|
*/
|
||||||
mbed::Callback<void(void)> _scheduling_failure_handler;
|
mbed::Callback<void(void)> _scheduling_failure_handler;
|
||||||
|
|
||||||
timer_event_t _rx2_closure_timer_for_class_c;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure to hold MCPS indication data.
|
* Structure to hold MCPS indication data.
|
||||||
*/
|
*/
|
||||||
|
@ -692,8 +672,6 @@ private:
|
||||||
bool _continuous_rx2_window_open;
|
bool _continuous_rx2_window_open;
|
||||||
|
|
||||||
device_class_t _device_class;
|
device_class_t _device_class;
|
||||||
|
|
||||||
uint8_t _prev_qos_level;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MBED_LORAWAN_MAC_H__
|
#endif // MBED_LORAWAN_MAC_H__
|
||||||
|
|
|
@ -145,40 +145,40 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(const uint8_t *payload, ui
|
||||||
mlme_conf.nb_gateways = payload[mac_index++];
|
mlme_conf.nb_gateways = payload[mac_index++];
|
||||||
break;
|
break;
|
||||||
case SRV_MAC_LINK_ADR_REQ: {
|
case SRV_MAC_LINK_ADR_REQ: {
|
||||||
adr_req_params_t link_adr_req;
|
adr_req_params_t linkAdrReq;
|
||||||
int8_t link_adr_dr = DR_0;
|
int8_t linkAdrDatarate = DR_0;
|
||||||
int8_t link_adr_txpower = TX_POWER_0;
|
int8_t linkAdrTxPower = TX_POWER_0;
|
||||||
uint8_t link_adr_nbtrans = 0;
|
uint8_t linkAdrNbRep = 0;
|
||||||
uint8_t link_adr_nb_bytes_pasred = 0;
|
uint8_t linkAdrNbBytesParsed = 0;
|
||||||
|
|
||||||
// Fill parameter structure
|
// Fill parameter structure
|
||||||
link_adr_req.payload = &payload[mac_index - 1];
|
linkAdrReq.payload = &payload[mac_index - 1];
|
||||||
link_adr_req.payload_size = commands_size - (mac_index - 1);
|
linkAdrReq.payload_size = commands_size - (mac_index - 1);
|
||||||
link_adr_req.adr_enabled = mac_sys_params.adr_on;
|
linkAdrReq.adr_enabled = mac_sys_params.adr_on;
|
||||||
link_adr_req.ul_dwell_time = mac_sys_params.uplink_dwell_time;
|
linkAdrReq.ul_dwell_time = mac_sys_params.uplink_dwell_time;
|
||||||
link_adr_req.current_datarate = mac_sys_params.channel_data_rate;
|
linkAdrReq.current_datarate = mac_sys_params.channel_data_rate;
|
||||||
link_adr_req.current_tx_power = mac_sys_params.channel_tx_power;
|
linkAdrReq.current_tx_power = mac_sys_params.channel_tx_power;
|
||||||
link_adr_req.current_nb_trans = mac_sys_params.nb_trans;
|
linkAdrReq.current_nb_rep = mac_sys_params.retry_num;
|
||||||
|
|
||||||
// Process the ADR requests
|
// Process the ADR requests
|
||||||
status = lora_phy.link_ADR_request(&link_adr_req,
|
status = lora_phy.link_ADR_request(&linkAdrReq,
|
||||||
&link_adr_dr,
|
&linkAdrDatarate,
|
||||||
&link_adr_txpower,
|
&linkAdrTxPower,
|
||||||
&link_adr_nbtrans,
|
&linkAdrNbRep,
|
||||||
&link_adr_nb_bytes_pasred);
|
&linkAdrNbBytesParsed);
|
||||||
|
|
||||||
if ((status & 0x07) == 0x07) {
|
if ((status & 0x07) == 0x07) {
|
||||||
mac_sys_params.channel_data_rate = link_adr_dr;
|
mac_sys_params.channel_data_rate = linkAdrDatarate;
|
||||||
mac_sys_params.channel_tx_power = link_adr_txpower;
|
mac_sys_params.channel_tx_power = linkAdrTxPower;
|
||||||
mac_sys_params.nb_trans = link_adr_nbtrans;
|
mac_sys_params.retry_num = linkAdrNbRep;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the answers to the buffer
|
// Add the answers to the buffer
|
||||||
for (uint8_t i = 0; i < (link_adr_nb_bytes_pasred / 5); i++) {
|
for (uint8_t i = 0; i < (linkAdrNbBytesParsed / 5); i++) {
|
||||||
ret_value = add_link_adr_ans(status);
|
ret_value = add_link_adr_ans(status);
|
||||||
}
|
}
|
||||||
// Update MAC index
|
// Update MAC index
|
||||||
mac_index += link_adr_nb_bytes_pasred - 1;
|
mac_index += linkAdrNbBytesParsed - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SRV_MAC_DUTY_CYCLE_REQ:
|
case SRV_MAC_DUTY_CYCLE_REQ:
|
||||||
|
|
|
@ -36,8 +36,7 @@ SPDX-License-Identifier: BSD-3-Clause
|
||||||
#define CHANNELS_IN_MASK 16
|
#define CHANNELS_IN_MASK 16
|
||||||
|
|
||||||
LoRaPHY::LoRaPHY()
|
LoRaPHY::LoRaPHY()
|
||||||
: _radio(NULL),
|
: _radio(NULL)
|
||||||
_lora_time(NULL)
|
|
||||||
{
|
{
|
||||||
memset(&phy_params, 0, sizeof(phy_params));
|
memset(&phy_params, 0, sizeof(phy_params));
|
||||||
}
|
}
|
||||||
|
@ -807,11 +806,6 @@ void LoRaPHY::compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols,
|
||||||
((uint32_t *)phy_params.bandwidths.table)[rx_conf_params->datarate]);
|
((uint32_t *)phy_params.bandwidths.table)[rx_conf_params->datarate]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rx_conf_params->rx_slot == RX_SLOT_WIN_1) {
|
|
||||||
rx_conf_params->frequency = phy_params.channels.channel_list[rx_conf_params->channel].frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
get_rx_window_params(t_symbol, min_rx_symbols, rx_error, RADIO_WAKEUP_TIME,
|
get_rx_window_params(t_symbol, min_rx_symbols, rx_error, RADIO_WAKEUP_TIME,
|
||||||
&rx_conf_params->window_timeout, &rx_conf_params->window_offset);
|
&rx_conf_params->window_timeout, &rx_conf_params->window_offset);
|
||||||
}
|
}
|
||||||
|
@ -994,7 +988,7 @@ uint8_t LoRaPHY::link_ADR_request(adr_req_params_t *link_adr_req,
|
||||||
verify_params.adr_enabled = link_adr_req->adr_enabled;
|
verify_params.adr_enabled = link_adr_req->adr_enabled;
|
||||||
verify_params.current_datarate = link_adr_req->current_datarate;
|
verify_params.current_datarate = link_adr_req->current_datarate;
|
||||||
verify_params.current_tx_power = link_adr_req->current_tx_power;
|
verify_params.current_tx_power = link_adr_req->current_tx_power;
|
||||||
verify_params.current_nb_rep = link_adr_req->current_nb_trans;
|
verify_params.current_nb_rep = link_adr_req->current_nb_rep;
|
||||||
|
|
||||||
verify_params.datarate = adr_settings.datarate;
|
verify_params.datarate = adr_settings.datarate;
|
||||||
verify_params.tx_power = adr_settings.tx_power;
|
verify_params.tx_power = adr_settings.tx_power;
|
||||||
|
|
|
@ -479,7 +479,7 @@ uint8_t LoRaPHYAU915::link_ADR_request(adr_req_params_t* params,
|
||||||
verify_params.nb_rep = adr_settings.nb_rep;
|
verify_params.nb_rep = adr_settings.nb_rep;
|
||||||
verify_params.current_datarate = params->current_datarate;
|
verify_params.current_datarate = params->current_datarate;
|
||||||
verify_params.current_tx_power = params->current_tx_power;
|
verify_params.current_tx_power = params->current_tx_power;
|
||||||
verify_params.current_nb_rep = params->current_nb_trans;
|
verify_params.current_nb_rep = params->current_nb_rep;
|
||||||
verify_params.channel_mask = temp_channel_masks;
|
verify_params.channel_mask = temp_channel_masks;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -510,7 +510,7 @@ uint8_t LoRaPHYCN470::link_ADR_request(adr_req_params_t* params,
|
||||||
verify_params.nb_rep = adr_settings.nb_rep;
|
verify_params.nb_rep = adr_settings.nb_rep;
|
||||||
verify_params.current_datarate = params->current_datarate;
|
verify_params.current_datarate = params->current_datarate;
|
||||||
verify_params.current_tx_power = params->current_tx_power;
|
verify_params.current_tx_power = params->current_tx_power;
|
||||||
verify_params.current_nb_rep = params->current_nb_trans;
|
verify_params.current_nb_rep = params->current_nb_rep;
|
||||||
verify_params.channel_mask = temp_channel_masks;
|
verify_params.channel_mask = temp_channel_masks;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -517,7 +517,7 @@ uint8_t LoRaPHYUS915::link_ADR_request(adr_req_params_t* params,
|
||||||
verify_params.nb_rep = adr_settings.nb_rep;
|
verify_params.nb_rep = adr_settings.nb_rep;
|
||||||
verify_params.current_datarate = params->current_datarate;
|
verify_params.current_datarate = params->current_datarate;
|
||||||
verify_params.current_tx_power = params->current_tx_power;
|
verify_params.current_tx_power = params->current_tx_power;
|
||||||
verify_params.current_nb_rep = params->current_nb_trans;
|
verify_params.current_nb_rep = params->current_nb_rep;
|
||||||
verify_params.channel_mask = temp_channel_masks;
|
verify_params.channel_mask = temp_channel_masks;
|
||||||
|
|
||||||
// Verify the parameters and update, if necessary
|
// Verify the parameters and update, if necessary
|
||||||
|
|
|
@ -329,10 +329,9 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
int8_t current_tx_power;
|
int8_t current_tx_power;
|
||||||
/*!
|
/*!
|
||||||
* The current number of repetitions for obtaining a QOS level set by
|
* The current number of repetitions.
|
||||||
* NS (applicable only to unconfirmed messages).
|
|
||||||
*/
|
*/
|
||||||
uint8_t current_nb_trans;
|
uint8_t current_nb_rep;
|
||||||
} adr_req_params_t;
|
} adr_req_params_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -70,8 +70,6 @@ typedef uint32_t lorawan_time_t;
|
||||||
*/
|
*/
|
||||||
#define LORAMAC_PHY_MAXPAYLOAD 255
|
#define LORAMAC_PHY_MAXPAYLOAD 255
|
||||||
|
|
||||||
#define LORAWAN_DEFAULT_QOS 1
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Default user application maximum data size for transmission
|
* Default user application maximum data size for transmission
|
||||||
|
@ -189,10 +187,9 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
uint32_t join_accept_delay2;
|
uint32_t join_accept_delay2;
|
||||||
/*!
|
/*!
|
||||||
* The number of uplink messages repetitions for QOS set by network server
|
* The number of uplink messages repetitions (confirmed messages only).
|
||||||
* in LinkADRReq mac command (unconfirmed messages only).
|
|
||||||
*/
|
*/
|
||||||
uint8_t nb_trans;
|
uint8_t retry_num;
|
||||||
/*!
|
/*!
|
||||||
* The datarate offset between uplink and downlink on first window.
|
* The datarate offset between uplink and downlink on first window.
|
||||||
*/
|
*/
|
||||||
|
@ -877,9 +874,6 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
int8_t data_rate;
|
int8_t data_rate;
|
||||||
/*!
|
/*!
|
||||||
*
|
|
||||||
* For CONFIRMED Messages:
|
|
||||||
*
|
|
||||||
* The number of trials to transmit the frame, if the LoRaMAC layer did not
|
* The number of trials to transmit the frame, if the LoRaMAC layer did not
|
||||||
* receive an acknowledgment. The MAC performs a datarate adaptation
|
* receive an acknowledgment. The MAC performs a datarate adaptation
|
||||||
* according to the LoRaWAN Specification V1.0.2, chapter 18.4, as in
|
* according to the LoRaWAN Specification V1.0.2, chapter 18.4, as in
|
||||||
|
@ -898,13 +892,6 @@ typedef struct {
|
||||||
*
|
*
|
||||||
* Note that if nb_trials is set to 1 or 2, the MAC will not decrease
|
* Note that if nb_trials is set to 1 or 2, the MAC will not decrease
|
||||||
* the datarate, if the LoRaMAC layer did not receive an acknowledgment.
|
* the datarate, if the LoRaMAC layer did not receive an acknowledgment.
|
||||||
*
|
|
||||||
* For UNCONFIRMED Messages:
|
|
||||||
*
|
|
||||||
* Provides a certain QOS level set by network server in LinkADRReq MAC
|
|
||||||
* command. The device will transmit the given UNCONFIRMED message nb_trials
|
|
||||||
* time with same frame counter until a downlink is received. Standard defined
|
|
||||||
* range is 1:15. Data rates will NOT be adapted according to chapter 18.4.
|
|
||||||
*/
|
*/
|
||||||
uint8_t nb_trials;
|
uint8_t nb_trials;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue