mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #13825 from artokin/nanostack_release_v12_6_1_feature-wisun
[feature-wisun] Nanostack release v12.6.1pull/13883/head
commit
0f4dbfda56
|
@ -382,6 +382,8 @@ int ws_management_channel_plan_set(
|
|||
*
|
||||
* Change the default configuration for Wi-SUN FHSS operation.
|
||||
*
|
||||
* Calling with fhss_uc_dwell_interval = 0, fhss_broadcast_interval = 0xffffffff,
|
||||
* fhss_bc_dwell_interval = 0 restores stack defaults
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param fhss_uc_dwell_interval default to 250 ms.
|
||||
|
@ -403,6 +405,7 @@ int ws_management_fhss_timing_configure(
|
|||
* Change the default configuration for Wi-SUN FHSS operation.
|
||||
* if application defined is used the behaviour is undefined
|
||||
*
|
||||
* Calling with dwell_interval = 0, channel_function = 0xff, fixed_channel = 0xffff restores stack defaults
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param channel_function Unicast channel function.
|
||||
|
@ -458,6 +461,8 @@ int ws_management_fhss_unicast_channel_function_validate(
|
|||
* Change the default configuration for Wi-SUN FHSS operation.
|
||||
* if application defined is used the behaviour is undefined
|
||||
*
|
||||
* Calling with dwell_interval = 0, channel_function = 0xff,
|
||||
* broadcast_interval = 0xffffffff, fixed_channel = 0xffff restores stack defaults
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param channel_function Broadcast channel function.
|
||||
|
|
|
@ -629,13 +629,14 @@ static void thread_bbr_network_data_send(thread_bbr_t *this, uint8_t prefix[8],
|
|||
|
||||
static void thread_bbr_routing_enable(thread_bbr_t *this, bool multicast_routing_enabled)
|
||||
{
|
||||
// Start multicast proxying
|
||||
// We do not enable multicast forwarding as there is other default router present in network
|
||||
multicast_fwd_set_forwarding(this->interface_id, multicast_routing_enabled);
|
||||
|
||||
if (this->routing_enabled) {
|
||||
return;
|
||||
}
|
||||
tr_info("br: enable routing");
|
||||
// Start multicast proxying
|
||||
// We do not enable multicast forwarding as there is other default router present in network
|
||||
multicast_fwd_set_forwarding(this->interface_id, multicast_routing_enabled);
|
||||
this->routing_enabled = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1045,6 +1045,15 @@ cleanup:
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
static void ws_bootstrap_asynch_trickle_stop(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
cur->ws_info->trickle_pas_running = false;
|
||||
cur->ws_info->trickle_pa_running = false;
|
||||
cur->ws_info->trickle_pcs_running = false;
|
||||
cur->ws_info->trickle_pc_running = false;
|
||||
cur->ws_info->trickle_pc_consistency_block_period = 0;
|
||||
}
|
||||
|
||||
static int8_t ws_bootstrap_down(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) {
|
||||
|
@ -1058,7 +1067,7 @@ static int8_t ws_bootstrap_down(protocol_interface_info_entry_t *cur)
|
|||
ns_fhss_delete(cur->ws_info->fhss_api);
|
||||
cur->ws_info->fhss_api = NULL;
|
||||
// Reset WS information
|
||||
// ws_common_reset(cur)
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
ws_llc_reset(cur);
|
||||
if (nd_proxy_downstream_interface_unregister(cur->id) != 0) {
|
||||
tr_warn("nd proxy unregister failed");
|
||||
|
@ -1103,11 +1112,7 @@ void ws_bootstrap_configuration_reset(protocol_interface_info_entry_t *cur)
|
|||
|
||||
cur->nwk_bootstrap_state = ER_ACTIVE_SCAN;
|
||||
cur->ws_info->network_pan_id = 0xffff;
|
||||
cur->ws_info->trickle_pas_running = false;
|
||||
cur->ws_info->trickle_pa_running = false;
|
||||
cur->ws_info->trickle_pcs_running = false;
|
||||
cur->ws_info->trickle_pc_running = false;
|
||||
cur->ws_info->trickle_pc_consistency_block_period = 0;
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
|
||||
//cur->mac_security_key_usage_update_cb = ws_management_mac_security_key_update_cb;
|
||||
return;
|
||||
|
@ -3228,6 +3233,9 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
|
|||
case WS_DISCOVERY_START:
|
||||
tr_info("Discovery start");
|
||||
|
||||
protocol_mac_reset(cur);
|
||||
ws_llc_reset(cur);
|
||||
lowpan_adaptation_interface_reset(cur->id);
|
||||
//Clear Pending Key Index State
|
||||
cur->ws_info->pending_key_index_info.state = NO_PENDING_PROCESS;
|
||||
cur->mac_parameters->mac_default_key_index = 0;
|
||||
|
@ -3236,11 +3244,7 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
|
|||
blacklist_clear();
|
||||
|
||||
// All trickle timers stopped to allow entry from any state
|
||||
cur->ws_info->trickle_pa_running = false;
|
||||
cur->ws_info->trickle_pc_running = false;
|
||||
cur->ws_info->trickle_pas_running = false;
|
||||
cur->ws_info->trickle_pcs_running = false;
|
||||
cur->ws_info->trickle_pc_consistency_block_period = 0;
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
|
||||
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
||||
tr_info("Border router start network");
|
||||
|
@ -3329,11 +3333,7 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
|
|||
case WS_CONFIGURATION_START:
|
||||
tr_info("Configuration start");
|
||||
// Old configuration is considered invalid stopping all
|
||||
cur->ws_info->trickle_pa_running = false;
|
||||
cur->ws_info->trickle_pc_running = false;
|
||||
cur->ws_info->trickle_pas_running = false;
|
||||
cur->ws_info->trickle_pcs_running = false;
|
||||
cur->ws_info->trickle_pc_consistency_block_period = 0;
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
|
||||
// Build list of possible neighbours and learn first broadcast schedule
|
||||
|
||||
|
@ -3342,11 +3342,7 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
|
|||
case WS_OPERATION_START:
|
||||
tr_info("operation start");
|
||||
// Advertisements stopped during the RPL scan
|
||||
cur->ws_info->trickle_pa_running = false;
|
||||
cur->ws_info->trickle_pc_running = false;
|
||||
cur->ws_info->trickle_pas_running = false;
|
||||
cur->ws_info->trickle_pcs_running = false;
|
||||
cur->ws_info->trickle_pc_consistency_block_period = 0;
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
// Activate RPL
|
||||
// Activate IPv6 stack
|
||||
ws_bootstrap_ip_stack_activate(cur);
|
||||
|
@ -3362,11 +3358,7 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
|
|||
case WS_ROUTING_READY:
|
||||
tr_info("Routing ready");
|
||||
// stopped all to make sure we can enter here from any state
|
||||
cur->ws_info->trickle_pa_running = false;
|
||||
cur->ws_info->trickle_pc_running = false;
|
||||
cur->ws_info->trickle_pas_running = false;
|
||||
cur->ws_info->trickle_pcs_running = false;
|
||||
cur->ws_info->trickle_pc_consistency_block_period = 0;
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
|
||||
// Indicate PAE controller that bootstrap is ready
|
||||
ws_pae_controller_bootstrap_done(cur);
|
||||
|
@ -3547,11 +3539,7 @@ void ws_bootstrap_state_machine(protocol_interface_info_entry_t *cur)
|
|||
case ER_PANA_AUTH:
|
||||
tr_info("authentication start");
|
||||
// Advertisements stopped during the EAPOL
|
||||
cur->ws_info->trickle_pa_running = false;
|
||||
cur->ws_info->trickle_pc_running = false;
|
||||
cur->ws_info->trickle_pas_running = false;
|
||||
cur->ws_info->trickle_pcs_running = false;
|
||||
cur->ws_info->trickle_pc_consistency_block_period = 0;
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
ws_fhss_configure(cur, false);
|
||||
int8_t new_default = cur->ws_info->weakest_received_rssi - 1;
|
||||
if ((new_default < CCA_DEFAULT_DBM) && (new_default >= CCA_LOW_LIMIT) && (new_default <= CCA_HIGH_LIMIT)) {
|
||||
|
|
|
@ -942,7 +942,7 @@ int8_t ws_cfg_fhss_validate(ws_fhss_cfg_t *cfg, ws_fhss_cfg_t *new_cfg)
|
|||
return CFG_SETTINGS_ERROR_FHSS_CONF;
|
||||
}
|
||||
|
||||
if (new_cfg->fhss_bc_dwell_interval < 15) {
|
||||
if (new_cfg->fhss_bc_dwell_interval < 100) {
|
||||
return CFG_SETTINGS_ERROR_FHSS_CONF;
|
||||
}
|
||||
|
||||
|
|
|
@ -1259,6 +1259,16 @@ static void ws_llc_mpx_data_request(const mpx_api_t *api, const struct mcps_data
|
|||
return;
|
||||
}
|
||||
|
||||
if (!base->ie_params.hopping_schedule) {
|
||||
tr_error("Missing FHSS configurations");
|
||||
mcps_data_conf_t data_conf;
|
||||
memset(&data_conf, 0, sizeof(mcps_data_conf_t));
|
||||
data_conf.msduHandle = data->msduHandle;
|
||||
data_conf.status = MLME_TRANSACTION_OVERFLOW;
|
||||
user_cb->data_confirm(&base->mpx_data_base.mpx_api, &data_conf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (user_id == MPX_KEY_MANAGEMENT_ENC_USER_ID) {
|
||||
ws_llc_mpx_eapol_request(base, user_cb, data);
|
||||
} else if (user_id == MPX_LOWPAN_ENC_USER_ID) {
|
||||
|
@ -1643,10 +1653,11 @@ mpx_api_t *ws_llc_mpx_api_get(struct protocol_interface_info_entry *interface)
|
|||
int8_t ws_llc_asynch_request(struct protocol_interface_info_entry *interface, asynch_request_t *request)
|
||||
{
|
||||
llc_data_base_t *base = ws_llc_discover_by_interface(interface);
|
||||
if (!base) {
|
||||
if (!base || !base->ie_params.hopping_schedule) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//Calculate IE Buffer size
|
||||
request->wh_requested_ie_list.fc_ie = false; //Never should not be a part Asynch message
|
||||
request->wh_requested_ie_list.rsl_ie = false; //Never should not be a part Asynch message
|
||||
|
|
|
@ -461,22 +461,22 @@ int ws_management_fhss_timing_configure(
|
|||
return -2;
|
||||
}
|
||||
|
||||
if (fhss_uc_dwell_interval > 0) {
|
||||
cfg.fhss_uc_dwell_interval = fhss_uc_dwell_interval;
|
||||
} else if (fhss_uc_dwell_interval == 0xff) {
|
||||
if (fhss_uc_dwell_interval == 0) {
|
||||
cfg.fhss_uc_dwell_interval = cfg_default.fhss_uc_dwell_interval;
|
||||
} else {
|
||||
cfg.fhss_uc_dwell_interval = fhss_uc_dwell_interval;
|
||||
}
|
||||
|
||||
if (fhss_broadcast_interval > 0) {
|
||||
cfg.fhss_bc_interval = fhss_broadcast_interval;
|
||||
} else if (fhss_broadcast_interval == 0xffff) {
|
||||
if (fhss_broadcast_interval > 0xffffff) {
|
||||
cfg.fhss_bc_interval = cfg_default.fhss_bc_interval;
|
||||
} else if (fhss_broadcast_interval > 0) {
|
||||
cfg.fhss_bc_interval = fhss_broadcast_interval;
|
||||
}
|
||||
|
||||
if (fhss_bc_dwell_interval > 0) {
|
||||
cfg.fhss_bc_dwell_interval = fhss_bc_dwell_interval;
|
||||
} else if (fhss_bc_dwell_interval == 0xff) {
|
||||
if (fhss_bc_dwell_interval == 0) {
|
||||
cfg.fhss_bc_dwell_interval = cfg_default.fhss_bc_dwell_interval;
|
||||
} else {
|
||||
cfg.fhss_bc_dwell_interval = fhss_bc_dwell_interval;
|
||||
}
|
||||
|
||||
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
|
||||
|
@ -509,10 +509,10 @@ int ws_management_fhss_unicast_channel_function_configure(
|
|||
return -2;
|
||||
}
|
||||
|
||||
if (dwell_interval > 0) {
|
||||
cfg.fhss_uc_dwell_interval = dwell_interval;
|
||||
} else {
|
||||
if (dwell_interval == 0) {
|
||||
cfg.fhss_uc_dwell_interval = cfg_default.fhss_uc_dwell_interval;
|
||||
} else {
|
||||
cfg.fhss_uc_dwell_interval = dwell_interval;
|
||||
}
|
||||
if (channel_function < 0xff) {
|
||||
cfg.fhss_uc_channel_function = channel_function;
|
||||
|
@ -611,16 +611,16 @@ int ws_management_fhss_broadcast_channel_function_configure(
|
|||
return -2;
|
||||
}
|
||||
|
||||
if (dwell_interval > 0) {
|
||||
cfg.fhss_bc_dwell_interval = dwell_interval;
|
||||
} else {
|
||||
if (dwell_interval == 0) {
|
||||
cfg.fhss_bc_dwell_interval = cfg_default.fhss_bc_dwell_interval;
|
||||
} else {
|
||||
cfg.fhss_bc_dwell_interval = dwell_interval;
|
||||
}
|
||||
|
||||
if (broadcast_interval > 0) {
|
||||
cfg.fhss_bc_interval = broadcast_interval;
|
||||
} else {
|
||||
if (broadcast_interval > 0xffffff) {
|
||||
cfg.fhss_bc_interval = cfg_default.fhss_bc_interval;
|
||||
} else if (broadcast_interval > 0) {
|
||||
cfg.fhss_bc_interval = broadcast_interval;
|
||||
}
|
||||
|
||||
if (channel_function != 0xff) {
|
||||
|
|
|
@ -106,10 +106,27 @@ static void ws_neighbor_calculate_ufsi_drift(ws_neighbor_class_entry_t *ws_neigh
|
|||
if (ws_neighbor->fhss_data.uc_timing_info.unicast_channel_function == WS_TR51CF) {
|
||||
seq_length = ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels;
|
||||
}
|
||||
uint32_t ufsi_prev_tmp = ws_neighbor->fhss_data.uc_timing_info.ufsi;
|
||||
uint32_t ufsi_cur_tmp = ws_utt->ufsi;
|
||||
if (ws_neighbor->fhss_data.uc_timing_info.unicast_channel_function == WS_DH1CF) {
|
||||
if (ufsi_cur_tmp < ufsi_prev_tmp) {
|
||||
ufsi_cur_tmp += 0xffffff;
|
||||
}
|
||||
}
|
||||
// Convert 24-bit UFSI to real time before drift calculation
|
||||
uint32_t time_since_seq_start_prev_ms = own_ceil((float)((uint64_t)ws_neighbor->fhss_data.uc_timing_info.ufsi * seq_length * ws_neighbor->fhss_data.uc_timing_info.unicast_dwell_interval) / 0x1000000);
|
||||
uint32_t time_since_seq_start_cur_ms = own_ceil((float)((uint64_t)ws_utt->ufsi * seq_length * ws_neighbor->fhss_data.uc_timing_info.unicast_dwell_interval) / 0x1000000);
|
||||
uint32_t time_since_seq_start_prev_ms = own_ceil((float)((uint64_t)ufsi_prev_tmp * seq_length * ws_neighbor->fhss_data.uc_timing_info.unicast_dwell_interval) / 0x1000000);
|
||||
uint32_t time_since_seq_start_cur_ms = own_ceil((float)((uint64_t)ufsi_cur_tmp * seq_length * ws_neighbor->fhss_data.uc_timing_info.unicast_dwell_interval) / 0x1000000);
|
||||
uint32_t time_since_last_ufsi_us = timestamp - ws_neighbor->fhss_data.uc_timing_info.utt_rx_timestamp;
|
||||
|
||||
if (ws_neighbor->fhss_data.uc_timing_info.unicast_channel_function == WS_TR51CF) {
|
||||
uint32_t full_uc_schedule_ms = ws_neighbor->fhss_data.uc_timing_info.unicast_dwell_interval * ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels;
|
||||
uint32_t temp_ms = (time_since_last_ufsi_us / 1000) / full_uc_schedule_ms;
|
||||
if (time_since_seq_start_cur_ms >= time_since_seq_start_prev_ms) {
|
||||
temp_ms--;
|
||||
}
|
||||
time_since_seq_start_cur_ms += temp_ms * full_uc_schedule_ms + (full_uc_schedule_ms - time_since_seq_start_prev_ms) + time_since_seq_start_prev_ms;
|
||||
}
|
||||
|
||||
uint32_t ufsi_diff_ms = time_since_seq_start_cur_ms - time_since_seq_start_prev_ms;
|
||||
int32_t ufsi_drift_ms = (int32_t)(time_since_last_ufsi_us / 1000 - ufsi_diff_ms);
|
||||
// Only trace if there is significant error
|
||||
|
|
|
@ -695,6 +695,9 @@ void ws_pae_auth_fast_timer(uint16_t ticks)
|
|||
ws_pae_auth_timer_stop(pae_auth);
|
||||
}
|
||||
}
|
||||
|
||||
// Update key storage fast timer
|
||||
ws_pae_key_storage_fast_timer(ticks);
|
||||
}
|
||||
|
||||
void ws_pae_auth_slow_timer(uint16_t seconds)
|
||||
|
|
|
@ -122,7 +122,7 @@ static pae_controller_t *ws_pae_controller_get(protocol_interface_info_entry_t *
|
|||
static void ws_pae_controller_frame_counter_timer(uint16_t seconds, pae_controller_t *entry);
|
||||
static void ws_pae_controller_frame_counter_timer_trigger(uint16_t seconds, pae_controller_t *entry);
|
||||
static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool use_threshold);
|
||||
static void ws_pae_controller_nvm_frame_counter_write(nvm_tlv_t *tlv_entry);
|
||||
static void ws_pae_controller_nvm_frame_counter_write(frame_cnt_nvm_tlv_t *tlv_entry);
|
||||
static int8_t ws_pae_controller_nvm_frame_counter_read(uint32_t *restart_cnt, uint64_t *stored_time, uint16_t *pan_version, frame_counters_t *counters);
|
||||
static pae_controller_t *ws_pae_controller_get_or_create(int8_t interface_id);
|
||||
static void ws_pae_controller_gtk_hash_set(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash);
|
||||
|
@ -801,8 +801,8 @@ static int8_t ws_pae_controller_frame_counter_read(pae_controller_t *controller)
|
|||
}
|
||||
if (updated) {
|
||||
// Writes incremented frame counters
|
||||
ws_pae_nvm_store_frame_counter_tlv_create((nvm_tlv_t *) &controller->pae_nvm_buffer, controller->restart_cnt, controller->sec_keys_nw_info.pan_version, &controller->frame_counters);
|
||||
ws_pae_controller_nvm_frame_counter_write((nvm_tlv_t *) &controller->pae_nvm_buffer);
|
||||
ws_pae_nvm_store_frame_counter_tlv_create((frame_cnt_nvm_tlv_t *) &controller->pae_nvm_buffer, controller->restart_cnt, controller->sec_keys_nw_info.pan_version, &controller->frame_counters);
|
||||
ws_pae_controller_nvm_frame_counter_write((frame_cnt_nvm_tlv_t *) &controller->pae_nvm_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -839,28 +839,28 @@ static int8_t ws_pae_controller_nw_info_read(pae_controller_t *controller, sec_p
|
|||
|
||||
static int8_t ws_pae_controller_nvm_nw_info_write(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, sec_prot_gtk_keys_t *gtks)
|
||||
{
|
||||
nvm_tlv_t *tlv = ws_pae_controller_nvm_tlv_get(interface_ptr);
|
||||
nw_info_nvm_tlv_t *tlv = (nw_info_nvm_tlv_t *) ws_pae_controller_nvm_tlv_get(interface_ptr);
|
||||
if (!tlv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ws_pae_nvm_store_nw_info_tlv_create(tlv, pan_id, network_name, gtks);
|
||||
|
||||
ws_pae_nvm_store_tlv_file_write(NW_INFO_FILE, tlv);
|
||||
ws_pae_nvm_store_tlv_file_write(NW_INFO_FILE, (nvm_tlv_t *) tlv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int8_t ws_pae_controller_nvm_nw_info_read(protocol_interface_info_entry_t *interface_ptr, uint16_t *pan_id, char *network_name, sec_prot_gtk_keys_t *gtks)
|
||||
{
|
||||
nvm_tlv_t *tlv_entry = ws_pae_controller_nvm_tlv_get(interface_ptr);
|
||||
nw_info_nvm_tlv_t *tlv_entry = (nw_info_nvm_tlv_t *) ws_pae_controller_nvm_tlv_get(interface_ptr);
|
||||
if (!tlv_entry) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ws_pae_nvm_store_generic_tlv_create(tlv_entry, PAE_NVM_NW_INFO_TAG, PAE_NVM_NW_INFO_LEN);
|
||||
ws_pae_nvm_store_generic_tlv_create((nvm_tlv_t *) tlv_entry, PAE_NVM_NW_INFO_TAG, PAE_NVM_NW_INFO_LEN);
|
||||
|
||||
if (ws_pae_nvm_store_tlv_file_read(NW_INFO_FILE, tlv_entry) < 0) {
|
||||
if (ws_pae_nvm_store_tlv_file_read(NW_INFO_FILE, (nvm_tlv_t *) tlv_entry) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1654,6 +1654,8 @@ void ws_pae_controller_slow_timer(uint16_t seconds)
|
|||
}
|
||||
ws_pae_controller_frame_counter_timer(seconds, entry);
|
||||
}
|
||||
|
||||
ws_pae_current_time_update(seconds);
|
||||
}
|
||||
|
||||
static void ws_pae_controller_frame_counter_timer(uint16_t seconds, pae_controller_t *entry)
|
||||
|
@ -1727,8 +1729,8 @@ static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool
|
|||
if (update_needed || entry->frame_cnt_store_force_timer == 0) {
|
||||
tr_debug("Write frame counters: system time %"PRIu32"", protocol_core_monotonic_time / 10);
|
||||
// Writes modified frame counters
|
||||
ws_pae_nvm_store_frame_counter_tlv_create((nvm_tlv_t *) &entry->pae_nvm_buffer, entry->restart_cnt, entry->sec_keys_nw_info.pan_version, &entry->frame_counters);
|
||||
ws_pae_controller_nvm_frame_counter_write((nvm_tlv_t *) &entry->pae_nvm_buffer);
|
||||
ws_pae_nvm_store_frame_counter_tlv_create((frame_cnt_nvm_tlv_t *) &entry->pae_nvm_buffer, entry->restart_cnt, entry->sec_keys_nw_info.pan_version, &entry->frame_counters);
|
||||
ws_pae_controller_nvm_frame_counter_write((frame_cnt_nvm_tlv_t *) &entry->pae_nvm_buffer);
|
||||
|
||||
// Reset force interval when ever values are stored
|
||||
entry->frame_cnt_store_force_timer = FRAME_COUNTER_STORE_FORCE_INTERVAL;
|
||||
|
@ -1737,23 +1739,23 @@ static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool
|
|||
|
||||
static int8_t ws_pae_controller_nvm_frame_counter_read(uint32_t *restart_cnt, uint64_t *stored_time, uint16_t *pan_version, frame_counters_t *counters)
|
||||
{
|
||||
nvm_tlv_t *tlv = ws_pae_nvm_store_generic_tlv_allocate_and_create(
|
||||
frame_cnt_nvm_tlv_t *tlv = (frame_cnt_nvm_tlv_t *) ws_pae_nvm_store_generic_tlv_allocate_and_create(
|
||||
PAE_NVM_FRAME_COUNTER_TAG, PAE_NVM_FRAME_COUNTER_LEN);
|
||||
if (!tlv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ws_pae_nvm_store_tlv_file_read(FRAME_COUNTER_FILE, tlv) < 0) {
|
||||
ws_pae_nvm_store_generic_tlv_free(tlv);
|
||||
if (ws_pae_nvm_store_tlv_file_read(FRAME_COUNTER_FILE, (nvm_tlv_t *) tlv) < 0) {
|
||||
ws_pae_nvm_store_generic_tlv_free((nvm_tlv_t *) tlv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ws_pae_nvm_store_frame_counter_tlv_read(tlv, restart_cnt, stored_time, pan_version, counters) < 0) {
|
||||
ws_pae_nvm_store_generic_tlv_free(tlv);
|
||||
ws_pae_nvm_store_generic_tlv_free((nvm_tlv_t *) tlv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ws_pae_nvm_store_generic_tlv_free(tlv);
|
||||
ws_pae_nvm_store_generic_tlv_free((nvm_tlv_t *) tlv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1798,9 +1800,9 @@ nvm_tlv_t *ws_pae_controller_nvm_tlv_get(protocol_interface_info_entry_t *interf
|
|||
return (nvm_tlv_t *) &controller->pae_nvm_buffer;
|
||||
}
|
||||
|
||||
static void ws_pae_controller_nvm_frame_counter_write(nvm_tlv_t *tlv_entry)
|
||||
static void ws_pae_controller_nvm_frame_counter_write(frame_cnt_nvm_tlv_t *tlv_entry)
|
||||
{
|
||||
ws_pae_nvm_store_tlv_file_write(FRAME_COUNTER_FILE, tlv_entry);
|
||||
ws_pae_nvm_store_tlv_file_write(FRAME_COUNTER_FILE, (nvm_tlv_t *) tlv_entry);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "ns_list.h"
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "randLIB.h"
|
||||
#include "fhss_config.h"
|
||||
#include "NWK_INTERFACE/Include/protocol.h"
|
||||
#include "6LoWPAN/ws/ws_config.h"
|
||||
|
@ -57,6 +58,9 @@
|
|||
/* Force key storage reference time update, if reference time differs more 31 days */
|
||||
#define KEY_STORAGE_REF_TIME_UPDATE_FORCE_THRESHOLD GTK_DEFAULT_LIFETIME + 86400
|
||||
|
||||
// Base scatter timer value, 3 seconds */
|
||||
#define KEY_STORAGE_SCATTER_TIMER_BASE_VALUE 30
|
||||
|
||||
typedef enum {
|
||||
WRITE_SET = 0,
|
||||
TIME_SET,
|
||||
|
@ -84,6 +88,7 @@ typedef struct {
|
|||
uint16_t free_entries; /**< Free entries in array */
|
||||
bool allocated : 1; /**< Allocated */
|
||||
bool modified : 1; /**< Array modified */
|
||||
bool pending_storing : 1; /**< Entry is pending storing to NVM */
|
||||
} key_storage_array_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -95,6 +100,7 @@ typedef struct {
|
|||
uint16_t store_timer_timeout; /**< Storing timing timeout */
|
||||
uint16_t store_timer; /**< Storing timer */
|
||||
uint32_t restart_cnt; /**< Re-start counter */
|
||||
uint32_t scatter_timer; /**< NVM storing scatter timer */
|
||||
} key_storage_params_t;
|
||||
|
||||
static key_storage_params_t key_storage_params;
|
||||
|
@ -107,7 +113,10 @@ static void ws_pae_key_storage_list_all_free(void);
|
|||
static sec_prot_keys_storage_t *ws_pae_key_storage_get(const void *instance, const uint8_t *eui64, key_storage_array_t **key_storage_array, bool return_free);
|
||||
static sec_prot_keys_storage_t *ws_pae_key_storage_replace(const void *instance, key_storage_array_t **key_storage_array);
|
||||
static void ws_pae_key_storage_trace(uint16_t field_set, sec_prot_keys_storage_t *key_storage, key_storage_array_t *key_storage_array);
|
||||
static void ws_pae_key_storage_scatter_timer_timeout(void);
|
||||
static void ws_pae_key_storage_fast_timer_start(void);
|
||||
static void ws_pae_key_storage_timer_expiry_set(void);
|
||||
static void ws_pae_key_storage_fast_timer_ticks_set(void);
|
||||
static int8_t ws_pae_key_storage_array_time_update_entry(uint64_t time_difference, sec_prot_keys_storage_t *storage_array_entry);
|
||||
static int8_t ws_pae_key_storage_array_time_check_and_update_all(key_storage_array_t *key_storage_array, bool modified);
|
||||
static int8_t ws_pae_key_storage_array_counters_check_and_update_all(key_storage_array_t *key_storage_array);
|
||||
|
@ -159,6 +168,7 @@ void ws_pae_key_storage_init(void)
|
|||
key_storage_params.replace_index = 0;
|
||||
key_storage_params.store_bitfield = 0,
|
||||
key_storage_params.restart_cnt = 0;
|
||||
key_storage_params.scatter_timer = 0;
|
||||
}
|
||||
|
||||
void ws_pae_key_storage_delete(void)
|
||||
|
@ -189,6 +199,7 @@ static int8_t ws_pae_key_storage_allocate(const void *instance, uint16_t key_sto
|
|||
key_storage_array->free_entries = key_storage_array->entries;
|
||||
key_storage_array->instance = instance;
|
||||
key_storage_array->modified = false;
|
||||
key_storage_array->pending_storing = false;
|
||||
|
||||
ws_pae_nvm_store_key_storage_tlv_create((nvm_tlv_t *) key_storage_array->storage_array_handle, key_storage_array->size);
|
||||
|
||||
|
@ -329,10 +340,13 @@ static sec_prot_keys_storage_t *ws_pae_key_storage_replace(const void *instance,
|
|||
key_storage_params.replace_index++;
|
||||
|
||||
tr_info("KeyS replace array: %p i: %i eui64: %s", (void *) entry->storage_array, replace_index, tr_array(storage_array[replace_index].ptk_eui_64, 8));
|
||||
break;
|
||||
}
|
||||
|
||||
// If replace index is not found it means that index has gone past the last entry
|
||||
if (storage_array == NULL) {
|
||||
tr_info("KeyS replace array first index");
|
||||
|
||||
/* Gets first key storage array and sets the array and sets index to zero and sets
|
||||
(next) replace index to first */
|
||||
key_storage_array_t *key_storage_array_entry = ns_list_get_first(&key_storage_array_list);
|
||||
|
@ -648,6 +662,7 @@ int8_t ws_pae_key_storage_store(void)
|
|||
{
|
||||
uint8_t entry_offset = 0;
|
||||
uint64_t store_bitfield = 0;
|
||||
bool start_scatter_timer = false;
|
||||
|
||||
ns_list_foreach(key_storage_array_t, entry, &key_storage_array_list) {
|
||||
// Bitfield is set for all entries (also that are non-modified in this write)
|
||||
|
@ -671,17 +686,20 @@ int8_t ws_pae_key_storage_store(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
char filename[KEY_STORAGE_FILE_LEN];
|
||||
ws_pae_key_storage_filename_set(filename, entry_offset);
|
||||
tr_info("KeyS write array: %p file: %s", (void *) entry->storage_array, filename);
|
||||
nvm_tlv_t *tlv = (nvm_tlv_t *) entry->storage_array_handle;
|
||||
ws_pae_nvm_store_tlv_file_write(filename, tlv);
|
||||
entry->pending_storing = true;
|
||||
start_scatter_timer = true;
|
||||
|
||||
// No longer pending for storing
|
||||
// Item is pending for storing, reset modified flag
|
||||
entry->modified = false;
|
||||
entry_offset++;
|
||||
}
|
||||
|
||||
tr_info("KeyS storage store, bitf: %"PRIx64, store_bitfield);
|
||||
|
||||
if (start_scatter_timer) {
|
||||
ws_pae_key_storage_fast_timer_start();
|
||||
}
|
||||
|
||||
if (key_storage_params.store_bitfield != store_bitfield) {
|
||||
key_storage_params.store_bitfield = store_bitfield;
|
||||
nvm_tlv_t *tlv = ws_pae_nvm_store_generic_tlv_allocate_and_create(
|
||||
|
@ -694,6 +712,38 @@ int8_t ws_pae_key_storage_store(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ws_pae_key_storage_scatter_timer_timeout(void)
|
||||
{
|
||||
uint8_t entry_offset = 0;
|
||||
bool pending_entry = false;
|
||||
|
||||
ns_list_foreach(key_storage_array_t, entry, &key_storage_array_list) {
|
||||
if (!entry->pending_storing) {
|
||||
entry_offset++;
|
||||
continue;
|
||||
}
|
||||
pending_entry = true;
|
||||
|
||||
char filename[KEY_STORAGE_FILE_LEN];
|
||||
ws_pae_key_storage_filename_set(filename, entry_offset);
|
||||
tr_info("KeyS write array: %p file: %s", (void *) entry->storage_array, filename);
|
||||
nvm_tlv_t *tlv = (nvm_tlv_t *) entry->storage_array_handle;
|
||||
ws_pae_nvm_store_tlv_file_write(filename, tlv);
|
||||
|
||||
// Item has been stored, reset pending storing and modified flag
|
||||
entry->pending_storing = false;
|
||||
entry->modified = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pending_entry) {
|
||||
ws_pae_key_storage_fast_timer_ticks_set();
|
||||
return;
|
||||
}
|
||||
|
||||
tr_info("KeyS all pending entries stored");
|
||||
}
|
||||
|
||||
void ws_pae_key_storage_read(uint32_t restart_cnt)
|
||||
{
|
||||
key_storage_params.store_bitfield = 0;
|
||||
|
@ -838,8 +888,30 @@ void ws_pae_key_storage_timer(uint16_t seconds)
|
|||
key_storage_params.store_timer = key_storage_params.store_timer_timeout;
|
||||
ws_pae_key_storage_store();
|
||||
}
|
||||
}
|
||||
|
||||
ws_pae_current_time_update(seconds);
|
||||
void ws_pae_key_storage_fast_timer(uint16_t ticks)
|
||||
{
|
||||
if (key_storage_params.scatter_timer == 0) {
|
||||
return;
|
||||
} else if (key_storage_params.scatter_timer > ticks) {
|
||||
key_storage_params.scatter_timer -= ticks;
|
||||
} else {
|
||||
key_storage_params.scatter_timer = 0;
|
||||
ws_pae_key_storage_scatter_timer_timeout();
|
||||
}
|
||||
}
|
||||
|
||||
static void ws_pae_key_storage_fast_timer_start(void)
|
||||
{
|
||||
ws_pae_key_storage_fast_timer_ticks_set();
|
||||
}
|
||||
|
||||
static void ws_pae_key_storage_fast_timer_ticks_set(void)
|
||||
{
|
||||
// (0.625 - 1,375) * 3 seconds
|
||||
key_storage_params.scatter_timer = randLIB_randomise_base(KEY_STORAGE_SCATTER_TIMER_BASE_VALUE, 0x5000, 0xB000);
|
||||
tr_info("KeyS scatter timer %"PRIi32, key_storage_params.scatter_timer);
|
||||
}
|
||||
|
||||
static void ws_pae_key_storage_timer_expiry_set(void)
|
||||
|
|
|
@ -153,6 +153,14 @@ bool ws_pae_key_storage_supp_delete(const void *instance, const uint8_t *eui64);
|
|||
*/
|
||||
void ws_pae_key_storage_timer(uint16_t seconds);
|
||||
|
||||
/**
|
||||
* ws_pae_key_storage_fast_timer key storage fast timers
|
||||
*
|
||||
* \param ticks Ticks passed
|
||||
*
|
||||
*/
|
||||
void ws_pae_key_storage_fast_timer(uint16_t ticks);
|
||||
|
||||
/**
|
||||
* ws_pae_key_storage_storing_interval_get gets key storage storing interval
|
||||
*
|
||||
|
|
|
@ -67,13 +67,13 @@ void ws_pae_nvm_store_generic_tlv_free(nvm_tlv_t *tlv_entry)
|
|||
ns_dyn_mem_free(tlv_entry);
|
||||
}
|
||||
|
||||
void ws_pae_nvm_store_nw_info_tlv_create(nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks)
|
||||
void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks)
|
||||
{
|
||||
int len;
|
||||
tlv_entry->tag = PAE_NVM_NW_INFO_TAG;
|
||||
tlv_entry->len = PAE_NVM_NW_INFO_LEN;
|
||||
|
||||
uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN;
|
||||
uint8_t *tlv = (uint8_t *) &tlv_entry->data[0];
|
||||
|
||||
tlv = common_write_16_bit(pan_id, tlv);
|
||||
|
||||
|
@ -119,7 +119,7 @@ void ws_pae_nvm_store_nw_info_tlv_create(nvm_tlv_t *tlv_entry, uint16_t pan_id,
|
|||
|
||||
}
|
||||
|
||||
int8_t ws_pae_nvm_store_nw_info_tlv_read(nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks)
|
||||
int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks)
|
||||
{
|
||||
if (!tlv_entry || !pan_id || !nw_name) {
|
||||
return -1;
|
||||
|
@ -129,7 +129,7 @@ int8_t ws_pae_nvm_store_nw_info_tlv_read(nvm_tlv_t *tlv_entry, uint16_t *pan_id,
|
|||
return -1;
|
||||
}
|
||||
|
||||
uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN;
|
||||
uint8_t *tlv = (uint8_t *) &tlv_entry->data[0];
|
||||
|
||||
if (*pan_id == 0xffff) {
|
||||
// If application has not set pan_id read it from NVM
|
||||
|
@ -184,12 +184,12 @@ int8_t ws_pae_nvm_store_nw_info_tlv_read(nvm_tlv_t *tlv_entry, uint16_t *pan_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ws_pae_nvm_store_keys_tlv_create(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec_keys)
|
||||
void ws_pae_nvm_store_keys_tlv_create(keys_nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec_keys)
|
||||
{
|
||||
tlv_entry->tag = PAE_NVM_KEYS_TAG;
|
||||
tlv_entry->len = PAE_NVM_KEYS_LEN;
|
||||
|
||||
uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN;
|
||||
uint8_t *tlv = (uint8_t *) &tlv_entry->data[0];
|
||||
|
||||
uint8_t *eui_64 = sec_prot_keys_ptk_eui_64_get(sec_keys);
|
||||
if (eui_64) {
|
||||
|
@ -231,7 +231,7 @@ void ws_pae_nvm_store_keys_tlv_create(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec
|
|||
tr_debug("NVM KEYS write");
|
||||
}
|
||||
|
||||
int8_t ws_pae_nvm_store_keys_tlv_read(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec_keys)
|
||||
int8_t ws_pae_nvm_store_keys_tlv_read(keys_nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec_keys)
|
||||
{
|
||||
if (!tlv_entry || !sec_keys) {
|
||||
return -1;
|
||||
|
@ -241,7 +241,7 @@ int8_t ws_pae_nvm_store_keys_tlv_read(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec
|
|||
return -1;
|
||||
}
|
||||
|
||||
uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN;
|
||||
uint8_t *tlv = (uint8_t *) &tlv_entry->data[0];
|
||||
|
||||
// EUI-64 set */
|
||||
if (*tlv++ == PAE_NVM_FIELD_SET) {
|
||||
|
@ -281,12 +281,12 @@ int8_t ws_pae_nvm_store_keys_tlv_read(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ws_pae_nvm_store_frame_counter_tlv_create(nvm_tlv_t *tlv_entry, uint32_t restart_cnt, uint16_t pan_version, frame_counters_t *counters)
|
||||
void ws_pae_nvm_store_frame_counter_tlv_create(frame_cnt_nvm_tlv_t *tlv_entry, uint32_t restart_cnt, uint16_t pan_version, frame_counters_t *counters)
|
||||
{
|
||||
tlv_entry->tag = PAE_NVM_FRAME_COUNTER_TAG;
|
||||
tlv_entry->len = PAE_NVM_FRAME_COUNTER_LEN;
|
||||
|
||||
uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN;
|
||||
uint8_t *tlv = (uint8_t *) &tlv_entry->data[0];
|
||||
|
||||
tlv = common_write_32_bit(restart_cnt, tlv);
|
||||
|
||||
|
@ -311,7 +311,7 @@ void ws_pae_nvm_store_frame_counter_tlv_create(nvm_tlv_t *tlv_entry, uint32_t re
|
|||
tr_debug("NVM FRAME COUNTER write");
|
||||
}
|
||||
|
||||
int8_t ws_pae_nvm_store_frame_counter_tlv_read(nvm_tlv_t *tlv_entry, uint32_t *restart_cnt, uint64_t *stored_time, uint16_t *pan_version, frame_counters_t *counters)
|
||||
int8_t ws_pae_nvm_store_frame_counter_tlv_read(frame_cnt_nvm_tlv_t *tlv_entry, uint32_t *restart_cnt, uint64_t *stored_time, uint16_t *pan_version, frame_counters_t *counters)
|
||||
{
|
||||
if (!tlv_entry || !counters) {
|
||||
return -1;
|
||||
|
@ -321,7 +321,7 @@ int8_t ws_pae_nvm_store_frame_counter_tlv_read(nvm_tlv_t *tlv_entry, uint32_t *r
|
|||
return -1;
|
||||
}
|
||||
|
||||
uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN;
|
||||
uint8_t *tlv = (uint8_t *) &tlv_entry->data[0];
|
||||
|
||||
*restart_cnt = common_read_32_bit(tlv);
|
||||
tlv += 4;
|
||||
|
|
|
@ -49,6 +49,24 @@
|
|||
// key storage index bitfield (8)
|
||||
#define PAE_NVM_KEY_STORAGE_INDEX_LEN 8
|
||||
|
||||
typedef struct nw_info_nvm_tlv {
|
||||
uint16_t tag; /**< Unique tag */
|
||||
uint16_t len; /**< Number of the bytes after the length field */
|
||||
uint8_t data[PAE_NVM_NW_INFO_LEN]; /**< Data */
|
||||
} nw_info_nvm_tlv_t;
|
||||
|
||||
typedef struct keys_nvm_tlv {
|
||||
uint16_t tag; /**< Unique tag */
|
||||
uint16_t len; /**< Number of the bytes after the length field */
|
||||
uint8_t data[PAE_NVM_KEYS_LEN]; /**< Data */
|
||||
} keys_nvm_tlv_t;
|
||||
|
||||
typedef struct frame_cnt_nvm_tlv {
|
||||
uint16_t tag; /**< Unique tag */
|
||||
uint16_t len; /**< Number of the bytes after the length field */
|
||||
uint8_t data[PAE_NVM_FRAME_COUNTER_LEN]; /**< Data */
|
||||
} frame_cnt_nvm_tlv_t;
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_generic_tlv_create create NVM generic storage TLV
|
||||
*
|
||||
|
@ -77,7 +95,7 @@ void ws_pae_nvm_store_generic_tlv_free(nvm_tlv_t *tlv_entry);
|
|||
* \return TLV entry or NULL
|
||||
*
|
||||
*/
|
||||
void ws_pae_nvm_store_nw_info_tlv_create(nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks);
|
||||
void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_nw_info_tlv_read read from NVM network info TLV
|
||||
|
@ -91,7 +109,7 @@ void ws_pae_nvm_store_nw_info_tlv_create(nvm_tlv_t *tlv_entry, uint16_t pan_id,
|
|||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_nvm_store_nw_info_tlv_read(nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks);
|
||||
int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_keys_tlv_create create NVM keys TLV
|
||||
|
@ -100,7 +118,7 @@ int8_t ws_pae_nvm_store_nw_info_tlv_read(nvm_tlv_t *tlv_entry, uint16_t *pan_id,
|
|||
* \param sec_keys security keys
|
||||
*
|
||||
*/
|
||||
void ws_pae_nvm_store_keys_tlv_create(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec_keys);
|
||||
void ws_pae_nvm_store_keys_tlv_create(keys_nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec_keys);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_nw_info_tlv_read read from NVM keys TLV
|
||||
|
@ -112,7 +130,7 @@ void ws_pae_nvm_store_keys_tlv_create(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec
|
|||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_nvm_store_keys_tlv_read(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec_keys);
|
||||
int8_t ws_pae_nvm_store_keys_tlv_read(keys_nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec_keys);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_frame_counter_tlv_create create NVM frame counter TLV
|
||||
|
@ -123,7 +141,7 @@ int8_t ws_pae_nvm_store_keys_tlv_read(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec
|
|||
* \param counters frame counters
|
||||
*
|
||||
*/
|
||||
void ws_pae_nvm_store_frame_counter_tlv_create(nvm_tlv_t *tlv_entry, uint32_t restart_cnt, uint16_t pan_version, frame_counters_t *counters);
|
||||
void ws_pae_nvm_store_frame_counter_tlv_create(frame_cnt_nvm_tlv_t *tlv_entry, uint32_t restart_cnt, uint16_t pan_version, frame_counters_t *counters);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_frame_counter_tlv_read read from NVM frame counter TLV
|
||||
|
@ -138,7 +156,7 @@ void ws_pae_nvm_store_frame_counter_tlv_create(nvm_tlv_t *tlv_entry, uint32_t re
|
|||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_nvm_store_frame_counter_tlv_read(nvm_tlv_t *tlv_entry, uint32_t *restart_cnt, uint64_t *stored_time, uint16_t *pan_version, frame_counters_t *counters);
|
||||
int8_t ws_pae_nvm_store_frame_counter_tlv_read(frame_cnt_nvm_tlv_t *tlv_entry, uint32_t *restart_cnt, uint64_t *stored_time, uint16_t *pan_version, frame_counters_t *counters);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_key_storage_index_tlv_create create NVM key storage index TLV
|
||||
|
|
|
@ -40,8 +40,8 @@ typedef struct nvm_tlv {
|
|||
|
||||
typedef struct {
|
||||
nvm_tlv_t nvm_tlv; /**< NVM TLV */
|
||||
uint64_t reference_time; /**< Reference time used for timers (set when file is created) */
|
||||
uint32_t reference_restart_cnt; /**< Reference re-start counter set when file is created) */
|
||||
uint64_t reference_time; /**< Reference time used for timers (set when file is created) */
|
||||
} key_storage_nvm_tlv_entry_t;
|
||||
|
||||
// tag + length
|
||||
|
|
|
@ -415,25 +415,25 @@ static void ws_pae_supp_nvm_update(pae_supp_t *pae_supp)
|
|||
|
||||
static int8_t ws_pae_supp_nvm_keys_write(pae_supp_t *pae_supp)
|
||||
{
|
||||
nvm_tlv_t *tlv = ws_pae_controller_nvm_tlv_get(pae_supp->interface_ptr);
|
||||
keys_nvm_tlv_t *tlv = (keys_nvm_tlv_t *) ws_pae_controller_nvm_tlv_get(pae_supp->interface_ptr);
|
||||
if (!tlv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ws_pae_nvm_store_keys_tlv_create(tlv, &pae_supp->entry.sec_keys);
|
||||
ws_pae_nvm_store_tlv_file_write(KEYS_FILE, tlv);
|
||||
ws_pae_nvm_store_tlv_file_write(KEYS_FILE, (nvm_tlv_t *) tlv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int8_t ws_pae_supp_nvm_keys_read(pae_supp_t *pae_supp)
|
||||
{
|
||||
nvm_tlv_t *tlv = ws_pae_controller_nvm_tlv_get(pae_supp->interface_ptr);
|
||||
keys_nvm_tlv_t *tlv = (keys_nvm_tlv_t *) ws_pae_controller_nvm_tlv_get(pae_supp->interface_ptr);
|
||||
if (!tlv) {
|
||||
return -1;
|
||||
}
|
||||
ws_pae_nvm_store_generic_tlv_create(tlv, PAE_NVM_KEYS_TAG, PAE_NVM_KEYS_LEN);
|
||||
if (ws_pae_nvm_store_tlv_file_read(KEYS_FILE_NAME, tlv) < 0) {
|
||||
ws_pae_nvm_store_generic_tlv_create((nvm_tlv_t *) tlv, PAE_NVM_KEYS_TAG, PAE_NVM_KEYS_LEN);
|
||||
if (ws_pae_nvm_store_tlv_file_read(KEYS_FILE_NAME, (nvm_tlv_t *) tlv) < 0) {
|
||||
return -1;
|
||||
}
|
||||
ws_pae_nvm_store_keys_tlv_read(tlv, &pae_supp->entry.sec_keys);
|
||||
|
|
|
@ -33,9 +33,6 @@
|
|||
// Wednesday, January 1, 2020 0:00:00 GMT
|
||||
#define CURRENT_TIME_INIT_VALUE 1577836800
|
||||
|
||||
// Increment two hours in addition to maximum storing interval
|
||||
#define CURRENT_TIME_INCREMENT_VALUE (2 * 3600)
|
||||
|
||||
static uint64_t current_time = CURRENT_TIME_INIT_VALUE;
|
||||
static ns_time_api_system_time_callback *system_time_callback = NULL;
|
||||
|
||||
|
@ -167,6 +164,8 @@ int8_t ws_pae_current_time_set(uint64_t time)
|
|||
{
|
||||
current_time = time;
|
||||
|
||||
tr_debug("Current time set: %"PRIi64, time);
|
||||
|
||||
if (system_time_callback) {
|
||||
uint64_t system_time = system_time_callback();
|
||||
// System time has gone backwards
|
||||
|
@ -174,8 +173,6 @@ int8_t ws_pae_current_time_set(uint64_t time)
|
|||
tr_error("FATAL: system time less than reference time or more than 12 months in future: %"PRIi64" reference time: %"PRIi64, system_time, current_time);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
current_time += FRAME_COUNTER_STORE_FORCE_INTERVAL + CURRENT_TIME_INCREMENT_VALUE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -886,6 +886,11 @@ static buffer_t *icmpv6_ra_handler(buffer_t *buf)
|
|||
uint8_t dns_search_list_len = length - 8; // Length includes type and length
|
||||
//Cut Padding
|
||||
dns_search_list_len = icmpv6_dns_search_list_remove_pad(dns_search_list, dns_search_list_len);
|
||||
|
||||
// validate lifetime to be at least same amount as default route lifetime
|
||||
if (dns_lifetime > 0 && dns_lifetime < router_lifetime) {
|
||||
dns_lifetime = router_lifetime;
|
||||
}
|
||||
//tr_info("DNS Search List: %s Lifetime: %lu", trace_array(dns_search_list, dns_search_list_len), (unsigned long) dns_lifetime);
|
||||
// Add DNS server to DNS information storage.
|
||||
net_dns_server_search_list_set(cur->id, buf->src_sa.address, dns_search_list, dns_search_list_len, dns_lifetime);
|
||||
|
@ -899,6 +904,12 @@ static buffer_t *icmpv6_ra_handler(buffer_t *buf)
|
|||
}
|
||||
uint8_t dns_count = (dns_length - 1) / 2;
|
||||
uint32_t dns_lifetime = common_read_32_bit(dptr + 2); // 2 x reserved
|
||||
|
||||
// validate lifetime to be at least same amount as default route lifetime
|
||||
if (dns_lifetime > 0 && dns_lifetime < router_lifetime) {
|
||||
dns_lifetime = router_lifetime;
|
||||
}
|
||||
|
||||
for (int n = 0; n < dns_count; n++) {
|
||||
uint8_t *dns_srv_addr = dptr + 6 + n * 16;
|
||||
//tr_info("DNS Server: %s Lifetime: %lu", trace_ipv6(dns_srv_addr), (unsigned long) dns_lifetime);
|
||||
|
|
|
@ -1183,15 +1183,24 @@ static void mac_pd_data_confirm_failure_handle(protocol_interface_rf_mac_setup_s
|
|||
mcps_data_confirm_cb(rf_mac_setup, &mcps_data_conf, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void mac_pd_data_ack_handler(mac_pre_parsed_frame_t *buf)
|
||||
{
|
||||
protocol_interface_rf_mac_setup_s *rf_mac_setup = buf->mac_class_ptr;
|
||||
|
||||
if (!rf_mac_setup->active_pd_data_request) {
|
||||
mcps_sap_pre_parsed_frame_buffer_free(buf);
|
||||
tr_debug("RX ack without active buffer");
|
||||
} else {
|
||||
mac_pre_build_frame_t *buffer = rf_mac_setup->active_pd_data_request;
|
||||
|
||||
//Validate here ack is proper to active buffer
|
||||
if (!mac_pd_sap_ack_validation(rf_mac_setup, &buf->fcf_dsn, mac_header_message_start_pointer(buf))) {
|
||||
tr_debug("Not a valid ACK for active tx process");
|
||||
mcps_sap_pre_parsed_frame_buffer_free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mac_ack_sap_rx_handler(buf, rf_mac_setup)) {
|
||||
//Do not forward ACK payload but Accept ACK
|
||||
mcps_sap_pre_parsed_frame_buffer_free(buf);
|
||||
|
|
|
@ -655,12 +655,16 @@ static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_set
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool mac_pd_sap_ack_validation(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_dsn, const uint8_t *data_ptr)
|
||||
bool mac_pd_sap_ack_validation(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_dsn, const uint8_t *data_ptr)
|
||||
{
|
||||
if (!rf_ptr->active_pd_data_request || !rf_ptr->active_pd_data_request->fcf_dsn.ackRequested) {
|
||||
if (!rf_ptr->active_pd_data_request || (!rf_ptr->active_pd_data_request->fcf_dsn.ackRequested && !rf_ptr->active_pd_data_request->ExtendedFrameExchange)) {
|
||||
return false; //No active Data request anymore or no ACK request for current TX
|
||||
}
|
||||
|
||||
if (rf_ptr->active_pd_data_request->ExtendedFrameExchange && fcf_dsn->frametype == FC_DATA_FRAME) {
|
||||
return true;//EFDE final message
|
||||
}
|
||||
|
||||
if (fcf_dsn->frameVersion != rf_ptr->active_pd_data_request->fcf_dsn.frameVersion) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
struct protocol_interface_rf_mac_setup;
|
||||
struct arm_phy_sap_msg_s;
|
||||
struct mac_fcf_sequence_s;
|
||||
|
||||
#define ENHANCED_ACK_NEIGHBOUR_POLL_MAX_TIME_US 3500
|
||||
|
||||
|
@ -61,4 +62,6 @@ void mac_pd_sap_state_machine(struct protocol_interface_rf_mac_setup *rf_mac_set
|
|||
|
||||
int8_t mac_data_edfe_force_stop(struct protocol_interface_rf_mac_setup *rf_ptr);
|
||||
|
||||
bool mac_pd_sap_ack_validation(struct protocol_interface_rf_mac_setup *rf_ptr, const struct mac_fcf_sequence_s *fcf_dsn, const uint8_t *data_ptr);
|
||||
|
||||
#endif /* MAC_PD_SAP_H_ */
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#define MPL_SEED_64_BIT 2
|
||||
#define MPL_SEED_128_BIT 3
|
||||
|
||||
#define MAX_BUFFERED_MESSAGES_SIZE 2048
|
||||
#define MAX_BUFFERED_MESSAGES_SIZE 8192
|
||||
#define MAX_BUFFERED_MESSAGE_LIFETIME 600 // 1/10 s ticks
|
||||
|
||||
static bool mpl_timer_running;
|
||||
|
|
|
@ -82,6 +82,7 @@ static int fhss_ws_manage_channel_table_allocation(fhss_structure_t *fhss_struct
|
|||
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots);
|
||||
static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure);
|
||||
static void fhss_unicast_handler(const fhss_api_t *fhss_api, uint16_t delay);
|
||||
static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay);
|
||||
static bool fhss_ws_check_tx_allowed(fhss_structure_t *fhss_structure);
|
||||
static int32_t fhss_channel_index_from_mask(const uint32_t *channel_mask, int32_t channel_index, uint16_t number_of_channels);
|
||||
|
||||
|
@ -114,6 +115,11 @@ void fhss_ws_start_timer(fhss_structure_t *fhss_structure, uint32_t time, void (
|
|||
// Reduce the compensation (per millisecond) from timeout.
|
||||
time -= NS_TO_US(time_in_ms * fhss_structure->ws->drift_per_millisecond_ns);
|
||||
fhss_start_timer(fhss_structure, time, callback);
|
||||
if (callback == fhss_unicast_handler) {
|
||||
fhss_structure->ws->next_uc_timeout = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api) + time;
|
||||
} else if (callback == fhss_broadcast_handler) {
|
||||
fhss_structure->ws->next_bc_timeout = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api) + time;
|
||||
}
|
||||
}
|
||||
|
||||
fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer)
|
||||
|
@ -285,6 +291,7 @@ static int32_t fhss_channel_index_from_mask(const uint32_t *channel_mask, int32_
|
|||
|
||||
static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
|
||||
{
|
||||
(void) delay;
|
||||
int32_t next_channel;
|
||||
fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api);
|
||||
if (!fhss_structure) {
|
||||
|
@ -298,8 +305,44 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
|
|||
fhss_structure->ws->broadcast_timer_running = false;
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t delay_us = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api) - fhss_structure->ws->next_bc_timeout;
|
||||
// Assume this was initial call for this function without timer
|
||||
if (!fhss_structure->ws->bc_slot && !fhss_structure->ws->next_bc_timeout) {
|
||||
delay_us = 0;
|
||||
}
|
||||
|
||||
if (fhss_structure->ws->is_on_bc_channel == false) {
|
||||
fhss_ws_start_timer(fhss_structure, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) - (delay * fhss_structure->platform_functions.fhss_resolution_divider), fhss_broadcast_handler);
|
||||
// If callback was delayed longer than broadcast interval, BC slot must be updated
|
||||
fhss_structure->ws->bc_slot += (US_TO_MS(delay_us) + (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval)) / fhss_structure->ws->fhss_configuration.fhss_broadcast_interval;
|
||||
// We weren't on broadcast channel. Check if after delayed interrupt we still shouldn't go to broadcast channel. Setting is_on_bc_channel to true forces to skip BC dwell interval next.
|
||||
if ((US_TO_MS(delay_us) % fhss_structure->ws->fhss_configuration.fhss_broadcast_interval) > fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) {
|
||||
fhss_structure->ws->is_on_bc_channel = true;
|
||||
// If delay + assumed timeout is longer than broadcast interval, delay value must be computed differently to make compensation work properly
|
||||
if (US_TO_MS(delay_us) + (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) > fhss_structure->ws->fhss_configuration.fhss_broadcast_interval) {
|
||||
delay_us = (MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) + delay_us) % MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval);
|
||||
}
|
||||
} else {
|
||||
if (US_TO_MS(delay_us) + (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) > fhss_structure->ws->fhss_configuration.fhss_broadcast_interval) {
|
||||
delay_us = ((MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) + delay_us) % MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval)) - MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If callback was delayed longer than broadcast interval, BC slot must be updated
|
||||
fhss_structure->ws->bc_slot += (US_TO_MS(delay_us) + fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) / fhss_structure->ws->fhss_configuration.fhss_broadcast_interval;
|
||||
// We were on broadcast channel. Check if after delayed interrupt we should go broadcast channel again. Setting is_on_bc_channel to false forces to start BC dwell interval next.
|
||||
if ((US_TO_MS(delay_us) % fhss_structure->ws->fhss_configuration.fhss_broadcast_interval) > (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval)) {
|
||||
fhss_structure->ws->is_on_bc_channel = false;
|
||||
}
|
||||
delay_us %= MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval);
|
||||
}
|
||||
|
||||
if (fhss_structure->ws->fhss_configuration.ws_bc_channel_function == WS_TR51CF) {
|
||||
fhss_structure->ws->bc_slot %= fhss_structure->number_of_channels;
|
||||
}
|
||||
|
||||
if (fhss_structure->ws->is_on_bc_channel == false) {
|
||||
fhss_ws_start_timer(fhss_structure, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) - (delay_us * fhss_structure->platform_functions.fhss_resolution_divider), fhss_broadcast_handler);
|
||||
fhss_structure->ws->is_on_bc_channel = true;
|
||||
next_channel = fhss_structure->ws->bc_channel = fhss_ws_calc_bc_channel(fhss_structure);
|
||||
|
||||
|
@ -315,7 +358,7 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
|
|||
} else {
|
||||
fhss_structure->ws->unicast_start_time_us = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api);
|
||||
uint32_t timeout = MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval);
|
||||
fhss_ws_start_timer(fhss_structure, timeout - (delay * fhss_structure->platform_functions.fhss_resolution_divider), fhss_broadcast_handler);
|
||||
fhss_ws_start_timer(fhss_structure, timeout - (delay_us * fhss_structure->platform_functions.fhss_resolution_divider), fhss_broadcast_handler);
|
||||
fhss_structure->ws->is_on_bc_channel = false;
|
||||
// Should return to own (unicast) listening channel after broadcast channel
|
||||
next_channel = fhss_structure->rx_channel;
|
||||
|
@ -413,9 +456,11 @@ static uint32_t fhss_ws_calculate_ufsi(fhss_structure_t *fhss_structure, uint32_
|
|||
{
|
||||
uint8_t dwell_time = fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval;
|
||||
uint16_t cur_slot = fhss_structure->ws->uc_slot;
|
||||
if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_TR51CF) {
|
||||
if (cur_slot == 0) {
|
||||
cur_slot = fhss_structure->number_of_uc_channels;
|
||||
}
|
||||
}
|
||||
cur_slot--;
|
||||
uint32_t remaining_time_ms = 0;
|
||||
if (fhss_structure->ws->unicast_timer_running == true) {
|
||||
|
@ -497,6 +542,8 @@ static int16_t fhss_ws_synch_state_set_callback(const fhss_api_t *api, fhss_stat
|
|||
fhss_stop_timer(fhss_structure, fhss_unicast_handler);
|
||||
fhss_stop_timer(fhss_structure, fhss_broadcast_handler);
|
||||
fhss_structure->ws->broadcast_timer_running = false;
|
||||
fhss_structure->ws->is_on_bc_channel = false;
|
||||
fhss_structure->ws->synchronization_time = 0;
|
||||
}
|
||||
|
||||
fhss_structure->fhss_state = fhss_state;
|
||||
|
@ -570,15 +617,11 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
|
|||
}
|
||||
if (fhss_structure->fhss_state == FHSS_SYNCHRONIZED) {
|
||||
fhss_ws_neighbor_timing_info_t *neighbor_timing_info = fhss_structure->ws->get_neighbor_info(api, destination_address);
|
||||
if (!neighbor_timing_info) {
|
||||
if (!neighbor_timing_info || neighbor_timing_info->uc_timing_info.unicast_number_of_channels == 0) {
|
||||
fhss_stats_update(fhss_structure, STATS_FHSS_UNKNOWN_NEIGHBOR, 1);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (neighbor_timing_info->uc_timing_info.unicast_number_of_channels == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t destination_slot = fhss_ws_calculate_destination_slot(neighbor_timing_info, tx_time);
|
||||
int32_t tx_channel = neighbor_timing_info->uc_timing_info.fixed_channel;
|
||||
if (neighbor_timing_info->uc_timing_info.unicast_channel_function == WS_TR51CF) {
|
||||
|
@ -896,18 +939,34 @@ static uint32_t fhss_ws_get_retry_period_callback(const fhss_api_t *api, uint8_t
|
|||
|
||||
static void fhss_unicast_handler(const fhss_api_t *fhss_api, uint16_t delay)
|
||||
{
|
||||
(void) delay;
|
||||
uint32_t timeout = 0;
|
||||
fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api);
|
||||
if (!fhss_structure) {
|
||||
return;
|
||||
}
|
||||
int32_t delay_us = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api) - fhss_structure->ws->next_uc_timeout;
|
||||
if (!fhss_structure->ws->uc_slot && !fhss_structure->ws->next_uc_timeout) {
|
||||
delay_us = 0;
|
||||
}
|
||||
|
||||
// If callback was delayed longer than dwell time, UC slot must be updated
|
||||
if ((fhss_structure->ws->fhss_configuration.ws_uc_channel_function != WS_FIXED_CHANNEL)) {
|
||||
fhss_structure->ws->uc_slot += US_TO_MS(delay_us) / fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval;
|
||||
if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_TR51CF) {
|
||||
fhss_structure->ws->uc_slot %= fhss_structure->number_of_uc_channels;
|
||||
}
|
||||
}
|
||||
delay_us %= MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval);
|
||||
|
||||
|
||||
timeout = fhss_ws_get_sf_timeout_callback(fhss_structure);
|
||||
if (!timeout) {
|
||||
fhss_stop_timer(fhss_structure, fhss_unicast_handler);
|
||||
fhss_structure->ws->unicast_timer_running = false;
|
||||
return;
|
||||
}
|
||||
fhss_ws_start_timer(fhss_structure, timeout - (delay * fhss_structure->platform_functions.fhss_resolution_divider), fhss_unicast_handler);
|
||||
fhss_ws_start_timer(fhss_structure, timeout - (delay_us * fhss_structure->platform_functions.fhss_resolution_divider), fhss_unicast_handler);
|
||||
fhss_structure->ws->unicast_timer_running = true;
|
||||
fhss_ws_update_uc_channel_callback(fhss_structure);
|
||||
// Unless we have broadcast schedule, we have to poll unicast queue when changing channel. This is randomized by the unicast schedule.
|
||||
|
|
|
@ -40,6 +40,8 @@ struct fhss_ws {
|
|||
int32_t drift_per_millisecond_ns;
|
||||
int16_t *tr51_channel_table;
|
||||
uint8_t *tr51_output_table;
|
||||
uint32_t next_uc_timeout;
|
||||
uint32_t next_bc_timeout;
|
||||
bool unicast_timer_running;
|
||||
bool broadcast_timer_running;
|
||||
bool is_on_bc_channel;
|
||||
|
|
Loading…
Reference in New Issue