mirror of https://github.com/ARMmbed/mbed-os.git
Rejoin logic added
BE to LE fixes, missing MLME types added LoRaWAN 1.1 Features added (Some LoRaPhy impl missing still + some TODOs in code) - MLME confirm handling refactored - Rejoin handling missing - new CF_LIST mechanism missing (+resets involved) - NVM handling missing Rejoin logic addedfeature-lorawan-1-1
parent
0d3283e3a0
commit
ccc3675a6a
|
@ -79,7 +79,15 @@ LoRaWANStack::LoRaWANStack()
|
|||
_device_mode_ind_ongoing(false),
|
||||
_new_class_type(CLASS_A),
|
||||
_automatic_uplink_ongoing(false),
|
||||
_queue(NULL)
|
||||
_queue(NULL),
|
||||
_rejoin_type1_send_period(MBED_CONF_LORA_REJOIN_TYPE1_SEND_PERIOD),
|
||||
_rejoin_type1_stamp(0),
|
||||
_rejoin_type0_counter(0),
|
||||
_forced_datarate(DR_0),
|
||||
_forced_period(0),
|
||||
_forced_retry_count(0),
|
||||
_forced_rejoin_type(REJOIN_REQUEST_TYPE0),
|
||||
_forced_counter(0)
|
||||
{
|
||||
_tx_metadata.stale = true;
|
||||
_rx_metadata.stale = true;
|
||||
|
@ -768,6 +776,8 @@ void LoRaWANStack::process_reception(const uint8_t *const payload, uint16_t size
|
|||
_ctrl_flags &= ~TX_DONE_FLAG;
|
||||
_ctrl_flags &= ~RETRY_EXHAUSTED_FLAG;
|
||||
|
||||
_rejoin_type0_counter++;
|
||||
|
||||
_loramac.on_radio_rx_done(payload, size, rssi, snr, callback(this, &LoRaWANStack::mlme_confirm_handler));
|
||||
|
||||
if (_loramac.get_mlme_confirmation()->pending) {
|
||||
|
@ -811,12 +821,26 @@ void LoRaWANStack::process_reception(const uint8_t *const payload, uint16_t size
|
|||
mlme_indication_handler();
|
||||
}
|
||||
|
||||
if (((_loramac.get_lora_time()->get_current_time()/1000) -
|
||||
_rejoin_type1_stamp) > _rejoin_type1_send_period) {
|
||||
_rejoin_type1_stamp = _loramac.get_lora_time()->get_current_time()/1000;
|
||||
process_rejoin(REJOIN_REQUEST_TYPE1, false);
|
||||
}
|
||||
uint32_t max_time;
|
||||
uint32_t max_count;
|
||||
_loramac.get_rejoin_parameters(max_time, max_count);
|
||||
if (_rejoin_type0_counter >= max_count) {
|
||||
//This causes excactly same handling as a timeout
|
||||
process_rejoin_type0();
|
||||
}
|
||||
|
||||
core_util_atomic_flag_clear(&_rx_payload_in_use);
|
||||
}
|
||||
|
||||
void LoRaWANStack::process_reception_timeout(bool is_timeout)
|
||||
{
|
||||
rx_slot_t slot = _loramac.get_current_slot();
|
||||
_rejoin_type0_counter++;
|
||||
|
||||
// when is_timeout == false, a CRC error took place in the received frame
|
||||
// we treat that erroneous frame as no frame received at all, hence handle
|
||||
|
@ -841,6 +865,24 @@ void LoRaWANStack::process_reception_timeout(bool is_timeout)
|
|||
*/
|
||||
if (slot == RX_SLOT_WIN_2) {
|
||||
post_process_tx_no_reception();
|
||||
_loramac.post_process_mcps_req();
|
||||
|
||||
state_controller(DEVICE_STATE_STATUS_CHECK);
|
||||
state_machine_run_to_completion();
|
||||
|
||||
if ((_loramac.get_lora_time()->get_current_time()/1000) -
|
||||
_rejoin_type1_stamp > _rejoin_type1_send_period) {
|
||||
_rejoin_type1_stamp = _loramac.get_lora_time()->get_current_time()/1000;
|
||||
process_rejoin(REJOIN_REQUEST_TYPE1, false);
|
||||
}
|
||||
|
||||
uint32_t max_time;
|
||||
uint32_t max_count;
|
||||
_loramac.get_rejoin_parameters(max_time, max_count);
|
||||
if (_rejoin_type0_counter >= max_count) {
|
||||
//This causes excactly same handling as a timeout
|
||||
process_rejoin_type0();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1043,6 +1085,13 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t& mlme_confirm)
|
|||
if (_loramac.get_server_type() == LW1_1) {
|
||||
_rekey_ind_needed = true;
|
||||
_rekey_ind_counter = 0;
|
||||
// THIS IS NOT ALLOWED HERE!
|
||||
// We might get JOIN_ACCEPT for rejoin type 1,
|
||||
// which points to different server!
|
||||
//reset_forced_rejoin();
|
||||
} else {
|
||||
_loramac.get_lora_time()->stop(_forced_timer);
|
||||
_loramac.get_lora_time()->stop(_rejoin_type0_timer);
|
||||
}
|
||||
state_controller(DEVICE_STATE_CONNECTED);
|
||||
break;
|
||||
|
@ -1059,7 +1108,25 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t& mlme_confirm)
|
|||
state_controller(DEVICE_STATE_JOINING);
|
||||
}
|
||||
} else if (mlme_confirm.type == MLME_FORCE_REJOIN) {
|
||||
//TODO: handle this
|
||||
if (join_req_type_t(mlme_confirm.rejoin_type) <= REJOIN_REQUEST_TYPE2 &&
|
||||
_loramac.get_server_type() == LW1_1 ) {
|
||||
_forced_datarate = mlme_confirm.datarate;
|
||||
_forced_period = ((1 << mlme_confirm.period)*32 + (rand()%33))*1000;
|
||||
_forced_retry_count = mlme_confirm.max_retries;
|
||||
if (_forced_retry_count) {
|
||||
_forced_retry_count += 1;
|
||||
}
|
||||
_forced_rejoin_type = join_req_type_t(mlme_confirm.rejoin_type);
|
||||
// See LW 1.1 chapter 5.13 - RejoinType
|
||||
if (join_req_type_t(mlme_confirm.rejoin_type) == REJOIN_REQUEST_TYPE1) {
|
||||
_forced_rejoin_type = REJOIN_REQUEST_TYPE0;
|
||||
}
|
||||
reset_forced_rejoin();
|
||||
process_rejoin(_forced_rejoin_type, true);
|
||||
if (_forced_retry_count) {
|
||||
_loramac.get_lora_time()->start(_forced_timer, _forced_period);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1341,4 +1408,61 @@ void LoRaWANStack::process_uninitialized_state(lorawan_status_t &op_status)
|
|||
if (op_status == LORAWAN_STATUS_OK) {
|
||||
_device_current_state = DEVICE_STATE_IDLE;
|
||||
}
|
||||
|
||||
if (MBED_CONF_LORA_VERSION == LORAWAN_VERSION_1_1) {
|
||||
_loramac.get_lora_time()->init(_forced_timer,
|
||||
mbed::callback(this, &LoRaWANStack::forced_timer_expiry));
|
||||
|
||||
_loramac.get_lora_time()->init(_rejoin_type0_timer,
|
||||
mbed::callback(this, &LoRaWANStack::process_rejoin_type0));
|
||||
|
||||
_rejoin_type1_stamp = _loramac.get_lora_time()->get_current_time()/1000;
|
||||
}
|
||||
}
|
||||
|
||||
void LoRaWANStack::process_rejoin(join_req_type_t rejoin_type, bool is_forced)
|
||||
{
|
||||
if (_loramac.get_server_type() == LW1_1 ) {
|
||||
_loramac.rejoin(rejoin_type, is_forced, _forced_datarate);
|
||||
if (rejoin_type == REJOIN_REQUEST_TYPE0) {
|
||||
_loramac.get_lora_time()->stop(_rejoin_type0_timer);
|
||||
_rejoin_type0_counter = 0;
|
||||
uint32_t max_time;
|
||||
uint32_t max_count;
|
||||
_loramac.get_rejoin_parameters(max_time, max_count);
|
||||
_loramac.get_lora_time()->start(_rejoin_type0_timer, max_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoRaWANStack::reset_forced_rejoin()
|
||||
{
|
||||
_forced_counter = 0;
|
||||
_loramac.get_lora_time()->stop(_forced_timer);
|
||||
}
|
||||
|
||||
void LoRaWANStack::forced_timer_expiry()
|
||||
{
|
||||
if (_loramac.get_server_type() == LW1_1 ) {
|
||||
if (_forced_counter < _forced_retry_count) {
|
||||
process_rejoin(_forced_rejoin_type, true);
|
||||
_loramac.get_lora_time()->start(_forced_timer, _forced_period);
|
||||
} else {
|
||||
reset_forced_rejoin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoRaWANStack::process_rejoin_type0()
|
||||
{
|
||||
if (_loramac.get_server_type() == LW1_1 ) {
|
||||
//stop in case counter was exceeded
|
||||
_loramac.get_lora_time()->stop(_rejoin_type0_timer);
|
||||
_rejoin_type0_counter = 0;
|
||||
process_rejoin(REJOIN_REQUEST_TYPE0, false);
|
||||
uint32_t max_time;
|
||||
uint32_t max_count;
|
||||
_loramac.get_rejoin_parameters(max_time, max_count);
|
||||
_loramac.get_lora_time()->start(_rejoin_type0_timer, max_time);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -513,8 +513,17 @@ private:
|
|||
void post_process_tx_with_reception(void);
|
||||
void post_process_tx_no_reception(void);
|
||||
|
||||
void process_rejoin(join_req_type_t rejoin_type, bool is_forced);
|
||||
void reset_forced_rejoin();
|
||||
|
||||
void forced_timer_expiry();
|
||||
void process_rejoin_type0();
|
||||
|
||||
private:
|
||||
LoRaMac _loramac;
|
||||
|
||||
LoRaWANTimeHandler _lora_time;
|
||||
|
||||
radio_events_t radio_events;
|
||||
device_states_t _device_current_state;
|
||||
lorawan_app_callbacks_t _callbacks;
|
||||
|
@ -539,6 +548,17 @@ private:
|
|||
uint8_t _rx_payload[LORAMAC_PHY_MAXPAYLOAD];
|
||||
events::EventQueue *_queue;
|
||||
lorawan_time_t _tx_timestamp;
|
||||
uint32_t _rejoin_type1_send_period;
|
||||
uint32_t _rejoin_type1_stamp;
|
||||
timer_event_t _rejoin_type0_timer;
|
||||
uint32_t _rejoin_type0_counter;
|
||||
|
||||
uint8_t _forced_datarate;
|
||||
uint32_t _forced_period;
|
||||
uint8_t _forced_retry_count;
|
||||
join_req_type_t _forced_rejoin_type;
|
||||
uint8_t _forced_counter;
|
||||
timer_event_t _forced_timer;
|
||||
};
|
||||
|
||||
#endif /* LORAWANSTACK_H_ */
|
||||
|
|
|
@ -66,6 +66,16 @@ using namespace mbed;
|
|||
*/
|
||||
#define DOWN_LINK 1
|
||||
|
||||
static void memcpy_convert_endianess(uint8_t *dst,
|
||||
const uint8_t *src,
|
||||
uint16_t size)
|
||||
{
|
||||
dst = dst + (size - 1);
|
||||
while (size--) {
|
||||
*dst-- = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
LoRaMac::LoRaMac()
|
||||
: _lora_time(),
|
||||
_lora_phy(NULL),
|
||||
|
@ -86,6 +96,8 @@ LoRaMac::LoRaMac()
|
|||
_prev_qos_level(LORAWAN_DEFAULT_QOS),
|
||||
_demod_ongoing(false)
|
||||
{
|
||||
_params.rejoin_forced = false;
|
||||
_params.forced_datarate = DR_0;
|
||||
_params.is_rx_window_enabled = true;
|
||||
_params.max_ack_timeout_retries = 1;
|
||||
_params.ack_timeout_retry_counter = 1;
|
||||
|
@ -118,11 +130,6 @@ const loramac_mcps_indication_t *LoRaMac::get_mcps_indication() const
|
|||
return &_mcps_indication;
|
||||
}
|
||||
|
||||
const loramac_mlme_confirm_t *LoRaMac::get_mlme_confirmation() const
|
||||
{
|
||||
return &_mlme_confirmation;
|
||||
}
|
||||
|
||||
const loramac_mlme_indication_t *LoRaMac::get_mlme_indication() const
|
||||
{
|
||||
return &_mlme_indication;
|
||||
|
@ -184,18 +191,7 @@ loramac_event_info_status_t LoRaMac::handle_join_accept_frame(const uint8_t *pay
|
|||
uint32_t mic_rx = 0;
|
||||
server_type_t stype = LW1_0_2;
|
||||
|
||||
//Store server type to local so that invalid join accept of rejoin request won't affect the orig. type.
|
||||
if ( (((_params.rx_buffer[11] >> 7) & 0x01) == 1) && MBED_CONF_LORA_VERSION == LORAWAN_VERSION_1_1) {
|
||||
stype = LW1_1;
|
||||
} else {
|
||||
stype = LW1_0_2;
|
||||
//Server does not support LW 1.1 so we need to unset JS keys
|
||||
memcpy(_params.keys.js_intkey, _params.keys.nwk_key, sizeof(_params.keys.nwk_skey));
|
||||
memcpy(_params.keys.js_enckey, _params.keys.nwk_key, sizeof(_params.keys.nwk_skey));
|
||||
}
|
||||
|
||||
uint8_t *decrypt_key = NULL;
|
||||
uint8_t *mic_key = _params.keys.js_intkey; //in case of LW1.0.2 js_intkey == nwk_key == app_key
|
||||
|
||||
if (_params.join_request_type == JOIN_REQUEST) {
|
||||
decrypt_key = _params.keys.nwk_key;
|
||||
|
@ -203,6 +199,13 @@ loramac_event_info_status_t LoRaMac::handle_join_accept_frame(const uint8_t *pay
|
|||
decrypt_key = _params.keys.js_enckey;
|
||||
}
|
||||
|
||||
if (0 != _lora_crypto.decrypt_join_frame(payload + 1, size - 1,
|
||||
decrypt_key, APPKEY_KEY_LENGTH,
|
||||
_params.rx_buffer + 1)) {
|
||||
return LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
_params.rx_buffer[0] = payload[0];
|
||||
|
||||
//Store server type to local so that invalid join accept of rejoin request won't affect the orig. type.
|
||||
if ( (((_params.rx_buffer[11] >> 7) & 0x01) == 1) && MBED_CONF_LORA_VERSION == LORAWAN_VERSION_1_1) {
|
||||
stype = LW1_1;
|
||||
|
@ -213,18 +216,14 @@ loramac_event_info_status_t LoRaMac::handle_join_accept_frame(const uint8_t *pay
|
|||
memcpy(_params.keys.js_enckey, _params.keys.nwk_key, sizeof(_params.keys.nwk_skey));
|
||||
}
|
||||
|
||||
if (0 != _lora_crypto.decrypt_join_frame(payload + 1, size - 1,
|
||||
decrypt_key, APPKEY_KEY_LENGTH,
|
||||
_params.rx_buffer + 1)) {
|
||||
return LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
uint8_t payload_start = 1;
|
||||
uint8_t mic_start = 0;
|
||||
uint8_t args_size = 0;
|
||||
uint8_t args[16];
|
||||
|
||||
uint8_t *mic_key = _params.keys.js_intkey; //in case of LW1.0.2 js_intkey == nwk_key == app_key
|
||||
|
||||
if (stype == LW1_0_2) {
|
||||
_params.rx_buffer[0] = payload[0];
|
||||
mic_start = size - LORAMAC_MFR_LEN;
|
||||
|
||||
memcpy(args, _params.rx_buffer + 1, 6);
|
||||
|
@ -232,16 +231,20 @@ loramac_event_info_status_t LoRaMac::handle_join_accept_frame(const uint8_t *pay
|
|||
args_size = 8;
|
||||
} else {
|
||||
//MIC calculation needs more params, so we move the payload a bit
|
||||
_params.rx_buffer[0] = (uint8_t)_params.join_request_type;
|
||||
memcpy(_params.rx_buffer + 11, _params.rx_buffer, size - LORAMAC_MFR_LEN);
|
||||
memcpy(_params.rx_buffer + 1, _params.keys.app_eui, 8);
|
||||
memcpy(_params.rx_buffer + 9, (uint8_t *) &_params.dev_nonce, 2);
|
||||
mic_start = size - LORAMAC_MFR_LEN + 11;
|
||||
memmove(_params.rx_buffer + 11, _params.rx_buffer, size);
|
||||
_params.rx_buffer[0] = _params.join_request_type; // JoinReqType
|
||||
memcpy_convert_endianess(_params.rx_buffer + 1, _params.keys.app_eui, 8); // JoinEUI
|
||||
_params.rx_buffer[9] = _params.dev_nonce & 0xFF; // DevNonce
|
||||
_params.rx_buffer[10] = (_params.dev_nonce >> 8) & 0xFF;
|
||||
size += 11;
|
||||
|
||||
mic_start = size - LORAMAC_MFR_LEN;
|
||||
payload_start += 11;
|
||||
|
||||
memcpy(args, _params.rx_buffer + payload_start, 3);
|
||||
memcpy(args + 3, _params.keys.app_eui, 8);
|
||||
memcpy(args + 3 + 8, (uint8_t *) &_params.dev_nonce, 2);
|
||||
memcpy_convert_endianess(args + 3, _params.keys.app_eui, 8);
|
||||
args[3+8] = _params.dev_nonce & 0xFF;
|
||||
args[3+9] = (_params.dev_nonce >> 8) & 0xFF;
|
||||
args_size = 13;
|
||||
}
|
||||
|
||||
|
@ -743,7 +746,6 @@ void LoRaMac::on_radio_tx_done(lorawan_time_t timestamp)
|
|||
}
|
||||
} else {
|
||||
_mcps_confirmation.status = LORAMAC_EVENT_INFO_STATUS_OK;
|
||||
_mlme_confirmation.status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT;
|
||||
}
|
||||
|
||||
_params.last_channel_idx = _params.channel;
|
||||
|
@ -826,7 +828,6 @@ void LoRaMac::on_radio_tx_timeout(void)
|
|||
}
|
||||
|
||||
_mcps_confirmation.status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
|
||||
_mlme_confirmation.status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
|
||||
|
||||
_mac_commands.clear_command_buffer();
|
||||
|
||||
|
@ -849,14 +850,8 @@ void LoRaMac::on_radio_rx_timeout(bool is_timeout)
|
|||
|
||||
if (_params.rx_slot == RX_SLOT_WIN_1) {
|
||||
if (_params.is_node_ack_requested == true) {
|
||||
_mcps_confirmation.status = is_timeout ?
|
||||
LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT :
|
||||
LORAMAC_EVENT_INFO_STATUS_RX1_ERROR;
|
||||
_mcps_confirmation.status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR;
|
||||
}
|
||||
_mlme_confirmation.status = is_timeout ?
|
||||
LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT :
|
||||
LORAMAC_EVENT_INFO_STATUS_RX1_ERROR;
|
||||
|
||||
if (_device_class != CLASS_C) {
|
||||
if (_lora_time.get_elapsed_time(_params.timers.aggregated_last_tx_time) >= _params.rx_window2_delay) {
|
||||
_lora_time.stop(_params.timers.rx_window2_timer);
|
||||
|
@ -864,14 +859,8 @@ void LoRaMac::on_radio_rx_timeout(bool is_timeout)
|
|||
}
|
||||
} else {
|
||||
if (_params.is_node_ack_requested == true) {
|
||||
_mcps_confirmation.status = is_timeout ?
|
||||
LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT :
|
||||
LORAMAC_EVENT_INFO_STATUS_RX2_ERROR;
|
||||
_mcps_confirmation.status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR;
|
||||
}
|
||||
|
||||
_mlme_confirmation.status = is_timeout ?
|
||||
LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT :
|
||||
LORAMAC_EVENT_INFO_STATUS_RX2_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1574,7 +1563,10 @@ lorawan_status_t LoRaMac::prepare_join(const lorawan_connect_t *params, bool is_
|
|||
_params.keys.nwk_key = params->connection_u.otaa.app_key;
|
||||
}
|
||||
|
||||
if (0 != _lora_crypto.compute_join_server_keys(_params.keys.nwk_key, APPKEY_KEY_LENGTH, _params.keys.dev_eui,
|
||||
uint8_t converted_eui[8];
|
||||
memcpy_convert_endianess(converted_eui, _params.keys.dev_eui, 8);
|
||||
|
||||
if (0 != _lora_crypto.compute_join_server_keys(_params.keys.nwk_key, APPKEY_KEY_LENGTH, converted_eui,
|
||||
_params.keys.js_intkey, _params.keys.js_enckey)) {
|
||||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
@ -1649,7 +1641,10 @@ lorawan_status_t LoRaMac::prepare_join(const lorawan_connect_t *params, bool is_
|
|||
_params.keys.nwk_key = _params.keys.app_key;
|
||||
}
|
||||
|
||||
if (0 != _lora_crypto.compute_join_server_keys(_params.keys.nwk_key, APPKEY_KEY_LENGTH, _params.keys.dev_eui,
|
||||
uint8_t converted_eui[8];
|
||||
memcpy_convert_endianess(converted_eui, _params.keys.dev_eui, 8);
|
||||
|
||||
if (0 != _lora_crypto.compute_join_server_keys(_params.keys.nwk_key, APPKEY_KEY_LENGTH, converted_eui,
|
||||
_params.keys.js_intkey, _params.keys.js_enckey)) {
|
||||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
@ -1700,23 +1695,15 @@ lorawan_status_t LoRaMac::join(bool is_otaa)
|
|||
return send_join_request();
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMac::rejoin(join_req_type_t rejoin_type)
|
||||
lorawan_status_t LoRaMac::rejoin(join_req_type_t rejoin_type, bool is_forced, uint8_t datarate)
|
||||
{
|
||||
_params.join_request_type = rejoin_type;
|
||||
_params.rejoin_forced = is_forced;
|
||||
_params.forced_datarate = datarate;
|
||||
|
||||
return send_join_request();
|
||||
}
|
||||
|
||||
static void memcpy_convert_endianess(uint8_t *dst,
|
||||
const uint8_t *src,
|
||||
uint16_t size)
|
||||
{
|
||||
dst = dst + (size - 1);
|
||||
while (size--) {
|
||||
*dst-- = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMac::prepare_frame(loramac_mhdr_t *machdr,
|
||||
loramac_frame_ctrl_t *fctrl,
|
||||
const uint8_t fport,
|
||||
|
@ -1970,7 +1957,11 @@ lorawan_status_t LoRaMac::send_frame_on_channel(uint8_t channel)
|
|||
int8_t tx_power = 0;
|
||||
|
||||
tx_config.channel = channel;
|
||||
if (_params.rejoin_forced) {
|
||||
tx_config.datarate = _params.forced_datarate;
|
||||
} else {
|
||||
tx_config.datarate = _params.sys_params.channel_data_rate;
|
||||
}
|
||||
tx_config.tx_power = _params.sys_params.channel_tx_power;
|
||||
tx_config.max_eirp = _params.sys_params.max_eirp;
|
||||
tx_config.antenna_gain = _params.sys_params.antenna_gain;
|
||||
|
@ -1978,8 +1969,6 @@ lorawan_status_t LoRaMac::send_frame_on_channel(uint8_t channel)
|
|||
|
||||
_lora_phy->tx_config(&tx_config, &tx_power, &_params.timers.tx_toa);
|
||||
|
||||
_mlme_confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
|
||||
|
||||
_mcps_confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
|
||||
_mcps_confirmation.data_rate = _params.sys_params.channel_data_rate;
|
||||
_mcps_confirmation.tx_power = tx_power;
|
||||
|
@ -2008,6 +1997,11 @@ void LoRaMac::reset_mcps_indication()
|
|||
_mcps_indication.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
|
||||
}
|
||||
|
||||
LoRaWANTimeHandler *LoRaMac::get_lora_time()
|
||||
{
|
||||
return &_lora_time;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMac::initialize(EventQueue *queue,
|
||||
mbed::Callback<void(void)>scheduling_failure_handler)
|
||||
{
|
||||
|
@ -2233,3 +2227,9 @@ uint8_t LoRaMac::get_current_adr_ack_limit()
|
|||
{
|
||||
return _lora_phy->get_adr_ack_limit();
|
||||
}
|
||||
|
||||
void LoRaMac::get_rejoin_parameters(uint32_t& max_time, uint32_t& max_count)
|
||||
{
|
||||
max_time = _lora_phy->get_rejoin_max_time();
|
||||
max_count = _lora_phy->get_rejoin_max_count();
|
||||
}
|
||||
|
|
|
@ -196,6 +196,13 @@ public:
|
|||
*/
|
||||
lorawan_status_t multicast_channel_unlink(multicast_params_t *channel_param);
|
||||
|
||||
/**
|
||||
* @brief get_rejoin_parameters Gets current rejoin parameters
|
||||
* @param max_time Current rejoin max time
|
||||
* @param max_count Current rejoin max count
|
||||
*/
|
||||
void get_rejoin_parameters(uint32_t& max_time, uint32_t& max_count);
|
||||
|
||||
/** Binds phy layer to MAC.
|
||||
*
|
||||
* @param phy LoRaPHY object
|
||||
|
@ -353,9 +360,11 @@ public:
|
|||
/**
|
||||
* @brief rejoin Rejoins the network
|
||||
* @param rejoin_type Rejoin type indicates the rejoin message payload
|
||||
* @param is_forced Indicates if the function was called because of ForceRejoinReq
|
||||
* @param datarate In case of forced rejoin, datarate to be used for Rejoin request
|
||||
* @return LORAWAN_STATUS_OK or a negative error code on failure.
|
||||
*/
|
||||
lorawan_status_t rejoin(join_req_type_t rejoin_type);
|
||||
lorawan_status_t rejoin(join_req_type_t rejoin_type, bool is_forced = false, uint8_t datarate = DR_0);
|
||||
|
||||
/**
|
||||
* MAC operations upon successful transmission
|
||||
|
@ -402,7 +411,6 @@ public:
|
|||
*/
|
||||
const loramac_mcps_confirm_t *get_mcps_confirmation() const;
|
||||
const loramac_mcps_indication_t *get_mcps_indication() const;
|
||||
const loramac_mlme_confirm_t *get_mlme_confirmation() const;
|
||||
const loramac_mlme_indication_t *get_mlme_indication() const;
|
||||
|
||||
/**
|
||||
|
@ -470,6 +478,8 @@ public:
|
|||
void unlock(void) { }
|
||||
#endif
|
||||
|
||||
LoRaWANTimeHandler *get_lora_time();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Queries the LoRaMAC the maximum possible FRMPayload size to send.
|
||||
|
@ -626,7 +636,6 @@ private:
|
|||
* Resets MAC primitive blocks
|
||||
*/
|
||||
void reset_mcps_confirmation(void);
|
||||
void reset_mlme_confirmation(void);
|
||||
void reset_mcps_indication(void);
|
||||
|
||||
/**
|
||||
|
|
|
@ -143,6 +143,7 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(const uint8_t *payload, ui
|
|||
switch (payload[mac_index++]) {
|
||||
case SRV_MAC_RESET_CONF: {
|
||||
loramac_mlme_confirm_t mlme_conf;
|
||||
mlme_conf.type = MLME_RESET;
|
||||
mlme_conf.status = LORAMAC_EVENT_INFO_STATUS_OK;
|
||||
mlme_conf.version = payload[mac_index++] & 0x0F;
|
||||
confirm_handler(mlme_conf);
|
||||
|
@ -150,6 +151,7 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(const uint8_t *payload, ui
|
|||
break;
|
||||
case SRV_MAC_LINK_CHECK_ANS: {
|
||||
loramac_mlme_confirm_t mlme_conf;
|
||||
mlme_conf.type = MLME_LINK_CHECK;
|
||||
mlme_conf.status = LORAMAC_EVENT_INFO_STATUS_OK;
|
||||
mlme_conf.demod_margin = payload[mac_index++];
|
||||
mlme_conf.nb_gateways = payload[mac_index++];
|
||||
|
@ -305,6 +307,7 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(const uint8_t *payload, ui
|
|||
break;
|
||||
case SRV_MAC_REKEY_CONF: {
|
||||
loramac_mlme_confirm_t mlme_conf;
|
||||
mlme_conf.type = MLME_REKEY;
|
||||
mlme_conf.status = LORAMAC_EVENT_INFO_STATUS_OK;
|
||||
mlme_conf.version = payload[mac_index++] & 0x0F;
|
||||
confirm_handler(mlme_conf);
|
||||
|
|
|
@ -39,6 +39,9 @@ SPDX-License-Identifier: BSD-3-Clause
|
|||
#define GPS_EPOCH_DIFF_WITH_UTC 315964800
|
||||
#define CHANNELS_IN_MASK 16
|
||||
|
||||
#define DEVICE_DOES_NOT_SUPPORT_TIME 0
|
||||
#define DEVICE_SUPPORTS_TIME 1
|
||||
|
||||
LoRaPHY::LoRaPHY()
|
||||
: _radio(NULL),
|
||||
_lora_time(NULL),
|
||||
|
@ -690,7 +693,7 @@ uint8_t LoRaPHY::update_rejoin_params(uint32_t max_time, uint32_t max_count)
|
|||
//These will be taken into use at next rejoin "cycle"
|
||||
_rejoin_max_time = max_time;
|
||||
_rejoin_max_count = max_count;
|
||||
return 1;
|
||||
return DEVICE_SUPPORTS_TIME;
|
||||
}
|
||||
|
||||
void LoRaPHY::restore_default_channels()
|
||||
|
@ -1513,4 +1516,13 @@ uint8_t LoRaPHY::apply_DR_offset(int8_t dr, int8_t dr_offset)
|
|||
return datarate;
|
||||
}
|
||||
|
||||
uint32_t LoRaPHY::get_rejoin_max_time() const
|
||||
{
|
||||
return _rejoin_max_time;
|
||||
}
|
||||
|
||||
uint32_t LoRaPHY::get_rejoin_max_count() const
|
||||
{
|
||||
return _rejoin_max_count;
|
||||
}
|
||||
|
||||
|
|
|
@ -604,6 +604,18 @@ public: //Verifiers
|
|||
*/
|
||||
void set_adr_ack_delay(const uint16_t& value);
|
||||
|
||||
/**
|
||||
* @brief getRejoin_max_time Getter for current rejoin max time
|
||||
* @return Current rejoin max time in seconds
|
||||
*/
|
||||
uint32_t get_rejoin_max_time() const;
|
||||
|
||||
/**
|
||||
* @brief get_rejoin_max_count Getter for current rejoin max count
|
||||
* @return Current rejoin max count
|
||||
*/
|
||||
uint32_t get_rejoin_max_count() const;
|
||||
|
||||
protected:
|
||||
LoRaPHY();
|
||||
|
||||
|
|
|
@ -116,6 +116,10 @@
|
|||
"rejoin-default-max-count": {
|
||||
"help": "LW1.1 only! Maximum amount of messages which can be sent between Rejoin requests.",
|
||||
"value": 1000
|
||||
},
|
||||
"rejoin-type1-send-period": {
|
||||
"help": "Rejoin type 1 sending period. NOTE: Rejoin message will be sent when this period has expired. Default is 1 week",
|
||||
"value": 604800
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -553,14 +553,6 @@ typedef enum {
|
|||
* A TX timeout occurred.
|
||||
*/
|
||||
LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT,
|
||||
/*!
|
||||
* An RX timeout occurred on receive window 1.
|
||||
*/
|
||||
LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT,
|
||||
/*!
|
||||
* An RX timeout occurred on receive window 2.
|
||||
*/
|
||||
LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT,
|
||||
/*!
|
||||
* An RX error occurred on receive window 1.
|
||||
*/
|
||||
|
@ -1458,6 +1450,15 @@ typedef struct {
|
|||
*/
|
||||
multicast_params_t *multicast_channels;
|
||||
|
||||
/*!
|
||||
* \brief rejoin_forced Boolean indicating if rejoin is forced. See ForceRejoinReq LW 1.1 spec ch 5.13
|
||||
*/
|
||||
bool rejoin_forced;
|
||||
/*!
|
||||
* \brief forced_datarate See ForceRejoinReq LW 1.1 spec ch 5.13
|
||||
*/
|
||||
uint8_t forced_datarate;
|
||||
|
||||
} loramac_protocol_params;
|
||||
|
||||
#endif /* LORAWAN_SYSTEM_LORAWAN_DATA_STRUCTURES_H_ */
|
||||
|
|
Loading…
Reference in New Issue