Squashed 'connectivity/nanostack/sal-stack-nanostack/' changes from d879e6db87..09d9e24f2d

09d9e24f2d Merge branch 'release_internal' into release_external
9a3278a1e3 Removed Black list reject from wi-sun neighbour request function
76fc9d77a1 Support SLAAC addressing method for Wi-SUN Border router
71c8bde863 Modified Wi-SUN etx to wait for Probes
b720fbdfe0 Wi-SUN discovery and address registration update
e73c8082ed Merge pull request #2460 from ARMmbed/sync_with_mbed_os
7994d9537b If PMK and PTK are not set do not store keys to NVM
f8813e2d27 Follow Mbed OS coding style
f6ed87754c (via mbedos) Possible invalid memory access on memcpy
40dc215294 Set frame counter increment to 1000000
a57acc84a8 ETX update
5373de2ff4 EAPOL parent TX feilure is reorder candidate list.
6b0e264869 Allowed separate default settings in WS API
850252b9f9 Fixed EAPOL brodcast synch at border router device.
2c1c07779a Corrected unit test
16e38ce688 Changed EAPOL negotiation limit on small nw to 20
21af9233ec Wi-sun ETX update
80e13f4435 Changed EAP-TLS retry trace to info trace level
52a5018fd1 WS: Use special retry configuration when discovery is started (#2450)
7e3b99c375 Merge branch 'release_internal' into release_external
50b7a641b4 Key update to MAC is forced when nw name changes
f1f46f3873 Corrected identifier range alloc and added define for timeout
f836d1d818 FHSS WS: spread broadcast messages better on BC channel (#2449)
9a1b35398c Merge branch 'release_internal' into release_external
5e40cb3852 Fix 0 length domain search list
f0f5131833 Fixed coverity issue.
81b94e535d Added test harness API for set temporary neighbour lifetime longer
b969fa3779 Merge branch 'release_internal' into release_external
b66b834d0c Timed parent selection update

git-subtree-dir: connectivity/nanostack/sal-stack-nanostack
git-subtree-split: 09d9e24f2d3e97cd38139e5df3d9e79d2ee65f4e
pull/13718/head^2
Arto Kinnunen 2020-10-05 15:05:29 +03:00
parent 9a4e8a5964
commit b9f3753918
32 changed files with 554 additions and 163 deletions

View File

@ -204,6 +204,19 @@ void ws_test_skip_edfe_data_send(int8_t interface_id, bool skip);
*/
int8_t ws_test_drop_edfe_data_frames(int8_t interface_id, uint8_t number_of_dropped_frames);
/**
* Set neighbour temporary timeout value.
*
* Made only for test purpose for test EDFE certificatiomn test harness.
*
* \param interface_id Network interface ID.
* \param temporary_lifetime 0 to disable test harness, 240-2200 enable longer temporary neighbour lifetime. Values bigger than 2200 will be capped to 2200.
*
* \return 0 Success
* \return <0 Failure
*/
int ws_test_neighbour_temporary_lifetime_set(int8_t interface_id, uint32_t temporary_lifetime);
#ifdef __cplusplus
}
#endif

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*/
@ -139,8 +140,8 @@ mac_neighbor_table_entry_t *ws_bootstrap_mac_neighbor_add(struct protocol_interf
}
// TODO only call these for new neighbour
mlme_device_descriptor_t device_desc;
neighbor->lifetime = WS_NEIGHBOUR_TEMPORARY_ENTRY_LIFETIME;
neighbor->link_lifetime = WS_NEIGHBOUR_TEMPORARY_ENTRY_LIFETIME;
neighbor->lifetime = ws_cfg_neighbour_temporary_lifetime_get();
neighbor->link_lifetime = ws_cfg_neighbour_temporary_lifetime_get();
mac_helper_device_description_write(interface, &device_desc, neighbor->mac64, neighbor->mac16, 0, false);
mac_helper_devicetable_set(&device_desc, interface, neighbor->index, interface->mac_parameters->mac_default_key_index, true);
@ -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);
}
@ -1828,7 +1868,7 @@ static void ws_bootstrap_neighbor_table_clean(struct protocol_interface_info_ent
continue;
}
if (cur->link_lifetime != WS_NEIGHBOR_LINK_TIMEOUT) {
if (cur->link_lifetime < WS_NEIGHBOUR_TEMPORARY_NEIGH_MAX_LIFETIME) {
continue;
}
@ -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;
@ -1959,7 +2000,7 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
ws_neighbor_class_entry_t *ws_neighbor = ws_neighbor_class_entry_get(&cur->ws_info->neighbor_storage, entry_ptr->index);
etx_storage_t *etx_entry = etx_storage_entry_get(cur->id, entry_ptr->index);
if (!entry_ptr->trusted_device || !ws_neighbor || !etx_entry || ws_neighbor->negative_aro_send || entry_ptr->link_lifetime != WS_NEIGHBOR_LINK_TIMEOUT) {
if (!entry_ptr->trusted_device || !ws_neighbor || !etx_entry || ws_neighbor->negative_aro_send || entry_ptr->link_lifetime < WS_NEIGHBOUR_TEMPORARY_NEIGH_MAX_LIFETIME) {
return false;
}
@ -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

@ -55,6 +55,7 @@ typedef struct ws_cfg_nw_size_s {
ws_sec_prot_cfg_t sec_prot; /**< Security protocols configuration */
} ws_cfg_nw_size_t;
static uint32_t ws_test_temporary_entry_lifetime = 0;
typedef int8_t (*ws_cfg_default_set)(void *cfg);
typedef int8_t (*ws_cfg_validate)(void *cfg, void *new_cfg);
typedef int8_t (*ws_cfg_set)(protocol_interface_info_entry_t *cur, void *cfg, void *new_cfg, uint8_t *flags);
@ -86,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);
@ -600,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;
@ -680,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
@ -900,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;
@ -1275,4 +1273,21 @@ int8_t ws_cfg_settings_set(protocol_interface_info_entry_t *cur, ws_cfg_t *new_c
return ret_value;
}
uint32_t ws_cfg_neighbour_temporary_lifetime_get(void)
{
if (ws_test_temporary_entry_lifetime) {
return ws_test_temporary_entry_lifetime;
}
return WS_NEIGHBOUR_TEMPORARY_ENTRY_LIFETIME;
}
void ws_cfg_neighbour_temporary_lifetime_set(uint32_t lifetime)
{
if (lifetime >= WS_NEIGHBOUR_TEMPORARY_NEIGH_MAX_LIFETIME || lifetime == 0) {
if (lifetime > WS_NEIGHBOR_LINK_TIMEOUT) {
lifetime = WS_NEIGHBOR_LINK_TIMEOUT;
}
ws_test_temporary_entry_lifetime = lifetime;
}
}
#endif //HAVE_WS

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);
@ -187,4 +190,7 @@ int8_t ws_cfg_sec_prot_get(ws_sec_prot_cfg_t *cfg, uint8_t *flags);
int8_t ws_cfg_sec_prot_validate(ws_sec_prot_cfg_t *cfg, ws_sec_prot_cfg_t *new_cfg);
int8_t ws_cfg_sec_prot_set(protocol_interface_info_entry_t *cur, ws_sec_prot_cfg_t *cfg, ws_sec_prot_cfg_t *new_cfg, uint8_t *flags);
uint32_t ws_cfg_neighbour_temporary_lifetime_get(void);
void ws_cfg_neighbour_temporary_lifetime_set(uint32_t lifetime);
#endif // WS_CFG_STORAGE_H_

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

@ -241,6 +241,7 @@ typedef struct ws_bs_ie {
#define WS_NEIGHBOR_LINK_TIMEOUT 2200
#define WS_NEIGHBOUR_TEMPORARY_NEIGH_MAX_LIFETIME 240
#define WS_NEIGHBOUR_TEMPORARY_ENTRY_LIFETIME 5
#define WS_NEIGHBOUR_DHCP_ENTRY_LIFETIME 60
#define WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT_LARGE 520
@ -254,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
@ -269,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
@ -321,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

@ -422,4 +422,26 @@ int ws_device_min_sens_set(
return -1;
}
int ws_test_neighbour_temporary_lifetime_set(int8_t interface_id, uint32_t temporary_lifetime)
{
(void) interface_id;
(void) temporary_lifetime;
return -1;
}
void ws_test_skip_edfe_data_send(int8_t interface_id, bool skip)
{
(void) interface_id;
(void) skip;
}
int8_t ws_test_drop_edfe_data_frames(int8_t interface_id, uint8_t number_of_dropped_frames)
{
(void) interface_id;
(void) number_of_dropped_frames;
return -1;
}
#endif // no HAVE_WS

View File

@ -537,7 +537,7 @@ static void ws_llc_mac_confirm_cb(const mac_api_t *api, const mcps_data_conf_t *
ws_llc_mpx_eapol_send(base, message);
}
} else {
if (neighbor_info.ws_neighbor && neighbor_info.neighbor && neighbor_info.neighbor->link_lifetime != WS_NEIGHBOR_LINK_TIMEOUT) {
if (neighbor_info.ws_neighbor && neighbor_info.neighbor && neighbor_info.neighbor->link_lifetime < WS_NEIGHBOUR_TEMPORARY_NEIGH_MAX_LIFETIME) {
//Remove temp neighbour
tr_debug("Remove Temp Entry by TX confirm");
mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), neighbor_info.neighbor);
@ -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

@ -108,7 +108,7 @@ typedef struct {
bool gtk_new_act_time_exp: 1; /**< GTK new activation time expired */
} pae_auth_t;
static int8_t ws_pae_auth_network_keys_from_gtks_set(pae_auth_t *pae_auth);
static int8_t ws_pae_auth_network_keys_from_gtks_set(pae_auth_t *pae_auth, bool force_install);
static int8_t ws_pae_auth_active_gtk_set(pae_auth_t *pae_auth, uint8_t index);
static int8_t ws_pae_auth_network_key_index_set(pae_auth_t *pae_auth, uint8_t index);
static void ws_pae_auth_free(pae_auth_t *pae_auth);
@ -345,7 +345,7 @@ void ws_pae_auth_start(protocol_interface_info_entry_t *interface_ptr)
pae_auth->nw_info_updated(pae_auth->interface_ptr);
// Inserts keys and updates GTK hash on stack
ws_pae_auth_network_keys_from_gtks_set(pae_auth);
ws_pae_auth_network_keys_from_gtks_set(pae_auth, false);
// Sets active key index
ws_pae_auth_network_key_index_set(pae_auth, index);
@ -362,7 +362,7 @@ void ws_pae_auth_gtks_updated(protocol_interface_info_entry_t *interface_ptr)
return;
}
ws_pae_auth_network_keys_from_gtks_set(pae_auth);
ws_pae_auth_network_keys_from_gtks_set(pae_auth, false);
}
int8_t ws_pae_auth_nw_key_index_update(protocol_interface_info_entry_t *interface_ptr, uint8_t index)
@ -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
@ -470,7 +470,7 @@ int8_t ws_pae_auth_node_access_revoke_start(protocol_interface_info_entry_t *int
// Adds new GTK
ws_pae_auth_gtk_key_insert(pae_auth);
ws_pae_auth_network_keys_from_gtks_set(pae_auth);
ws_pae_auth_network_keys_from_gtks_set(pae_auth, false);
// Update keys to NVM as needed
pae_auth->nw_info_updated(pae_auth->interface_ptr);
@ -535,8 +535,11 @@ int8_t ws_pae_auth_nw_info_set(protocol_interface_info_entry_t *interface_ptr, u
}
pae_auth->pan_id = pan_id;
bool force_install = false;
if (strlen((char *) &pae_auth->network_name) > 0 && strcmp((char *) &pae_auth->network_name, network_name) != 0) {
update_keys = true;
// Force GTK install to update the new network name to GAK
force_install = true;
}
strcpy((char *) &pae_auth->network_name, network_name);
@ -548,7 +551,7 @@ int8_t ws_pae_auth_nw_info_set(protocol_interface_info_entry_t *interface_ptr, u
pae_auth->nw_keys_remove(pae_auth->interface_ptr);
}
ws_pae_auth_network_keys_from_gtks_set(pae_auth);
ws_pae_auth_network_keys_from_gtks_set(pae_auth, force_install);
int8_t index = sec_prot_keys_gtk_status_active_get(pae_auth->sec_keys_nw_info->gtks);
if (index >= 0) {
@ -559,7 +562,7 @@ int8_t ws_pae_auth_nw_info_set(protocol_interface_info_entry_t *interface_ptr, u
return 0;
}
static int8_t ws_pae_auth_network_keys_from_gtks_set(pae_auth_t *pae_auth)
static int8_t ws_pae_auth_network_keys_from_gtks_set(pae_auth_t *pae_auth, bool force_install)
{
// Authenticator keys are always fresh
sec_prot_keys_gtk_status_all_fresh_set(pae_auth->sec_keys_nw_info->gtks);
@ -571,7 +574,7 @@ static int8_t ws_pae_auth_network_keys_from_gtks_set(pae_auth_t *pae_auth)
}
if (pae_auth->nw_key_insert) {
pae_auth->nw_key_insert(pae_auth->interface_ptr, pae_auth->sec_keys_nw_info->gtks);
pae_auth->nw_key_insert(pae_auth->interface_ptr, pae_auth->sec_keys_nw_info->gtks, force_install);
}
return 0;
@ -707,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);
@ -716,7 +719,7 @@ void ws_pae_auth_slow_timer(uint16_t seconds)
if (second_index < 0) {
tr_info("GTK new install required active index: %i, time: %"PRIu32", system time: %"PRIu32"", active_index, timer_seconds, protocol_core_monotonic_time / 10);
ws_pae_auth_gtk_key_insert(pae_auth);
ws_pae_auth_network_keys_from_gtks_set(pae_auth);
ws_pae_auth_network_keys_from_gtks_set(pae_auth, false);
// Update keys to NVM as needed
pae_auth->nw_info_updated(pae_auth->interface_ptr);
} else {
@ -744,7 +747,7 @@ void ws_pae_auth_slow_timer(uint16_t seconds)
if (timer_seconds == 0) {
tr_info("GTK expired index: %i, system time: %"PRIu32"", i, protocol_core_monotonic_time / 10);
ws_pae_auth_gtk_clear(pae_auth, i);
ws_pae_auth_network_keys_from_gtks_set(pae_auth);
ws_pae_auth_network_keys_from_gtks_set(pae_auth, false);
// Update keys to NVM as needed
pae_auth->nw_info_updated(pae_auth->interface_ptr);
}

View File

@ -207,12 +207,13 @@ typedef void ws_pae_auth_gtk_hash_set(protocol_interface_info_entry_t *interface
*
* \param interface_ptr interface
* \param gtks group keys
* \param force_install TRUE force install keys, FALSE install keys only if GTKs has changed
*
* \return < 0 failure
* \return >= 0 success
*
*/
typedef int8_t ws_pae_auth_nw_key_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks);
typedef int8_t ws_pae_auth_nw_key_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks, bool force_install);
/**
* ws_pae_auth_nw_keys_remove remove network keys callback

View File

@ -126,7 +126,7 @@ static void ws_pae_controller_nvm_frame_counter_write(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);
static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks);
static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks, bool force_install);
static void ws_pae_controller_active_nw_key_clear(nw_key_t *nw_key);
static void ws_pae_controller_active_nw_key_set(protocol_interface_info_entry_t *cur, uint8_t index);
static int8_t ws_pae_controller_gak_from_gtk(uint8_t *gak, uint8_t *gtk, char *network_name);
@ -137,6 +137,7 @@ static void ws_pae_controller_nw_key_index_check_and_set(protocol_interface_info
static void ws_pae_controller_data_init(pae_controller_t *controller);
static int8_t ws_pae_controller_frame_counter_read(pae_controller_t *controller);
static void ws_pae_controller_frame_counter_reset(frame_counters_t *frame_counters);
static void ws_pae_controller_frame_counter_index_reset(frame_counters_t *frame_counters, uint8_t index);
static int8_t ws_pae_controller_nw_info_read(pae_controller_t *controller, sec_prot_gtk_keys_t *gtks);
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);
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);
@ -165,7 +166,7 @@ int8_t ws_pae_controller_authenticate(protocol_interface_info_entry_t *interface
// In case test keys are set uses those and does not initiate authentication
if (controller->gtks_set) {
if (sec_prot_keys_gtks_are_updated(&controller->gtks)) {
ws_pae_controller_nw_key_check_and_insert(controller->interface_ptr, &controller->gtks);
ws_pae_controller_nw_key_check_and_insert(controller->interface_ptr, &controller->gtks, false);
sec_prot_keys_gtks_updated_reset(&controller->gtks);
ws_pae_supp_gtks_set(controller->interface_ptr, &controller->gtks);
}
@ -403,7 +404,7 @@ int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface
return ws_pae_supp_nw_key_valid(interface_ptr, br_iid);
}
static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks)
static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks, bool force_install)
{
pae_controller_t *controller = ws_pae_controller_get(interface_ptr);
if (!controller) {
@ -429,6 +430,13 @@ static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_
tr_info("NW key remove: %i", i);
}
if (force_install) {
// Install always
nw_key[i].installed = false;
// Frame counters are fresh
ws_pae_controller_frame_counter_index_reset(&controller->frame_counters, i);
}
// If GTK key is not set, continues to next GTK
if (!gtk) {
continue;
@ -775,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;
@ -798,13 +812,18 @@ static int8_t ws_pae_controller_frame_counter_read(pae_controller_t *controller)
static void ws_pae_controller_frame_counter_reset(frame_counters_t *frame_counters)
{
for (uint8_t index = 0; index < GTK_NUM; index++) {
memset(frame_counters->counter[index].gtk, 0, GTK_LEN);
frame_counters->counter[index].frame_counter = 0;
frame_counters->counter[index].stored_frame_counter = 0;
frame_counters->counter[index].set = false;
ws_pae_controller_frame_counter_index_reset(frame_counters, index);
}
}
static void ws_pae_controller_frame_counter_index_reset(frame_counters_t *frame_counters, uint8_t index)
{
memset(frame_counters->counter[index].gtk, 0, GTK_LEN);
frame_counters->counter[index].frame_counter = 0;
frame_counters->counter[index].stored_frame_counter = 0;
frame_counters->counter[index].set = false;
}
static int8_t ws_pae_controller_nw_info_read(pae_controller_t *controller, sec_prot_gtk_keys_t *gtks)
{
if (ws_pae_controller_nvm_nw_info_read(controller->interface_ptr, &controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, gtks) < 0) {
@ -878,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

@ -355,7 +355,7 @@ int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_pt
}
// Modify keys
pae_supp->nw_key_insert(pae_supp->interface_ptr, pae_supp->sec_keys_nw_info->gtks);
pae_supp->nw_key_insert(pae_supp->interface_ptr, pae_supp->sec_keys_nw_info->gtks, false);
return 0;
}
@ -521,7 +521,7 @@ static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan
(sec_prot_keys_pmk_get(&pae_supp->entry.sec_keys) != NULL) &&
(sec_prot_keys_ptk_get(&pae_supp->entry.sec_keys) != NULL)) {
tr_debug("Existing keys used, counter %i", pae_supp->nw_keys_used_cnt);
if (pae_supp->nw_key_insert(pae_supp->interface_ptr, pae_supp->sec_keys_nw_info->gtks) >= 0) {
if (pae_supp->nw_key_insert(pae_supp->interface_ptr, pae_supp->sec_keys_nw_info->gtks, false) >= 0) {
tr_debug("Keys inserted");
}
pae_supp->nw_keys_used_cnt++;
@ -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) {
@ -1260,7 +1262,7 @@ static void ws_pae_supp_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e
if ((type == IEEE_802_11_4WH || type == IEEE_802_11_GKH) && result == KMP_RESULT_OK) {
if (sec_keys) {
sec_prot_keys_t *keys = sec_keys;
pae_supp->nw_key_insert(pae_supp->interface_ptr, keys->gtks);
pae_supp->nw_key_insert(pae_supp->interface_ptr, keys->gtks, false);
}
ws_pae_supp_authenticate_response(pae_supp, AUTH_RESULT_OK);

View File

@ -221,12 +221,13 @@ typedef const uint8_t *ws_pae_supp_auth_next_target(protocol_interface_info_entr
*
* \param interface_ptr interface
* \param gtks group keys
* \param force_install TRUE force install keys, FALSE install keys only if GTKs has changed
*
* \return < 0 failure
* \return >= 0 success
*
*/
typedef int8_t ws_pae_supp_nw_key_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks);
typedef int8_t ws_pae_supp_nw_key_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks, bool force_install);
/**
* ws_pae_supp_gtk_hash_ptr_get get pointer to GTK hash storage callback

View File

@ -164,4 +164,17 @@ int ws_test_6lowpan_fragmentation_mtu_size_set(int8_t interface_id, uint16_t mtu
return 0;
}
int ws_test_neighbour_temporary_lifetime_set(int8_t interface_id, uint32_t temporary_lifetime)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
return -1;
}
ws_cfg_neighbour_temporary_lifetime_set(temporary_lifetime);
return 0;
}
#endif // HAVE_WS

View File

@ -1794,6 +1794,9 @@ int8_t mcps_generic_edfe_frame_init(protocol_interface_rf_mac_setup_s *rf_ptr, c
//Data Here
mac_pre_build_frame_t *buffer;
if (response->wait_response) {
if (rf_ptr->active_pd_data_request == NULL) {
return -1;
}
buffer = rf_ptr->active_pd_data_request;
buffer->message_builded = false;
} else {

View File

@ -179,6 +179,7 @@ struct rpl_instance {
bool dao_in_transit: 1; /* If we have a DAO in transit */
bool requested_dao_ack: 1; /* If we requested an ACK (so we retry if no ACK, rather than assuming success) */
bool pending_neighbour_confirmation: 1; /* if we have not finished address registration state to parent */
bool parent_was_selected: 1;
uint8_t poison_count;
uint8_t repair_dis_count;
uint16_t repair_dis_timer;

View File

@ -1516,6 +1516,7 @@ void rpl_instance_run_parent_selection(rpl_instance_t *instance)
if (preferred_parent) {
// Always stop repair if we find a parent
rpl_instance_set_local_repair(instance, false);
instance->parent_was_selected = true;
//Validate time from last DIO
uint32_t time_between_parent = protocol_core_monotonic_time - preferred_parent->dio_timestamp;
@ -1525,11 +1526,12 @@ void rpl_instance_run_parent_selection(rpl_instance_t *instance)
rpl_control_transmit_dis(instance->domain, NULL, RPL_SOLINFO_PRED_INSTANCEID, instance->id, NULL, 0, preferred_parent->ll_address);
}
} else if (original_preferred) {
// Only start repair if we just lost a parent
} else if (instance->parent_was_selected) {
// Only start repair if we just lost a parent or current rank goes to infinity
rpl_instance_set_local_repair(instance, true);
instance->parent_was_selected = false;
} else {
// !preferred_parent && !original_preferred - didn't have a parent,
// !preferred_parent && !instance->parent_was_selected - didn't have a parent,
// still don't. Leave repair flag as-is (would be off on initial start
// up, may be on if having problems mid-session).
}

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

@ -79,6 +79,8 @@ typedef enum {
#define RADIUS_ID_RANGE_SIZE 10
#define RADIUS_ID_RANGE_NUM (255 / RADIUS_ID_RANGE_SIZE) - 1
#define RADIUS_ID_TIMEOUT 60
typedef struct radius_client_sec_prot_lib_int_s radius_client_sec_prot_lib_int_t;
typedef struct {
@ -120,7 +122,6 @@ typedef struct {
static uint16_t radius_client_sec_prot_size(void);
static int8_t radius_client_sec_prot_init(sec_prot_t *prot);
static int8_t radius_client_sec_prot_shared_data_timeout(uint16_t ticks);
static void radius_identifier_timer_value_set(uint8_t conn_num, uint8_t id_range, uint8_t value);
static int8_t radius_client_sec_prot_shared_data_delete(void);
static void radius_identifier_timer_value_set(uint8_t conn_num, uint8_t id_range, uint8_t value);
static void radius_client_sec_prot_create_response(sec_prot_t *prot, sec_prot_result_e result);
@ -541,17 +542,17 @@ static uint8_t radius_client_sec_prot_identifier_allocate(sec_prot_t *prot, uint
{
radius_client_sec_prot_int_t *data = radius_client_sec_prot_get(prot);
if (!data->radius_id_range_set || value >= (data->radius_id_range * RADIUS_ID_RANGE_SIZE) + RADIUS_ID_RANGE_SIZE) {
if (!data->radius_id_range_set || value >= (data->radius_id_range * RADIUS_ID_RANGE_SIZE) + RADIUS_ID_RANGE_SIZE - 1) {
for (uint8_t conn_num = 0; conn_num < RADIUS_CONN_NUMBER; conn_num++) {
for (uint8_t id_range = 0; id_range < RADIUS_ID_RANGE_NUM; id_range++) {
if (shared_data->radius_identifier_timer[conn_num][id_range] == 0) {
// If range has been already reserved
if (data->radius_id_range_set) {
// Set previous range to timeout in 5 seconds
radius_identifier_timer_value_set(data->radius_id_conn_num, data->radius_id_range, 5);
// Set previous range to timeout at 1/5 of identifier timeout
radius_identifier_timer_value_set(data->radius_id_conn_num, data->radius_id_range, RADIUS_ID_TIMEOUT / 5);
}
// Set timeout for new range to 60 seconds
radius_identifier_timer_value_set(conn_num, id_range, 60);
radius_identifier_timer_value_set(conn_num, id_range, RADIUS_ID_TIMEOUT);
data->radius_id_conn_num = conn_num;
data->radius_id_range = id_range;
data->radius_id_range_set = true;
@ -560,7 +561,7 @@ static uint8_t radius_client_sec_prot_identifier_allocate(sec_prot_t *prot, uint
}
}
} else {
radius_identifier_timer_value_set(data->radius_id_conn_num, data->radius_id_range, 60);
radius_identifier_timer_value_set(data->radius_id_conn_num, data->radius_id_range, RADIUS_ID_TIMEOUT);
return value + 1;
}
@ -572,7 +573,8 @@ static void radius_client_sec_prot_identifier_free(sec_prot_t *prot)
radius_client_sec_prot_int_t *data = radius_client_sec_prot_get(prot);
if (data->radius_id_range_set) {
radius_identifier_timer_value_set(data->radius_id_conn_num, data->radius_id_range, 5);
// Timeout at 1/5 of identifier timeout
radius_identifier_timer_value_set(data->radius_id_conn_num, data->radius_id_range, RADIUS_ID_TIMEOUT / 5);
}
}

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

@ -373,19 +373,23 @@ uint8_t *sec_prot_lib_message_handle(uint8_t *ptk, uint16_t *kde_len, eapol_pdu_
uint8_t *kde = ns_dyn_mem_temporary_alloc(key_data_len);
*kde_len = key_data_len;
if (eapol_pdu->msg.key.key_information.encrypted_key_data) {
size_t output_len = eapol_pdu->msg.key.key_data_length;
if (nist_aes_key_wrap(0, &ptk[KEK_INDEX], 128, key_data, key_data_len, kde, &output_len) < 0 || output_len != (size_t) key_data_len - 8) {
tr_error("Decrypt failed");
ns_dyn_mem_free(kde);
return NULL;
if (kde) {
if (eapol_pdu->msg.key.key_information.encrypted_key_data) {
size_t output_len = eapol_pdu->msg.key.key_data_length;
if (nist_aes_key_wrap(0, &ptk[KEK_INDEX], 128, key_data, key_data_len, kde, &output_len) < 0 || output_len != (size_t) key_data_len - 8) {
tr_error("Decrypt failed");
ns_dyn_mem_free(kde);
return NULL;
}
*kde_len = output_len;
} else {
memcpy(kde, key_data, *kde_len);
}
*kde_len = output_len;
} else {
memcpy(kde, key_data, *kde_len);
return kde;
}
return kde;
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

@ -305,12 +305,12 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
/* Start timer with random timeout to trigger broadcast TX queue poll event.
* Min random is 1/50 of the channel dwell interval.
* Max random is 1/10 of the channel dwell interval.
* Max random is 3/4 of the channel dwell interval.
* Event timer resolution is 50us.
*/
uint32_t bc_dwell_us = MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval);
uint16_t bc_min_random = (bc_dwell_us / 50) / 50;
uint16_t bc_max_random = (bc_dwell_us / 10) / 50;
uint16_t bc_max_random = (bc_dwell_us - (bc_dwell_us / 4)) / 50;
eventOS_callback_timer_start(fhss_structure->fhss_event_timer, randLIB_get_random_in_range(bc_min_random, bc_max_random));
} else {
fhss_structure->ws->unicast_start_time_us = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api);
@ -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;
}

View File

@ -150,15 +150,17 @@ int8_t net_dns_server_search_list_set(int8_t interface_id, const uint8_t address
info_ptr->dns_search_list_ptr = NULL;
}
if (!info_ptr->dns_search_list_ptr) {
info_ptr->dns_search_list_ptr = ns_dyn_mem_alloc(dns_search_list_len);
if (dns_search_list_len) {
if (!info_ptr->dns_search_list_ptr) {
info_ptr->dns_search_list_ptr = ns_dyn_mem_alloc(dns_search_list_len);
}
if (!info_ptr->dns_search_list_ptr) {
return -2;
}
memcpy(info_ptr->dns_search_list_ptr, dns_search_list_ptr, dns_search_list_len);
}
if (!info_ptr->dns_search_list_ptr) {
return -2;
}
memcpy(info_ptr->dns_search_list_ptr, dns_search_list_ptr, dns_search_list_len);
info_ptr->dns_search_list_len = dns_search_list_len;
tr_info("DNS Search List: %s Lifetime: %lu", trace_array(info_ptr->dns_search_list_ptr, info_ptr->dns_search_list_len), (unsigned long) info_ptr->lifetime);