Merge commit '4098b26c4477b6ed8929e71c571b8fb13195582a' into feature-wisun

* commit '4098b26c4477b6ed8929e71c571b8fb13195582a':
  Squashed 'features/nanostack/sal-stack-nanostack/' changes from 7e3b99c375..09d9e24f2d
pull/13716/head
Arto Kinnunen 2020-10-05 13:59:55 +03:00
commit c1c9ba5c6a
22 changed files with 398 additions and 109 deletions

View File

@ -97,6 +97,7 @@ int ws_bbr_start(int8_t interface_id, int8_t backbone_interface_id);
#define BBR_BB_WAIT 0x0004 /**< Wait backbone availability before starting Wi-SUN network */
#define BBR_DEFAULT_ROUTE 0x0008 /**< Add default route parameter to DIO */
#define BBR_REQUIRE_DAO_REFRESH 0x0010 /**< Do not increment PAN version number when active forces DAO update from nodes*/
#define BBR_GUA_SLAAC 0x0020 /**< in Global prefix use SLAAC address generation to reduce traffic during bootstrap */
/**
* Configure border router features.

View File

@ -492,6 +492,8 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
uint8_t local_prefix[8] = {0};
uint8_t global_prefix[8] = {0};
uint8_t prefix_flags = 0;
uint32_t prefix_lifetime = 0;
//tr_info("BBR status check");
@ -596,7 +598,6 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
}
// TODO add global prefix
if (memcmp(global_prefix, ADDR_UNSPECIFIED, 8) != 0) {
tr_info("RPL global prefix activate %s", trace_ipv6_prefix(global_prefix, 64));
// Add default route to RPL
// Enable default routing to backbone
@ -606,8 +607,12 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
return;
}
}
if (configuration & BBR_GUA_SLAAC) {
prefix_flags |= PIO_A;
prefix_lifetime = WS_ULA_LIFETIME;
}
ws_bbr_dhcp_server_start(cur, global_prefix, cur->ws_info->cfg->bbr.dhcp_address_lifetime);
rpl_control_update_dodag_prefix(protocol_6lowpan_rpl_root_dodag, global_prefix, 64, 0, 0, 0, false);
rpl_control_update_dodag_prefix(protocol_6lowpan_rpl_root_dodag, global_prefix, 64, prefix_flags, prefix_lifetime, prefix_lifetime, false);
// no check for failure should have
if (configuration & BBR_GUA_ROUTE) {
@ -626,7 +631,11 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
* There is no status checks on prefix adds so this makes sure they are not lost
* DHCP validation should be done also
*/
rpl_control_update_dodag_prefix(protocol_6lowpan_rpl_root_dodag, current_global_prefix, 64, 0, 0, 0, false);
if (configuration & BBR_GUA_SLAAC) {
prefix_flags |= PIO_A;
prefix_lifetime = WS_ULA_LIFETIME;
}
rpl_control_update_dodag_prefix(protocol_6lowpan_rpl_root_dodag, current_global_prefix, 64, prefix_flags, prefix_lifetime, prefix_lifetime, false);
if (configuration & BBR_GUA_ROUTE) {
// Add also global prefix and route to RPL

View File

@ -110,6 +110,7 @@ static int8_t ws_bootstrap_neighbor_set(protocol_interface_info_entry_t *cur, pa
static void ws_bootstrap_candidate_table_reset(protocol_interface_info_entry_t *cur);
static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interface_info_entry *cur, const uint8_t *addr, bool create);
static void ws_bootstrap_candidate_parent_sort(struct protocol_interface_info_entry *cur, parent_info_t *new_entry);
typedef enum {
WS_PARENT_SOFT_SYNCH = 0, /**< let FHSS make decision if synchronization is needed*/
@ -289,6 +290,20 @@ static void ws_bootstrap_address_notification_cb(struct protocol_interface_info_
}
}
static void ws_bootstrap_configure_max_retries(protocol_interface_info_entry_t *cur, uint8_t max_mac_retries, uint8_t max_channel_retries)
{
mac_helper_mac_mlme_max_retry_set(cur->id, max_mac_retries);
const fhss_ws_configuration_t *fhss_configuration_cur = ns_fhss_ws_configuration_get(cur->ws_info->fhss_api);
if (fhss_configuration_cur && fhss_configuration_cur->config_parameters.number_of_channel_retries != max_channel_retries) {
fhss_ws_configuration_t fhss_configuration;
memset(&fhss_configuration, 0, sizeof(fhss_ws_configuration_t));
memcpy(&fhss_configuration, ns_fhss_ws_configuration_get(cur->ws_info->fhss_api), sizeof(fhss_ws_configuration_t));
fhss_configuration.config_parameters.number_of_channel_retries = max_channel_retries;
ns_fhss_ws_configuration_set(cur->ws_info->fhss_api, &fhss_configuration);
}
}
static int ws_bootstrap_tasklet_init(protocol_interface_info_entry_t *cur)
{
if (cur->bootStrapId < 0) {
@ -601,7 +616,6 @@ static int8_t ws_fhss_initialize(protocol_interface_info_entry_t *cur)
fhss_configuration.ws_bc_channel_function = (fhss_ws_channel_functions)cur->ws_info->cfg->fhss.fhss_bc_channel_function;
fhss_configuration.fhss_bc_dwell_interval = cur->ws_info->cfg->fhss.fhss_bc_dwell_interval;
fhss_configuration.fhss_broadcast_interval = cur->ws_info->cfg->fhss.fhss_bc_interval;
fhss_configuration.config_parameters.number_of_channel_retries = WS_NUMBER_OF_CHANNEL_RETRIES;
fhss_api = ns_fhss_ws_create(&fhss_configuration, cur->ws_info->fhss_timer_ptr);
if (!fhss_api) {
@ -765,7 +779,7 @@ static void ws_bootstrap_primary_parent_set(struct protocol_interface_info_entry
void ws_bootstrap_eapol_parent_synch(struct protocol_interface_info_entry *cur, llc_neighbour_req_t *neighbor_info)
{
if (cur->ws_info->configuration_learned || !neighbor_info->ws_neighbor->broadcast_shedule_info_stored || !neighbor_info->ws_neighbor->broadcast_timing_info_stored) {
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER || cur->ws_info->configuration_learned || !neighbor_info->ws_neighbor->broadcast_shedule_info_stored || !neighbor_info->ws_neighbor->broadcast_timing_info_stored) {
return;
}
@ -820,6 +834,7 @@ static void ws_bootstrap_ll_address_validate(struct protocol_interface_info_entr
*/
uint16_t ws_etx_read(protocol_interface_info_entry_t *interface, addrtype_t addr_type, const uint8_t *addr_ptr)
{
uint16_t etx;
if (!addr_ptr || !interface) {
return 0;
@ -839,7 +854,16 @@ uint16_t ws_etx_read(protocol_interface_info_entry_t *interface, addrtype_t addr
return 0xffff;
}
return etx_local_etx_read(interface->id, attribute_index);
etx = etx_local_etx_read(interface->id, attribute_index);
// If we dont have valid ETX for children we assume good ETX.
// After enough packets is sent to children real calculated ETX is given.
// This might result in ICMP source route errors returned to Border router causing secondary route uses
if (etx == 0xffff && ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, mac_neighbor->mac64)) {
return 0x100;
}
return etx;
}
bool ws_bootstrap_nd_ns_transmit(protocol_interface_info_entry_t *cur, ipv6_neighbour_t *entry, bool unicast, uint8_t seq)
{
@ -1152,7 +1176,7 @@ static void ws_bootstrap_pan_advertisement_analyse_active(struct protocol_interf
static parent_info_t *ws_bootstrap_candidate_parent_get_best(protocol_interface_info_entry_t *cur)
{
ns_list_foreach_safe(parent_info_t, entry, &cur->ws_info->parent_list_reserved) {
tr_info("candidate list a:%s panid:%x cost:%d size:%d rssi:%d age:%"PRIu32, trace_array(entry->addr, 8), entry->pan_id, entry->pan_information.routing_cost, entry->pan_information.pan_size, entry->signal_dbm, protocol_core_monotonic_time - entry->age);
tr_info("candidate list a:%s panid:%x cost:%d size:%d rssi:%d txFailure:%u age:%"PRIu32, trace_array(entry->addr, 8), entry->pan_id, entry->pan_information.routing_cost, entry->pan_information.pan_size, entry->signal_dbm, entry->tx_fail, protocol_core_monotonic_time - entry->age);
}
return ns_list_get_first(&cur->ws_info->parent_list_reserved);
@ -1250,21 +1274,14 @@ static parent_info_t *ws_bootstrap_candidate_parent_allocate(protocol_interface_
} else {
// If there is no free entries always allocate the last one of reserved as it is the worst
entry = ns_list_get_last(&cur->ws_info->parent_list_reserved);
}
if (entry) {
entry->tx_fail = 0;
}
return entry;
}
static void ws_bootstrap_candidate_parent_free(protocol_interface_info_entry_t *cur, const uint8_t *addr)
{
ns_list_foreach_safe(parent_info_t, entry, &cur->ws_info->parent_list_reserved) {
if (memcmp(entry->addr, addr, 8) == 0) {
ns_list_remove(&cur->ws_info->parent_list_reserved, entry);
ns_list_add_to_end(&cur->ws_info->parent_list_free, entry);
return;
}
}
}
static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interface_info_entry *cur, const uint8_t *addr, bool create)
{
ns_list_foreach_safe(parent_info_t, entry, &cur->ws_info->parent_list_reserved) {
@ -1278,6 +1295,23 @@ static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interfac
return NULL;
}
static void ws_bootstrap_candidate_parent_mark_failure(protocol_interface_info_entry_t *cur, const uint8_t *addr)
{
parent_info_t *entry = ws_bootstrap_candidate_parent_get(cur, addr, false);
if (entry) {
ns_list_remove(&cur->ws_info->parent_list_reserved, entry);
if (entry->tx_fail >= 2) {
ns_list_add_to_end(&cur->ws_info->parent_list_free, entry);
} else {
entry->tx_fail++;
//New last
ns_list_add_to_end(&cur->ws_info->parent_list_reserved, entry);
ws_bootstrap_candidate_parent_sort(cur, entry);
}
}
}
static bool ws_bootstrap_candidate_parent_compare(parent_info_t *p1, parent_info_t *p2)
{
// Return true if P2 is better
@ -1285,6 +1319,10 @@ static bool ws_bootstrap_candidate_parent_compare(parent_info_t *p1, parent_info
// pan_cost
// signal quality
if (p2->tx_fail > p1->tx_fail) {
return false;
}
if (ws_neighbor_class_rsl_from_dbm_calculate(p1->signal_dbm) < (DEVICE_MIN_SENS + CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERISIS) &&
ws_neighbor_class_rsl_from_dbm_calculate(p2->signal_dbm) > (DEVICE_MIN_SENS + CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERISIS)) {
// above threshold is always better than not.
@ -1336,11 +1374,15 @@ static void ws_bootstrap_candidate_list_clean(struct protocol_interface_info_ent
static void ws_bootstrap_candidate_parent_sort(struct protocol_interface_info_entry *cur, parent_info_t *new_entry)
{
//Remove from the list
ns_list_foreach_safe(parent_info_t, entry, &cur->ws_info->parent_list_reserved) {
if (entry == new_entry) {
// own entry skip it
continue;
}
if (ws_bootstrap_candidate_parent_compare(entry, new_entry)) {
// New entry is better
//tr_debug("candidate list new is better");
@ -1550,7 +1592,6 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
}
if (neighbour_pointer_valid) {
etx_lqi_dbm_update(cur->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index, neighbor_info.neighbor->mac64);
//Update Neighbor Broadcast and Unicast Parameters
ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, ws_utt, data->timestamp, (uint8_t *) data->SrcAddr);
ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us, &cur->ws_info->hopping_schdule);
@ -1639,7 +1680,6 @@ static void ws_bootstrap_pan_config_solicit_analyse(struct protocol_interface_in
llc_neighbour_req_t neighbor_info;
if (ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false)) {
etx_lqi_dbm_update(cur->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index, neighbor_info.neighbor->mac64);
ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, ws_utt, data->timestamp, (uint8_t *) data->SrcAddr);
ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us, &cur->ws_info->hopping_schdule);
}
@ -1901,14 +1941,6 @@ static bool ws_bootstrap_neighbor_info_request(struct protocol_interface_info_en
return false;
}
uint8_t ll_target[16];
ws_bootsrap_create_ll_address(ll_target, mac_64);
if (blacklist_reject(ll_target)) {
// Rejected by blacklist
return false;
}
ws_bootstrap_neighbor_table_clean(interface);
neighbor_buffer->neighbor = ws_bootstrap_mac_neighbor_add(interface, mac_64);
@ -1948,6 +1980,15 @@ static void ws_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_pt
ws_bootstrap_neighbor_delete(cur, entry_ptr);
}
static uint32_t ws_probe_init_time_get(protocol_interface_info_entry_t *cur)
{
if (cur->ws_info->cfg->gen.network_size <= NETWORK_SIZE_SMALL) {
return WS_SMALL_PROBE_INIT_BASE_SECONDS;
}
return WS_NORMAL_PROBE_INIT_BASE_SECONDS;
}
static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
{
uint32_t time_from_start = entry_ptr->link_lifetime - entry_ptr->lifetime;
@ -2000,17 +2041,23 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
nud_proces = activate_nud;
} else if (etx_entry->etx_samples < WS_NEIGHBOR_ETX_SAMPLE_MAX) {
//Take Random number for trig a prope.
//Small network
//ETX Sample 0: random 1-4
//ETX Sample 1: random 2-8
//ETX Sample 2: random 4-16
//Medium and large
//ETX Sample 0: random 1-8
//ETX Sample 1: random 2-16
//ETX Sample 2: random 4-32
ws_bootsrap_create_ll_address(ll_address, entry_ptr->mac64);
if (!rpl_control_probe_parent_candidate(cur, ll_address)) {
return false;
}
uint32_t probe_period = WS_PROBE_INIT_BASE_SECONDS << etx_entry->etx_samples;
uint32_t probe_period = ws_probe_init_time_get(cur) << etx_entry->etx_samples;
uint32_t time_block = 1 << etx_entry->etx_samples;
if (time_from_start >= probe_period) {
//tr_debug("Link Probe test %u Sample trig", etx_entry->etx_samples);
activate_nud = true;
@ -2073,6 +2120,11 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
return -1;
}
if (!etx_allow_drop_for_poor_measurements(WS_ETX_BAD_INIT_LINK_LEVEL, WS_ETX_MAX_BAD_LINK_DROP)) {
etx_storage_list_allocate(cur->id, 0);
return -1;
}
etx_max_update_set(WS_ETX_MAX_UPDATE);
etx_max_set(WS_ETX_MAX);
@ -2182,8 +2234,6 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
set_req.value_size = sizeof(bool);
cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req);
mac_helper_mac_mlme_max_retry_set(cur->id, WS_MAX_FRAME_RETRIES);
// Set the default parameters for MPL
cur->mpl_proactive_forwarding = true;
@ -2443,7 +2493,8 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
}
ws_set_fhss_hop(cur);
// Set retry configuration for bootstrap ready state
ws_bootstrap_configure_max_retries(cur, WS_MAX_FRAME_RETRIES, WS_NUMBER_OF_CHANNEL_RETRIES);
} else if (event == RPL_EVENT_LOCAL_REPAIR_NO_MORE_DIS) {
/*
* RPL goes to passive mode, but does not require any extra changed
@ -2643,8 +2694,6 @@ static bool ws_rpl_new_parent_callback(uint8_t *ll_parent_address, void *handle,
ws_bootstrap_neighbor_set_stable(cur, entry->mac64);
//Copy fhss temporary data
*ws_neigh = entry->neigh_info_list;
//ETX Create here
etx_lqi_dbm_update(cur->id, entry->mpduLinkQuality, entry->signal_dbm, neigh_buffer.neighbor->index, neigh_buffer.neighbor->mac64);
mac_neighbor_table_trusted_neighbor(mac_neighbor_info(cur), neigh_buffer.neighbor, true);
}
ws_llc_free_multicast_temp_entry(cur, entry);
@ -2741,9 +2790,6 @@ static void ws_bootstrap_start_discovery(protocol_interface_info_entry_t *cur)
cur->ws_info->pan_timeout_timer = 0;
cur->ws_info->weakest_received_rssi = 0;
// Clear learned neighbours
ws_bootstrap_neighbor_list_clean(cur);
// Clear learned candidate parents
ws_bootstrap_candidate_table_reset(cur);
@ -2884,7 +2930,7 @@ static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_
// eapol parent selected is not working
tr_debug("authentication TX failed");
ws_bootstrap_candidate_parent_free(cur, target_eui_64);
ws_bootstrap_candidate_parent_mark_failure(cur, target_eui_64);
// Go back for network scanning
ws_bootstrap_state_change(cur, ER_ACTIVE_SCAN);
@ -2906,7 +2952,7 @@ static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_
static const uint8_t *ws_bootstrap_authentication_next_target(protocol_interface_info_entry_t *cur, const uint8_t *previous_eui_64, uint16_t *pan_id)
{
ws_bootstrap_candidate_parent_free(cur, previous_eui_64);
ws_bootstrap_candidate_parent_mark_failure(cur, previous_eui_64);
// Gets best target
parent_info_t *parent_info = ws_bootstrap_candidate_parent_get_best(cur);
@ -3262,14 +3308,20 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
// Set PAE port to 10254 and authenticator relay to 10253 (and to own ll address)
ws_pae_controller_authenticator_start(cur, PAE_AUTH_SOCKET_PORT, ll_addr, EAPOL_RELAY_SOCKET_PORT);
// Set retry configuration for bootstrap ready state
ws_bootstrap_configure_max_retries(cur, WS_MAX_FRAME_RETRIES, WS_NUMBER_OF_CHANNEL_RETRIES);
ws_bootstrap_event_operation_start(cur);
break;
}
ws_pae_controller_supp_init(cur);
// Clear learned neighbours
ws_bootstrap_neighbor_list_clean(cur);
// Configure LLC for network discovery
ws_bootstrap_network_discovery_configure(cur);
ws_bootstrap_fhss_activate(cur);
// Set retry configuration for discovery state
ws_bootstrap_configure_max_retries(cur, WS_MAX_FRAME_RETRIES_BOOTSTRAP, WS_NUMBER_OF_CHANNEL_RETRIES_BOOTSTRAP);
// Start network scan
ws_bootstrap_start_discovery(cur);
break;

View File

@ -87,11 +87,8 @@ static void ws_cfg_network_size_config_set_xlarge(ws_cfg_nw_size_t *cfg);
static void ws_cfg_network_size_config_set_certificate(ws_cfg_nw_size_t *cfg);
static int8_t ws_cfg_network_size_default_set(ws_gen_cfg_t *cfg);
static int8_t ws_cfg_gen_default_set(ws_gen_cfg_t *cfg);
static int8_t ws_cfg_phy_default_set(ws_phy_cfg_t *cfg);
static int8_t ws_cfg_timing_default_set(ws_timing_cfg_t *cfg);
static int8_t ws_cfg_bbr_default_set(ws_bbr_cfg_t *cfg);
static int8_t ws_cfg_mpl_default_set(ws_mpl_cfg_t *cfg);
static int8_t ws_cfg_fhss_default_set(ws_fhss_cfg_t *cfg);
static int8_t ws_cfg_sec_timer_default_set(ws_sec_timer_cfg_t *cfg);
static int8_t ws_cfg_sec_prot_default_set(ws_sec_prot_cfg_t *cfg);
@ -601,7 +598,7 @@ int8_t ws_cfg_gen_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *cfg, w
return CFG_SETTINGS_OK;
}
static int8_t ws_cfg_phy_default_set(ws_phy_cfg_t *cfg)
int8_t ws_cfg_phy_default_set(ws_phy_cfg_t *cfg)
{
// FHSS configuration
cfg->regulatory_domain = REG_DOMAIN_EU;
@ -681,7 +678,7 @@ int8_t ws_cfg_phy_set(protocol_interface_info_entry_t *cur, ws_phy_cfg_t *cfg, w
return CFG_SETTINGS_OK;
}
static int8_t ws_cfg_timing_default_set(ws_timing_cfg_t *cfg)
int8_t ws_cfg_timing_default_set(ws_timing_cfg_t *cfg)
{
// Configure the Wi-SUN timing trickle parameters
cfg->disc_trickle_imin = TRICKLE_IMIN_60_SECS; // 60 seconds
@ -901,7 +898,7 @@ int8_t ws_cfg_mpl_set(protocol_interface_info_entry_t *cur, ws_mpl_cfg_t *cfg, w
return CFG_SETTINGS_OK;
}
static int8_t ws_cfg_fhss_default_set(ws_fhss_cfg_t *cfg)
int8_t ws_cfg_fhss_default_set(ws_fhss_cfg_t *cfg)
{
// Set defaults for the device. user can modify these.
cfg->fhss_uc_fixed_channel = 0xffff;

View File

@ -159,10 +159,12 @@ int8_t ws_cfg_gen_get(ws_gen_cfg_t *cfg, uint8_t *flags);
int8_t ws_cfg_gen_validate(ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg);
int8_t ws_cfg_gen_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg, uint8_t *flags);
int8_t ws_cfg_phy_default_set(ws_phy_cfg_t *cfg);
int8_t ws_cfg_phy_get(ws_phy_cfg_t *cfg, uint8_t *flags);
int8_t ws_cfg_phy_validate(ws_phy_cfg_t *cfg, ws_phy_cfg_t *new_cfg);
int8_t ws_cfg_phy_set(protocol_interface_info_entry_t *cur, ws_phy_cfg_t *cfg, ws_phy_cfg_t *new_cfg, uint8_t *flags);
int8_t ws_cfg_timing_default_set(ws_timing_cfg_t *cfg);
int8_t ws_cfg_timing_get(ws_timing_cfg_t *cfg, uint8_t *flags);
int8_t ws_cfg_timing_validate(ws_timing_cfg_t *cfg, ws_timing_cfg_t *new_cfg);
int8_t ws_cfg_timing_set(protocol_interface_info_entry_t *cur, ws_timing_cfg_t *cfg, ws_timing_cfg_t *new_cfg, uint8_t *flags);
@ -175,6 +177,7 @@ int8_t ws_cfg_mpl_get(ws_mpl_cfg_t *cfg, uint8_t *flags);
int8_t ws_cfg_mpl_validate(ws_mpl_cfg_t *cfg, ws_mpl_cfg_t *new_cfg);
int8_t ws_cfg_mpl_set(protocol_interface_info_entry_t *cur, ws_mpl_cfg_t *cfg, ws_mpl_cfg_t *new_cfg, uint8_t *flags);
int8_t ws_cfg_fhss_default_set(ws_fhss_cfg_t *cfg);
int8_t ws_cfg_fhss_get(ws_fhss_cfg_t *cfg, uint8_t *flags);
int8_t ws_cfg_fhss_validate(ws_fhss_cfg_t *cfg, ws_fhss_cfg_t *new_cfg);
int8_t ws_cfg_fhss_set(protocol_interface_info_entry_t *cur, ws_fhss_cfg_t *cfg, ws_fhss_cfg_t *new_cfg, uint8_t *flags);

View File

@ -390,6 +390,24 @@ uint8_t ws_common_temporary_entry_size(uint8_t mac_table_size)
}
}
static void ws_common_neighbour_address_reg_link_update(protocol_interface_info_entry_t *interface, const uint8_t *eui64)
{
/*
* ARO registration from child can update the link timeout so we don't need to send extra NUD if ARO received
*/
mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, false, false);
if (mac_neighbor) {
if (mac_neighbor->link_lifetime != WS_NEIGHBOR_LINK_TIMEOUT) {
//Set Stable timeout for temporary entry here
mac_neighbor->link_lifetime = WS_NEIGHBOR_LINK_TIMEOUT;
tr_info("Added new neighbor %s : index:%u", trace_array(eui64, 8), mac_neighbor->index);
}
//Refresh
mac_neighbor->lifetime = mac_neighbor->link_lifetime;
}
}
uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *interface, const uint8_t *eui64)
{
uint8_t child_count = 0;
@ -402,14 +420,7 @@ uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *inte
//Validate Is EUI64 already allocated for any address
if (ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, eui64)) {
/*
* ARO registration from child can update the link timeout so we don't need to send extra NUD if ARO received
*/
mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, false, false);
if (mac_neighbor) {
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(interface), mac_neighbor, mac_neighbor->link_lifetime);
}
ws_common_neighbour_address_reg_link_update(interface, eui64);
tr_info("Child registration from old child");
return ARO_SUCCESS;
}
@ -431,7 +442,8 @@ uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *inte
tr_warn("Child registration not allowed %d/%d, max:%d", child_count, max_child_count, mac_neighbor_info(interface)->list_total_size);
return ARO_FULL;
}
ws_bootstrap_neighbor_set_stable(interface, eui64);
ws_common_neighbour_address_reg_link_update(interface, eui64);
tr_info("Child registration allowed %d/%d, max:%d", child_count, max_child_count, mac_neighbor_info(interface)->list_total_size);
return ARO_SUCCESS;
}

View File

@ -42,6 +42,7 @@ typedef struct parent_info_s {
uint16_t pan_id; /**< PAN ID */
uint8_t addr[8]; /**< address */
uint8_t link_quality; /**< LQI value measured during reception of the MPDU */
uint8_t tx_fail;
int8_t signal_dbm; /**< This extension for normal IEEE 802.15.4 Data indication */
ws_pan_information_t pan_information;
ws_utt_ie_t ws_utt;

View File

@ -255,7 +255,8 @@ typedef struct ws_bs_ie {
#define WS_NEIGHBOR_ETX_SAMPLE_MAX 3
#define WS_NEIGHBOR_FIRST_ETX_SAMPLE_MIN_COUNT 3 //This can't be bigger than WS_NEIGHBOR_ETX_SAMPLE_MAX
#define WS_PROBE_INIT_BASE_SECONDS 8
#define WS_SMALL_PROBE_INIT_BASE_SECONDS 4
#define WS_NORMAL_PROBE_INIT_BASE_SECONDS 8
#define WS_NUD_RAND_PROBABILITY 1
@ -270,6 +271,10 @@ typedef struct ws_bs_ie {
#define WS_ETX_MIN_WAIT_TIME 60
#define WS_ETX_BAD_INIT_LINK_LEVEL 3 //3 or higher attempt count will be dropped
#define WS_ETX_MAX_BAD_LINK_DROP 2 //Drop 2 bad link from init 3
#define WS_RPL_PARENT_CANDIDATE_MAX 5
#define WS_RPL_SELECTED_PARENT_MAX 2
@ -322,8 +327,12 @@ typedef struct ws_bs_ie {
* 3 4 1+3*1+4=20
*
*/
// This configuration is used when bootstrap is ready
#define WS_MAX_FRAME_RETRIES 3
#define WS_NUMBER_OF_CHANNEL_RETRIES 4
// This configuration is used during bootstrap
#define WS_MAX_FRAME_RETRIES_BOOTSTRAP 0
#define WS_NUMBER_OF_CHANNEL_RETRIES_BOOTSTRAP 19
#if (1 + WS_MAX_FRAME_RETRIES) * (1 + WS_NUMBER_OF_CHANNEL_RETRIES) < 20

View File

@ -174,8 +174,8 @@ extern uint8_t DEVICE_MIN_SENS;
#define FRAME_COUNTER_STORE_INTERVAL 60 // Time interval (on seconds) between checking if frame counter storing is needed
#define FRAME_COUNTER_STORE_FORCE_INTERVAL (3600 * 20) // Time interval (on seconds) before frame counter storing is forced (if no other storing operations triggered)
#define FRAME_COUNTER_STORE_TRIGGER 5 // Delay (on seconds) before storing, when storing of frame counters is triggered
#define FRAME_COUNTER_INCREMENT 1000 // How much frame counter is incremented on start up
#define FRAME_COUNTER_STORE_THRESHOLD 800 // How much frame counter must increment before it is stored
#define FRAME_COUNTER_INCREMENT 1000000 // How much frame counter is incremented on start up
#define FRAME_COUNTER_STORE_THRESHOLD 994999 // How much frame counter must increment before it is stored
/*
@ -219,7 +219,7 @@ extern uint8_t DEVICE_MIN_SENS;
#define SEC_PROT_TIMER_EXPIRATIONS 2 // Number of retries
// Maximum number of simultaneous security negotiations
#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_SMALL 3
#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_SMALL 20
#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_MEDIUM 20
#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_LARGE 50

View File

@ -729,8 +729,6 @@ static void ws_llc_data_indication_cb(const mac_api_t *api, const mcps_data_ind_
ws_neighbor_class_rsl_in_calculate(neighbor_info.ws_neighbor, data->signal_dbm);
if (neighbor_info.neighbor) {
//Refresh ETX dbm
etx_lqi_dbm_update(interface->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index, neighbor_info.neighbor->mac64);
if (data->Key.SecurityLevel) {
//SET trusted state
mac_neighbor_table_trusted_neighbor(mac_neighbor_info(interface), neighbor_info.neighbor, true);

View File

@ -170,18 +170,29 @@ int ws_management_regulatory_domain_set(
}
ws_phy_cfg_t cfg;
ws_phy_cfg_t cfg_default;
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
return -3;
}
if (ws_cfg_phy_default_set(&cfg_default) < 0) {
return -3;
}
if (regulatory_domain != 255) {
cfg.regulatory_domain = regulatory_domain;
} else {
cfg.regulatory_domain = cfg_default.regulatory_domain;
}
if (operating_mode != 255) {
cfg.operating_mode = operating_mode;
} else {
cfg.operating_mode = cfg_default.operating_mode;
}
if (operating_class != 255) {
cfg.operating_class = operating_class;
} else {
cfg.operating_class = cfg_default.operating_class;
}
if (ws_cfg_phy_set(cur, NULL, &cfg, 0) < 0) {
@ -334,7 +345,18 @@ int ws_management_channel_mask_set(
return -2;
}
memcpy(cfg.fhss_channel_mask, channel_mask, sizeof(uint32_t) * 8);
ws_fhss_cfg_t cfg_default;
if (ws_cfg_fhss_default_set(&cfg_default) < 0) {
return -2;
}
if (channel_mask) {
memcpy(cfg.fhss_channel_mask, channel_mask, sizeof(uint32_t) * 8);
} else {
// Use the default
memcpy(cfg.fhss_channel_mask, cfg_default.fhss_channel_mask, sizeof(uint32_t) * 8);
}
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
return -3;
@ -434,14 +456,27 @@ int ws_management_fhss_timing_configure(
return -2;
}
ws_fhss_cfg_t cfg_default;
if (ws_cfg_fhss_default_set(&cfg_default) < 0) {
return -2;
}
if (fhss_uc_dwell_interval > 0) {
cfg.fhss_uc_dwell_interval = fhss_uc_dwell_interval;
} else if (fhss_uc_dwell_interval == 0xff) {
cfg.fhss_uc_dwell_interval = cfg_default.fhss_uc_dwell_interval;
}
if (fhss_broadcast_interval > 0) {
cfg.fhss_bc_interval = fhss_broadcast_interval;
} else if (fhss_broadcast_interval == 0xffff) {
cfg.fhss_bc_interval = cfg_default.fhss_bc_interval;
}
if (fhss_bc_dwell_interval > 0) {
cfg.fhss_bc_dwell_interval = fhss_bc_dwell_interval;
} else if (fhss_bc_dwell_interval == 0xff) {
cfg.fhss_bc_dwell_interval = cfg_default.fhss_bc_dwell_interval;
}
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
@ -469,12 +504,27 @@ int ws_management_fhss_unicast_channel_function_configure(
return -2;
}
if (dwell_interval > 0) {
cfg.fhss_uc_dwell_interval = dwell_interval;
ws_fhss_cfg_t cfg_default;
if (ws_cfg_fhss_default_set(&cfg_default) < 0) {
return -2;
}
cfg.fhss_uc_channel_function = channel_function;
cfg.fhss_uc_fixed_channel = fixed_channel;
if (dwell_interval > 0) {
cfg.fhss_uc_dwell_interval = dwell_interval;
} else {
cfg.fhss_uc_dwell_interval = cfg_default.fhss_uc_dwell_interval;
}
if (channel_function < 0xff) {
cfg.fhss_uc_channel_function = channel_function;
} else {
cfg.fhss_uc_channel_function = cfg_default.fhss_uc_channel_function;
}
if (fixed_channel < 0xffff) {
cfg.fhss_uc_fixed_channel = fixed_channel;
} else {
cfg.fhss_uc_fixed_channel = cfg_default.fhss_uc_fixed_channel;
}
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
return -3;
@ -556,16 +606,34 @@ int ws_management_fhss_broadcast_channel_function_configure(
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
return -2;
}
ws_fhss_cfg_t cfg_default;
if (ws_cfg_fhss_default_set(&cfg_default) < 0) {
return -2;
}
if (dwell_interval > 0) {
cfg.fhss_bc_dwell_interval = dwell_interval;
}
if (broadcast_interval > 0) {
cfg.fhss_bc_interval = broadcast_interval;
} else {
cfg.fhss_bc_dwell_interval = cfg_default.fhss_bc_dwell_interval;
}
cfg.fhss_bc_channel_function = channel_function;
cfg.fhss_bc_fixed_channel = fixed_channel;
if (broadcast_interval > 0) {
cfg.fhss_bc_interval = broadcast_interval;
} else {
cfg.fhss_bc_interval = cfg_default.fhss_bc_interval;
}
if (channel_function != 0xff) {
cfg.fhss_bc_channel_function = channel_function;
} else {
cfg.fhss_bc_channel_function = cfg_default.fhss_bc_channel_function;
}
if (fixed_channel != 0xffff) {
cfg.fhss_bc_fixed_channel = fixed_channel;
} else {
cfg.fhss_bc_fixed_channel = cfg_default.fhss_bc_fixed_channel;
}
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
return -3;
@ -652,17 +720,33 @@ int ws_management_timing_parameters_set(
return -2;
}
ws_timing_cfg_t cfg_default;
if (ws_cfg_timing_default_set(&cfg_default) < 0) {
return -2;
}
if (disc_trickle_imin > 0) {
cfg.disc_trickle_imin = disc_trickle_imin;
} else {
cfg.disc_trickle_imin = cfg_default.disc_trickle_imin;
}
if (disc_trickle_imax > 0) {
cfg.disc_trickle_imax = disc_trickle_imax;
} else {
cfg.disc_trickle_imax = cfg_default.disc_trickle_imax;;
}
if (disc_trickle_k > 0) {
cfg.disc_trickle_k = disc_trickle_k;
} else {
cfg.disc_trickle_k = cfg_default.disc_trickle_k;;
}
if (pan_timeout > 0) {
cfg.pan_timeout = pan_timeout;
} else {
cfg.pan_timeout = cfg_default.pan_timeout;;
}
if (ws_cfg_timing_set(cur, NULL, &cfg, 0) < 0) {

View File

@ -440,7 +440,7 @@ int8_t ws_pae_auth_node_access_revoke_start(protocol_interface_info_entry_t *int
// If active GTK lifetime is larger than revocation lifetime decrements active GTK lifetime
if (active_lifetime > revocation_lifetime) {
sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, active_index, current_time, active_lifetime - revocation_lifetime);
sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, active_index, current_time, active_lifetime - revocation_lifetime, true);
tr_info("Access revocation start, GTK active index: %i, revoked lifetime: %"PRIu32"", active_index, revocation_lifetime);
} else {
// Otherwise decrements lifetime of the GTK to be installed after the active one
@ -451,7 +451,7 @@ int8_t ws_pae_auth_node_access_revoke_start(protocol_interface_info_entry_t *int
uint32_t second_lifetime = sec_prot_keys_gtk_lifetime_get(pae_auth->sec_keys_nw_info->gtks, second_index);
if (second_lifetime > second_revocation_lifetime) {
sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, second_index, current_time, second_lifetime - second_revocation_lifetime);
sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, second_index, current_time, second_lifetime - second_revocation_lifetime, true);
tr_info("Access revocation start, GTK second active index: %i, revoked lifetime: %"PRIu32"", second_index, second_revocation_lifetime);
}
// Removes other keys than active and GTK to be installed next
@ -710,7 +710,7 @@ void ws_pae_auth_slow_timer(uint16_t seconds)
if (!sec_prot_keys_gtk_is_set(pae_auth->sec_keys_nw_info->gtks, i)) {
continue;
}
uint32_t timer_seconds = sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, i, current_time, seconds);
uint32_t timer_seconds = sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, i, current_time, seconds, true);
if (active_index == i) {
if (!pae_auth->gtk_new_inst_req_exp) {
pae_auth->gtk_new_inst_req_exp = ws_pae_timers_gtk_new_install_required(pae_auth->sec_cfg, timer_seconds);

View File

@ -783,8 +783,14 @@ static int8_t ws_pae_controller_frame_counter_read(pae_controller_t *controller)
// Checks frame counters
for (uint8_t index = 0; index < GTK_NUM; index++) {
if (controller->frame_counters.counter[index].set) {
// Increments frame counters
controller->frame_counters.counter[index].frame_counter += FRAME_COUNTER_INCREMENT;
// If there is room on frame counter space
if (controller->frame_counters.counter[index].frame_counter < (UINT32_MAX - FRAME_COUNTER_INCREMENT * 2)) {
// Increments frame counters
controller->frame_counters.counter[index].frame_counter += FRAME_COUNTER_INCREMENT;
} else {
tr_error("Frame counter space exhausted");
controller->frame_counters.counter[index].frame_counter = UINT32_MAX;
}
controller->frame_counters.counter[index].stored_frame_counter =
controller->frame_counters.counter[index].frame_counter;
@ -891,6 +897,7 @@ int8_t ws_pae_controller_supp_init(protocol_interface_info_entry_t *interface_pt
ws_pae_controller_nw_info_read(controller, controller->sec_keys_nw_info.gtks);
// Set active key back to fresh so that it can be used again after re-start
sec_prot_keys_gtk_status_active_to_fresh_set(&controller->gtks);
sec_prot_keys_gtks_updated_reset(&controller->gtks);
return 0;
}

View File

@ -360,7 +360,17 @@ int8_t ws_pae_key_storage_supp_write(const void *instance, supp_entry_t *pae_sup
uint8_t *eui_64 = pae_supp->addr.eui_64;
key_storage_array_t *key_storage_array;
sec_prot_keys_storage_t *key_storage = ws_pae_key_storage_get(instance, eui_64, &key_storage_array, true);
// Check if entry exists
sec_prot_keys_storage_t *key_storage = ws_pae_key_storage_get(instance, eui_64, &key_storage_array, false);
if (key_storage == NULL) {
// Do not allocate new storage if PMK and PTK are not set
if (!pae_supp->sec_keys.pmk_set && !pae_supp->sec_keys.ptk_set) {
tr_info("KeyS PMK and PTK not set, skip storing, eui64: %s", tr_array(eui_64, 8));
return -1;
}
// Allocate new empty entry
key_storage = ws_pae_key_storage_get(instance, eui_64, &key_storage_array, true);
}
// If cannot find existing or empty storage and there is room for storages tries to allocate more storage
if (key_storage == NULL && key_storage_params.storages_empty > 0) {

View File

@ -549,11 +549,13 @@ int8_t ws_pae_supp_nw_info_set(protocol_interface_info_entry_t *interface_ptr, u
sec_prot_keys_ptk_delete(&pae_supp->entry.sec_keys);
sec_prot_keys_ptk_eui_64_delete(&pae_supp->entry.sec_keys);
// Delete GTKs
sec_prot_keys_gtks_init(pae_supp->sec_keys_nw_info->gtks);
sec_prot_keys_gtks_updated_set(pae_supp->sec_keys_nw_info->gtks);
ws_pae_supp_nvm_update(pae_supp);
sec_prot_keys_gtks_clear(pae_supp->sec_keys_nw_info->gtks);
// If data is changed, store to NVM
if (sec_prot_keys_are_updated(&pae_supp->entry.sec_keys) ||
sec_prot_keys_gtks_are_updated(pae_supp->sec_keys_nw_info->gtks)) {
ws_pae_supp_nvm_update(pae_supp);
}
}
return 0;
}
@ -888,7 +890,7 @@ void ws_pae_supp_slow_timer(uint16_t seconds)
continue;
}
uint64_t current_time = ws_pae_current_time_get();
sec_prot_keys_gtk_lifetime_decrement(pae_supp->sec_keys_nw_info->gtks, i, current_time, seconds);
sec_prot_keys_gtk_lifetime_decrement(pae_supp->sec_keys_nw_info->gtks, i, current_time, seconds, false);
}
if (pae_supp->initial_key_timer > 0) {

View File

@ -410,7 +410,7 @@ static void radius_eap_tls_sec_prot_radius_client_deleted(sec_prot_t *prot)
{
radius_eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
tr_debug("EAP-TLS: client deleted");
tr_info("EAP-TLS: client deleted");
data->radius_client_prot = NULL;
data->radius_client_send = NULL;
@ -526,7 +526,7 @@ static void radius_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
// On timeout
if (sec_prot_result_timeout_check(&data->common)) {
tr_debug("EAP-TLS: retry EAP request, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
tr_info("EAP-TLS: retry EAP request, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
if (radius_eap_tls_sec_prot_radius_eap_message_retry(prot) < 0) {
tr_error("EAP-TLS: retry msg send error");
}

View File

@ -96,6 +96,16 @@ void sec_prot_keys_gtks_init(sec_prot_gtk_keys_t *gtks)
gtks->updated = false;
}
void sec_prot_keys_gtks_clear(sec_prot_gtk_keys_t *gtks)
{
for (uint8_t i = 0; i < GTK_NUM; i++) {
if (sec_prot_keys_gtk_is_set(gtks, i)) {
gtks->updated = true;
}
}
memset(gtks, 0, sizeof(sec_prot_gtk_keys_t));
}
void sec_prot_keys_gtks_delete(sec_prot_gtk_keys_t *gtks)
{
ns_dyn_mem_free(gtks);
@ -113,12 +123,15 @@ void sec_prot_keys_pmk_write(sec_prot_keys_t *sec_keys, uint8_t *pmk, uint32_t p
void sec_prot_keys_pmk_delete(sec_prot_keys_t *sec_keys)
{
if (sec_keys->pmk_key_replay_cnt != 0 || sec_keys->pmk_key_replay_cnt_set ||
sec_keys->pmk_lifetime != 0 || sec_keys->pmk_set) {
sec_keys->updated = true;
}
memset(sec_keys->pmk, 0, PMK_LEN);
sec_keys->pmk_key_replay_cnt = 0;
sec_keys->pmk_key_replay_cnt_set = false;
sec_keys->pmk_lifetime = 0;
sec_keys->pmk_set = false;
sec_keys->updated = true;
}
uint8_t *sec_prot_keys_pmk_get(sec_prot_keys_t *sec_keys)
@ -222,10 +235,12 @@ void sec_prot_keys_ptk_write(sec_prot_keys_t *sec_keys, uint8_t *ptk, uint32_t p
void sec_prot_keys_ptk_delete(sec_prot_keys_t *sec_keys)
{
if (sec_keys->ptk_lifetime != 0 || sec_keys->ptk_set) {
sec_keys->updated = true;
}
memset(sec_keys->ptk, 0, PTK_LEN);
sec_keys->ptk_lifetime = 0;
sec_keys->ptk_set = false;
sec_keys->updated = true;
}
uint8_t *sec_prot_keys_ptk_get(sec_prot_keys_t *sec_keys)
@ -279,9 +294,11 @@ uint8_t *sec_prot_keys_ptk_eui_64_get(sec_prot_keys_t *sec_keys)
void sec_prot_keys_ptk_eui_64_delete(sec_prot_keys_t *sec_keys)
{
if (sec_keys->ptk_eui_64_set) {
sec_keys->updated = true;
}
memset(sec_keys->ptk_eui_64, 0, 8);
sec_keys->ptk_eui_64_set = false;
sec_keys->updated = true;
}
bool sec_prot_keys_ptk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint8_t seconds)
@ -490,7 +507,7 @@ uint32_t sec_prot_keys_gtk_lifetime_get(sec_prot_gtk_keys_t *gtks, uint8_t index
return gtks->gtk[index].lifetime;
}
uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint16_t seconds)
uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint16_t seconds, bool gtk_update_enable)
{
if (gtks->gtk[index].lifetime > seconds) {
gtks->gtk[index].lifetime -= seconds;
@ -508,7 +525,7 @@ uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t
diff = expirytime - gtks->gtk[index].expirytime;
}
// If timestamps differ for more than 5 minutes marks field as updated (and stores to NVM)
if (diff > 300) {
if (diff > 300 && gtk_update_enable) {
gtks->updated = true;
}
@ -588,7 +605,8 @@ int8_t sec_prot_keys_gtk_status_active_set(sec_prot_gtk_keys_t *gtks, uint8_t in
}
}
gtks->gtk[index].status = GTK_STATUS_ACTIVE;
gtks->updated = true;
/* Changing fresh to active does not change the gtks updated state since active
keys are set to fresh on nvm read on startup */
return 0;
}

View File

@ -200,6 +200,14 @@ sec_prot_gtk_keys_t *sec_prot_keys_gtks_create(void);
*/
void sec_prot_keys_gtks_init(sec_prot_gtk_keys_t *gtks);
/**
* sec_prot_keys_gtks_init clear GTK keys
*
* \param gtks GTK keys
*
*/
void sec_prot_keys_gtks_clear(sec_prot_gtk_keys_t *gtks);
/**
* sec_prot_keys_gtks_delete frees GTK keys memory
*
@ -616,11 +624,12 @@ uint32_t sec_prot_keys_gtk_lifetime_get(sec_prot_gtk_keys_t *gtks, uint8_t index
* \param index index for GTK
* \param current_time current timestamp
* \param seconds elapsed seconds
* \param gtk_update_enable enable GTK status to be updated
*
* \return new GTK lifetime
*
*/
uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint16_t seconds);
uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint16_t seconds, bool gtk_update_enable);
/**
* sec_prot_keys_gtk_exptime_from_lifetime_get converts GTK lifetime to expiry time.

View File

@ -389,7 +389,7 @@ uint8_t *sec_prot_lib_message_handle(uint8_t *ptk, uint16_t *kde_len, eapol_pdu_
return kde;
}
return NULL;
return NULL;
}
int8_t sec_prot_lib_gtk_read(uint8_t *kde, uint16_t kde_len, sec_prot_keys_t *sec_keys)

View File

@ -74,6 +74,8 @@ typedef struct {
uint8_t etx_min_sampling_time;
uint8_t ext_storage_list_size;
uint8_t min_attempts_count;
uint8_t drop_bad_max;
uint8_t bad_link_level;
bool cache_sample_requested;
int8_t interface_id;
} ext_info_t;
@ -87,6 +89,8 @@ static ext_info_t etx_info = {
.etx_cache_storage_list = NULL,
.ext_storage_list_size = 0,
.min_attempts_count = 0,
.drop_bad_max = 0,
.bad_link_level = 0,
.max_etx_update = 0,
.max_etx = 0xffff,
.init_etx_sample_count = 1,
@ -133,6 +137,8 @@ static void etx_calculation(etx_storage_t *entry, uint16_t attempts, uint8_t ack
entry->tmp_etx = false;
entry->etx = etx;
//Clear Drop count
entry->drop_bad_count = 0;
if (entry->etx_samples >= etx_info.init_etx_sample_count) {
etx_cache_entry_init(etx_neigh_info->attribute_index);
@ -149,6 +155,7 @@ static void etx_cache_entry_init(uint8_t attribute_index)
etx_sample_storage_t *storage = etx_info.etx_cache_storage_list + attribute_index;
storage->attempts_count = 0;
storage->transition_count = 0;
storage->etx_timer = etx_info.etx_min_sampling_time;
storage->received_acks = 0;
}
@ -162,21 +169,22 @@ static bool etx_update_possible(etx_sample_storage_t *storage, etx_storage_t *en
storage->etx_timer -= time_update;
}
}
if (entry->etx_samples == etx_info.init_etx_sample_count && time_update == 0) {
return true;
}
if (entry->etx_samples > etx_info.init_etx_sample_count) {
//Slower ETX update phase
if (storage->attempts_count >= etx_info.min_attempts_count) {
if (storage->etx_timer == 0 || storage->attempts_count == 0xffff || storage->received_acks == 0xff) {
if (storage->etx_timer == 0 || storage->attempts_count == 0xffff || storage->received_acks == 0xff) {
//When time is going zero or too much sample data
if (storage->transition_count >= etx_info.min_attempts_count) {
//Got least min sample in requested time or max possible sample
return true;
} else if (storage->transition_count != storage->received_acks) {
//Missing ack now ETX can be accelerated
return true;
}
}
return false;
}
if (time_update == 0) {
return true;
}
return false;
@ -188,6 +196,7 @@ static etx_sample_storage_t *etx_cache_sample_update(uint8_t attribute_index, ui
{
etx_sample_storage_t *storage = etx_info.etx_cache_storage_list + attribute_index;
storage->attempts_count += attempts;
storage->transition_count++;
if (ack_rx) {
storage->received_acks++;
}
@ -196,6 +205,26 @@ static etx_sample_storage_t *etx_cache_sample_update(uint8_t attribute_index, ui
}
static bool etx_drop_bad_sample(etx_storage_t *entry, uint8_t attempts, bool success)
{
if (etx_info.bad_link_level == 0 || !success) {
//Not enabled or Failure
return false;
}
if (attempts < etx_info.bad_link_level) {
//under configured value is accepted
return false;
}
if (entry->drop_bad_count < etx_info.drop_bad_max) {
//Accepted only configured max value 1-2
entry->drop_bad_count++;
return true;
}
return false;
}
/**
* \brief A function to update ETX value based on transmission attempts
@ -222,6 +251,11 @@ void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool succ
etx_neigh_info.mac64 = mac64_addr_ptr;
if (entry->etx_samples < 7) {
if (etx_drop_bad_sample(entry, attempts, success)) {
tr_debug("Drop bad etx init %u", attempts);
return;
}
entry->etx_samples++;
}
@ -235,10 +269,6 @@ void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool succ
}
etx_calculation(entry, storage->attempts_count, storage->received_acks, &etx_neigh_info);
if (entry->etx_samples < 7 && !success) {
entry->etx_samples = 7; //Stop Probing to failure
}
return;
}
@ -409,9 +439,13 @@ uint16_t etx_local_etx_read(int8_t interface_id, uint8_t attribute_index)
}
if (etx_info.cache_sample_requested && entry->etx_samples < etx_info.init_etx_sample_count) {
if (!entry->etx_samples) {
return 0;
etx_sample_storage_t *storage = etx_info.etx_cache_storage_list + attribute_index;
if (storage->received_acks == 0 && storage->attempts_count) {
//No ack so return max value
return etx_info.max_etx;
}
//Not ready yet
return 0xffff;
}
return etx_current_calc(entry->etx, entry->accumulated_failures) >> 4;
@ -668,6 +702,36 @@ bool etx_cached_etx_parameter_set(uint8_t min_wait_time, uint8_t etx_min_attempt
return true;
}
bool etx_allow_drop_for_poor_measurements(uint8_t bad_link_level, uint8_t max_allowed_drops)
{
//No ini ETX allocation done yet
if (etx_info.ext_storage_list_size == 0) {
return false;
}
if (bad_link_level == 0) {
//Disable feature
etx_info.bad_link_level = 0;
etx_info.drop_bad_max = 0;
return true;
}
if (bad_link_level < 2) {
// 2 attepts is min value
return false;
}
if (max_allowed_drops == 0 || max_allowed_drops > 3) {
//Accepted values is 1-3
return false;
}
etx_info.bad_link_level = bad_link_level;
etx_info.drop_bad_max = max_allowed_drops;
return true;
}
void etx_max_update_set(uint16_t etx_max_update)
{
if (etx_max_update) {

View File

@ -58,12 +58,14 @@ typedef struct etx_storage_s {
unsigned tmp_etx: 1;
unsigned linkIdr: 4;
unsigned etx_samples: 3;
unsigned drop_bad_count: 2;
} etx_storage_t;
typedef struct etx_sample_storage_s {
uint16_t attempts_count; /*!< TX attempt count */
uint8_t etx_timer; /*!< Count down from configured value 0 means that ETX Update is possible done again*/
uint8_t received_acks; /*!< Received ACK's */
uint8_t transition_count;
} etx_sample_storage_t;
/**
@ -279,6 +281,15 @@ bool etx_cached_etx_parameter_set(uint8_t min_wait_time, uint8_t etx_min_attempt
*/
void etx_max_update_set(uint16_t etx_max_update);
/**
* \brief A function for configure limit for detect bad init ETX sample
*
* \param bad_link_level 0 No limit and >=2 Level
* \param max_allowed_drops How many init probe is accepted to drop 1-2 are possible values
*
*/
bool etx_allow_drop_for_poor_measurements(uint8_t bad_link_level, uint8_t max_allowed_drops);
/**
* \brief A function for set Maxium ETX value
*

View File

@ -1063,7 +1063,7 @@ int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_co
fhss_structure->rx_channel = fhss_configuration->unicast_fixed_channel;
}
platform_exit_critical();
tr_info("fhss Configuration set, UC channel: %d, BC channel: %d, UC CF: %d, BC CF: %d, channels: BC %d UC %d, uc dwell: %d, bc dwell: %d, bc interval: %"PRIu32", bsi:%d",
tr_info("fhss Configuration set, UC channel: %d, BC channel: %d, UC CF: %d, BC CF: %d, channels: BC %d UC %d, uc dwell: %d, bc dwell: %d, bc interval: %"PRIu32", bsi:%d, ch retries: %u",
fhss_structure->ws->fhss_configuration.unicast_fixed_channel,
fhss_structure->ws->fhss_configuration.broadcast_fixed_channel,
fhss_structure->ws->fhss_configuration.ws_uc_channel_function,
@ -1073,7 +1073,9 @@ int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_co
fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval,
fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval,
fhss_structure->ws->fhss_configuration.fhss_broadcast_interval,
fhss_structure->ws->fhss_configuration.bsi);
fhss_structure->ws->fhss_configuration.bsi,
fhss_structure->ws->fhss_configuration.config_parameters.number_of_channel_retries);
return 0;
}