Skip to content

Commit

Permalink
Added ETX to rpl_possible_better_candidate
Browse files Browse the repository at this point in the history
ETX may be 0 when it is new neighbour and then etx is optimistic 128.

Change-Id: Ic5ed0d453d04a16ead9d040217cd132b5d35e366
  • Loading branch information
Juha Heiskanen committed Dec 2, 2019
1 parent 3441594 commit 1b99fe1
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 30 deletions.
41 changes: 26 additions & 15 deletions source/6LoWPAN/ws/ws_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2147,10 +2147,17 @@ static bool ws_rpl_new_parent_callback(uint8_t *ll_parent_address, void *handle,
}

uint8_t replacing[16];
uint8_t mac64[8];
uint8_t mac64[10];
bool replace_ok = false;
bool create_ok = false;
llc_neighbour_req_t neigh_buffer;

//Discover neigh ready here for possible ETX validate
memcpy(mac64, ll_parent_address + 8, 8);
mac64[0] ^= 2;

ws_bootstrap_neighbor_info_request(cur, mac64, &neigh_buffer, false);

if (rpl_control_candidate_list_size(cur, instance) < cur->ws_info->rpl_parent_candidate_max) {
//Not reach max value yet accept then all go to create neigh table
goto neigh_create;
Expand All @@ -2161,20 +2168,22 @@ static bool ws_rpl_new_parent_callback(uint8_t *ll_parent_address, void *handle,
return false;
}

// if not yet probed, return false
memcpy(mac64, replacing + 8, 8);
mac64[0] ^= 2;
// +2 Is for PAN ID space
memcpy(mac64 + 2, replacing + 8, 8);
mac64[2] ^= 2;

if (ws_bootstrap_neighbor_info_request(cur, mac64, &neigh_buffer, false)) {
//Verify that we have proped min 1 time
etx_storage_t *etx_entry = etx_storage_entry_get(cur->id, neigh_buffer.neighbor->index);
if (etx_entry && etx_entry->etx_samples == 0) {
return false;
}
if (ws_etx_read(cur, ADDR_802_15_4_LONG, mac64) == 0xffff) {
//Not proped yet because ETX is 0xffff
return false;
}

uint16_t etx = 0;
if (neigh_buffer.neighbor) {
etx = etx_local_etx_read(cur->id, neigh_buffer.neighbor->index);
}

// Accept now only better one's when max candidates slected and max candidate list size is reached
if (!rpl_possible_better_candidate(cur, instance, replacing, candidate_rank)) {
if (!rpl_possible_better_candidate(cur, instance, replacing, candidate_rank, etx)) {
return false;
}
//TODO if replacing has poor ETX, put it in blacklist as "poor ETX" to prevent reselection
Expand All @@ -2183,14 +2192,16 @@ static bool ws_rpl_new_parent_callback(uint8_t *ll_parent_address, void *handle,

neigh_create:

memcpy(mac64, ll_parent_address + 8, 8);
mac64[0] ^= 2;
if (ws_bootstrap_neighbor_info_request(cur, mac64, &neigh_buffer, false)) {

if (neigh_buffer.neighbor) {
//Use Already discovered entry
create_ok = true;
goto neigh_create_ok;
}

//Discover Multicast temporary entry
//Discover Multicast temporary entry for create neighbour table entry for new candidate
memcpy(mac64, ll_parent_address + 8, 8);
mac64[0] ^= 2;
ws_neighbor_temp_class_t *entry = ws_llc_get_multicast_temp_entry(cur, mac64);
if (!entry) {
return false;
Expand Down
7 changes: 3 additions & 4 deletions source/RPL/rpl_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ bool rpl_control_probe_parent_candidate(protocol_interface_info_entry_t *interfa
return false;
}

bool rpl_possible_better_candidate(struct protocol_interface_info_entry *interface, rpl_instance_t *rpl_instance, const uint8_t ll_addr[16], uint16_t candidate_rank)
bool rpl_possible_better_candidate(struct protocol_interface_info_entry *interface, rpl_instance_t *rpl_instance, const uint8_t ll_addr[16], uint16_t candidate_rank, uint16_t etx)
{
if (!interface->rpl_domain) {
return false;
Expand All @@ -283,7 +283,7 @@ bool rpl_possible_better_candidate(struct protocol_interface_info_entry *interfa
return false;
}

return rpl_instance_possible_better_candidate(rpl_instance, neighbour, candidate_rank);
return rpl_instance_possible_better_candidate(rpl_instance, neighbour, candidate_rank, etx);

}

Expand Down Expand Up @@ -1847,9 +1847,8 @@ void rpl_control_print(route_print_fn_t *print_fn)
unsigned s = s_full % 60;
unsigned h = m / 60;
m %= 60;
print_fn("Time %02u:%02u:%02u.%u (%u.%u)", h, m, s, t, s_full, t);
// %zu doesn't work on some Mbed toolchains
print_fn("RPL memory usage %" PRIu32, (uint32_t) rpl_alloc_total);
print_fn("Time %02u:%02u:%02u.%u (%u.%u) RPL memory usage %" PRIu32, h, m, s, t, s_full, t, (uint32_t) rpl_alloc_total);
ns_list_foreach(rpl_domain_t, domain, &rpl_domains) {
rpl_domain_print(domain, print_fn);
}
Expand Down
2 changes: 1 addition & 1 deletion source/RPL/rpl_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ void rpl_control_unpublish_address(rpl_domain_t *domain, const uint8_t addr[16])
bool rpl_control_is_dodag_parent(struct protocol_interface_info_entry *interface, const uint8_t ll_addr[16]);
bool rpl_control_is_dodag_parent_candidate(struct protocol_interface_info_entry *interface, const uint8_t ll_addr[16], uint16_t candidate_cmp_limiter);
bool rpl_control_probe_parent_candidate(struct protocol_interface_info_entry *interface, const uint8_t ll_addr[16]);
bool rpl_possible_better_candidate(struct protocol_interface_info_entry *interface, struct rpl_instance *rpl_instance, const uint8_t ll_addr[16], uint16_t candidate_rank);
bool rpl_possible_better_candidate(struct protocol_interface_info_entry *interface, struct rpl_instance *rpl_instance, const uint8_t ll_addr[16], uint16_t candidate_rank, uint16_t etx);
uint16_t rpl_control_parent_candidate_list_size(struct protocol_interface_info_entry *interface, bool parent_list);
uint16_t rpl_control_candidate_list_size(struct protocol_interface_info_entry *interface, struct rpl_instance *rpl_instance);
void rpl_control_neighbor_delete(struct protocol_interface_info_entry *interface, const uint8_t ll_addr[16]);
Expand Down
14 changes: 11 additions & 3 deletions source/RPL/rpl_mrhof.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
static void rpl_mrhof_parent_selection(rpl_instance_t *instance);
static uint16_t rpl_mrhof_path_cost_through_neighbour(const rpl_neighbour_t *neighbour);
static bool rpl_mrhof_neighbour_acceptable(const rpl_instance_t *instance, const rpl_neighbour_t *neighbour);
static bool rpl_mrhof_possible_better_candidate(const rpl_instance_t *instance, const rpl_neighbour_t *existing, uint16_t rank);
static bool rpl_mrhof_possible_better_candidate(const rpl_instance_t *instance, const rpl_neighbour_t *existing, uint16_t rank, uint16_t etx);

static rpl_objective_t rpl_mrhof = {
.ocp = RPL_OCP_MRHOF,
Expand Down Expand Up @@ -96,7 +96,7 @@ static bool rpl_mrhof_neighbour_acceptable(const rpl_instance_t *instance, const
return rpl_mrhof_link_metric_to_neighbour(neighbour) <= rpl_policy_mrhof_max_link_metric(instance->domain);
}

static bool rpl_mrhof_possible_better_candidate(const rpl_instance_t *instance, const rpl_neighbour_t *existing, uint16_t rank)
static bool rpl_mrhof_possible_better_candidate(const rpl_instance_t *instance, const rpl_neighbour_t *existing, uint16_t rank, uint16_t etx)
{
uint16_t existing_path = rpl_mrhof_path_cost_through_neighbour(existing);
// Optimistically assume we could get a perfect link to this new person
Expand All @@ -105,7 +105,15 @@ static bool rpl_mrhof_possible_better_candidate(const rpl_instance_t *instance,
// Think: could actually use rpl_mrhof_etx here to get an existing ETX estimate
// (except that gives infinite if no current link, would want a variant that checks
// blacklist records for remembered poor ETX)
uint16_t potential_path_with_hysteresis = rpl_rank_add(rank, 128 + rpl_policy_mrhof_parent_switch_threshold(instance->domain));
uint16_t threshold = rpl_policy_mrhof_parent_switch_threshold(instance->domain);
if (etx == 0) {
etx = 128;
} else if (etx >= (0xffff - threshold)) {
return false;
}

etx += threshold;
uint16_t potential_path_with_hysteresis = rpl_rank_add(rank, etx);
return potential_path_with_hysteresis <= existing_path;
}

Expand Down
2 changes: 1 addition & 1 deletion source/RPL/rpl_objective.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ typedef struct rpl_objective {
bool (*neighbour_acceptable)(const struct rpl_instance *, const struct rpl_neighbour *);
/* Could someone with specified rank be a significantly better candidate than the existing one? */
/* (In future, this API could be extended to pass a metric pointer as well as rank) */
bool (*possible_better_candidate)(const struct rpl_instance *, const struct rpl_neighbour *existing, uint16_t rank);
bool (*possible_better_candidate)(const struct rpl_instance *, const struct rpl_neighbour *existing, uint16_t rank, uint16_t etx);
ns_list_link_t link;
} rpl_objective_t;

Expand Down
5 changes: 3 additions & 2 deletions source/RPL/rpl_of0.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
static void rpl_of0_parent_selection(rpl_instance_t *instance);
static uint16_t rpl_of0_rank_through_neighbour(const rpl_neighbour_t *neighbour);
static bool rpl_of0_neighbour_acceptable(const rpl_instance_t *instance, const rpl_neighbour_t *neighbour);
static bool rpl_of0_possible_better_candidate(const rpl_instance_t *instance, const rpl_neighbour_t *existing, uint16_t rank);
static bool rpl_of0_possible_better_candidate(const rpl_instance_t *instance, const rpl_neighbour_t *existing, uint16_t rank, uint16_t etx);

static rpl_objective_t rpl_of0 = {
.ocp = RPL_OCP_OF0,
Expand Down Expand Up @@ -117,8 +117,9 @@ static uint16_t rpl_of0_rank_through_neighbour(const rpl_neighbour_t *neighbour)
return rpl_rank_add(neighbour->rank, rpl_of0_rank_increase(neighbour));
}

static bool rpl_of0_possible_better_candidate(const rpl_instance_t *instance, const rpl_neighbour_t *existing, uint16_t rank)
static bool rpl_of0_possible_better_candidate(const rpl_instance_t *instance, const rpl_neighbour_t *existing, uint16_t rank, uint16_t etx)
{
(void)etx;
uint16_t existing_path = rpl_of0_rank_through_neighbour(existing);
uint16_t potential_path_with_hysteresis = rpl_rank_add(rank, 2 * rpl_policy_of0_rank_factor(instance->domain) * existing->dodag_version->dodag->config.min_hop_rank_increase);
return potential_path_with_hysteresis <= existing_path;
Expand Down
4 changes: 2 additions & 2 deletions source/RPL/rpl_upward.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,9 @@ uint16_t rpl_instance_candidate_rank(const rpl_neighbour_t *candidate)
return candidate->rank;
}

bool rpl_instance_possible_better_candidate(const rpl_instance_t *instance, rpl_neighbour_t *replacing, uint16_t candidate_rank)
bool rpl_instance_possible_better_candidate(const rpl_instance_t *instance, rpl_neighbour_t *replacing, uint16_t candidate_rank, uint16_t etx)
{
return instance->of->possible_better_candidate(instance, replacing, candidate_rank);
return instance->of->possible_better_candidate(instance, replacing, candidate_rank, etx);
}

/* If we're a member of a DODAG Version matching the predicate in this instance,
Expand Down
2 changes: 1 addition & 1 deletion source/RPL/rpl_upward.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ bool rpl_instance_am_root(const rpl_instance_t *instance);
uint8_t rpl_instance_mop(const rpl_instance_t *instance);
rpl_dodag_version_t *rpl_instance_current_dodag_version(const rpl_instance_t *instance);
rpl_neighbour_t *rpl_instance_preferred_parent(const rpl_instance_t *instance);
bool rpl_instance_possible_better_candidate(const rpl_instance_t *instance, rpl_neighbour_t *replacing, uint16_t candidate_rank);
bool rpl_instance_possible_better_candidate(const rpl_instance_t *instance, rpl_neighbour_t *replacing, uint16_t candidate_rank, uint16_t etx);
rpl_dodag_version_t *rpl_instance_predicate_match(rpl_instance_t *instance, uint8_t pred, uint8_t instance_id, const uint8_t *dodagid, uint8_t version_num);
void rpl_instance_inconsistency(rpl_instance_t *instance);
void rpl_instance_consistent_rx(rpl_instance_t *instance);
Expand Down
2 changes: 1 addition & 1 deletion test/nanostack/unittest/stub/rpl_control_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ bool rpl_control_probe_parent_candidate(protocol_interface_info_entry_t *interfa
return false;
}

bool rpl_possible_better_candidate(struct protocol_interface_info_entry *interface, struct rpl_instance *rpl_instance, const uint8_t ll_addr[16], uint16_t candidate_rank)
bool rpl_possible_better_candidate(struct protocol_interface_info_entry *interface, struct rpl_instance *rpl_instance, const uint8_t ll_addr[16], uint16_t candidate_rank, uint16_t etx)
{
return true;
}
Expand Down
5 changes: 5 additions & 0 deletions test/nanostack/unittest/stub/rpl_upward_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,4 +503,9 @@ uint16_t rpl_instance_candidate_rank(const rpl_neighbour_t *candidate)
return 0xffff;
}

bool rpl_instance_possible_better_candidate(const rpl_instance_t *instance, rpl_neighbour_t *replacing, uint16_t candidate_rank, uint16_t etx)
{
return false;
}

#endif /* HAVE_RPL */

0 comments on commit 1b99fe1

Please sign in to comment.