Skip to content

Commit

Permalink
Additional check to detect parent connection problem
Browse files Browse the repository at this point in the history
When we hear Advertisement SOLICIT or Configuration SOLICIT or RPL DIS
from parent we confirm the parent connection by registering ARO address

If RPL goes to local repair state stack will change state to state 4
and sends an disconnection Event to application

When starting rpl_scan the rpl state is initialized
  • Loading branch information
Mika Tervonen authored and Mika Tervonen committed Feb 12, 2021
1 parent ffe48c9 commit 7a3c833
Showing 1 changed file with 90 additions and 38 deletions.
128 changes: 90 additions & 38 deletions source/6LoWPAN/ws/ws_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,

static void ws_address_registration_update(protocol_interface_info_entry_t *interface, const uint8_t addr[16]);
static int8_t ws_bootstrap_neighbor_set(protocol_interface_info_entry_t *cur, parent_info_t *parent_ptr, bool clear_list);
static void ws_bootstrap_parent_confirm(protocol_interface_info_entry_t *cur, struct rpl_instance *instance);

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);
Expand All @@ -120,6 +121,7 @@ static void ws_bootstrap_packet_congestion_init(protocol_interface_info_entry_t

static void ws_bootstrap_asynch_trickle_stop(protocol_interface_info_entry_t *cur);
static void ws_bootstrap_advertise_start(protocol_interface_info_entry_t *cur);
static void ws_bootstrap_rpl_scan_start(protocol_interface_info_entry_t *cur);

typedef enum {
WS_PARENT_SOFT_SYNCH = 0, /**< let FHSS make decision if synchronization is needed*/
Expand Down Expand Up @@ -1617,6 +1619,13 @@ static void ws_bootstrap_pan_advertisement_solicit_analyse(struct protocol_inter

tr_info("Making parent selection in %u s", (cur->bootsrap_state_machine_cnt / 10));
}

if (ws_bootstrap_state_active(cur) && cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(cur), data->SrcAddr, ADDR_802_15_4_LONG);
if (neighbor && neighbor->link_role == PRIORITY_PARENT_NEIGHBOUR) {
ws_bootstrap_parent_confirm(cur, NULL);
}
}
}


Expand Down Expand Up @@ -1803,7 +1812,12 @@ static void ws_bootstrap_pan_config_solicit_analyse(struct protocol_interface_in
ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us, &cur->ws_info->hopping_schdule);
}


if (ws_bootstrap_state_active(cur) && cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(cur), data->SrcAddr, ADDR_802_15_4_LONG);
if (neighbor && neighbor->link_role == PRIORITY_PARENT_NEIGHBOUR) {
ws_bootstrap_parent_confirm(cur, NULL);
}
}

/*
* A consistent transmission is defined as a PAN Configuration Solicit with
Expand Down Expand Up @@ -2605,6 +2619,63 @@ static void ws_address_parent_update(protocol_interface_info_entry_t *interface)
ws_address_registration_update(interface, NULL);
}

static void ws_bootstrap_parent_confirm(protocol_interface_info_entry_t *cur, struct rpl_instance *instance)
{
/* Possible problem with the parent connection
* Give some time for parent to rejoin and confirm the connection with ARO and DAO
*/
const rpl_dodag_conf_t *config = NULL;
uint32_t Imin_secs = 0;

if (!ws_bootstrap_state_active(cur)) {
// If we are not in Active state no need to confirm parent
return;
}

tr_info("RPL parent confirm");

if (!instance) {
// If we dont have instance we take any available to get reference
instance = rpl_control_enumerate_instances(cur->rpl_domain, NULL);
}

if (instance) {
config = rpl_control_get_dodag_config(instance);
}

if (config) {
//dio imin Period caluclate in seconds
uint32_t Imin_ms = config->dio_interval_min < 32 ? (1ul << config->dio_interval_min) : 0xfffffffful;
//Covert to seconds and multiple by 2 so we give time to recovery so divide by 500 do that operation
Imin_secs = (Imin_ms + 499) / 500;

if (Imin_secs > 0xffff) {
Imin_secs = 0xffff;
}
}
if (Imin_secs == 0) {
// If we dont have RPL configuration we assume conservative value
Imin_secs = 60;
}

/*Speed up the ARO registration*/
if (cur->ws_info->aro_registration_timer > Imin_secs) {
cur->ws_info->aro_registration_timer = Imin_secs;
}
}

static void ws_rpl_parent_dis_callback(const uint8_t *ll_parent_address, void *handle, struct rpl_instance *instance)
{
(void) ll_parent_address;
protocol_interface_info_entry_t *cur = handle;
if (!cur->rpl_domain || cur->interface_mode != INTERFACE_UP) {
return;
}
//Multicast DIS from parent indicate that Parent is not valid in short time window possible
ws_bootstrap_parent_confirm(cur, instance);
}


static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
{

Expand Down Expand Up @@ -2670,10 +2741,14 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)

} else if (event == RPL_EVENT_LOCAL_REPAIR_START) {
tr_debug("RPL local repair start");
//Disable Asynchs
ws_bootstrap_asynch_trickle_stop(cur);
ws_nwk_event_post(cur, ARM_NWK_NWK_CONNECTION_DOWN);

//Disable Async and go to state 4 to confirm parent connection
ws_bootstrap_parent_confirm(cur, NULL);
// Move to state 4 if we see issues with primary parent
if (ws_bootstrap_state_active(cur)) {
tr_info("Move state 4 to wait parent connection confirmation");
ws_bootstrap_rpl_scan_start(cur);
ws_nwk_event_post(cur, ARM_NWK_NWK_CONNECTION_DOWN);
}
} else if (event == RPL_EVENT_DAO_PARENT_ADD) {
ws_address_parent_update(cur);
}
Expand Down Expand Up @@ -2880,34 +2955,6 @@ static bool ws_rpl_new_parent_callback(uint8_t *ll_parent_address, void *handle,
return create_ok;
}

static void ws_rpl_parent_dis_callback(const uint8_t *ll_parent_address, void *handle, struct rpl_instance *instance)
{
(void) ll_parent_address;
protocol_interface_info_entry_t *cur = handle;
if (!cur->rpl_domain || cur->interface_mode != INTERFACE_UP) {
return;
}
//Multicast DIS from parent indicate that Parent is not valid in short time window possible
//Here we could trigger ARO registration by Triggle Imin
//Trigger ARO by Imin * 2
const rpl_dodag_conf_t *config = rpl_control_get_dodag_config(instance);
if (!config) {
//dio imin Period caluclate in seconds
uint32_t Imin_ms = config->dio_interval_min < 32 ? (1ul << config->dio_interval_min) : 0xfffffffful;
//Covert to seconds and multiple by 2 so we give time to recovery so divide by 500 do that opeartion
uint32_t Imin_secs = (Imin_ms + 499) / 500;

if (Imin_secs > 0xffff) {
Imin_secs = 0xffff;
}

if (cur->ws_info->aro_registration_timer > Imin_secs) {
cur->ws_info->aro_registration_timer = Imin_secs;
}
}

}

static void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur)
{
tr_debug("RPL Activate");
Expand Down Expand Up @@ -3253,18 +3300,18 @@ static void ws_bootstrap_start_configuration_learn(protocol_interface_info_entry
static void ws_bootstrap_rpl_scan_start(protocol_interface_info_entry_t *cur)
{
tr_debug("Start RPL learn");
// Stop Trickle timers
ws_bootstrap_asynch_trickle_stop(cur);

// routers wait until RPL root is contacted
ws_bootstrap_state_change(cur, ER_RPL_SCAN);
// Change state as the state is checked in state machine
cur->ws_info->rpl_state = RPL_EVENT_LOCAL_REPAIR_START;
//For Large network and medium should do passive scan
if (ws_cfg_network_config_get(cur) > CONFIG_SMALL) {
// Set timeout for check to 30 - 60 seconds
cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(WS_RPL_DIS_INITIAL_TIMEOUT / 2, WS_RPL_DIS_INITIAL_TIMEOUT);
}
/* While in Join State 4, if a non Border Router determines it has been unable to communicate with the PAN Border
* Router for an interval of PAN_TIMEOUT, a node MUST assume failure of the PAN Border Router and MUST
* Transition to Join State 1
*/
ws_common_border_router_alive_update(cur);
}

/*
Expand Down Expand Up @@ -3619,6 +3666,11 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
ws_bootstrap_event_routing_ready(cur);
} else {
ws_bootstrap_rpl_scan_start(cur);
/* While in Join State 4, if a non Border Router determines it has been unable to communicate with the PAN Border
* Router for an interval of PAN_TIMEOUT, a node MUST assume failure of the PAN Border Router and MUST
* Transition to Join State 1
*/
ws_common_border_router_alive_update(cur);
}
break;
case WS_ROUTING_READY:
Expand Down

0 comments on commit 7a3c833

Please sign in to comment.