Skip to content

Commit

Permalink
Add API for partition weighting set (ARMmbed#1513)
Browse files Browse the repository at this point in the history
Add new API for setting partition weighting value.
  • Loading branch information
Arto Kinnunen authored Dec 18, 2017
1 parent 8811d6f commit d5e2198
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 20 deletions.
14 changes: 14 additions & 0 deletions nanostack/thread_management_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,20 @@ int thread_management_device_certificate_set(int8_t interface_id, const unsigned
*/
int thread_management_network_certificate_set(int8_t interface_id, const unsigned char *network_certificate_ptr, uint16_t network_certificate_len, const unsigned char *priv_key_ptr, uint16_t priv_key_len);

/**
* Set Thread partition weighting.
*
* This function sets weighting value for Thread network partition. Interface will be restarted if interface is active and
* new weighting value is different than previous weighting value.
*
* \param interface_id Network interface ID.
* \param partition_weighting New weighting value for Thread partition
*
* \return 0, OK.
* \return <0 fail.
*/
int thread_management_partition_weighting_set(int8_t interface_id, uint8_t partition_weighting);

#ifdef __cplusplus
}
#endif
Expand Down
17 changes: 11 additions & 6 deletions source/6LoWPAN/Thread/thread_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,10 @@ static int thread_router_check_previous_partition_info(protocol_interface_info_e
//check for parameters
return -1;
}
if ((leaderData->partitionId == cur->thread_info->previous_partition_info.partitionId) && (routeTlv->dataPtr[0] == cur->thread_info->previous_partition_info.idSequence)) {
//drop the advertisement
if ((leaderData->partitionId == cur->thread_info->previous_partition_info.partitionId) &&
(leaderData->weighting == cur->thread_info->previous_partition_info.weighting) &&
(routeTlv->dataPtr[0] == cur->thread_info->previous_partition_info.idSequence)) {
//drop the advertisement from previuos partition
return 1;
}
else {
Expand Down Expand Up @@ -499,6 +501,7 @@ int thread_bootstrap_partition_process(protocol_interface_info_entry_t *cur, uin
/*Rule 2: When comparing two singleton or two non-singleton Thread Network Partitions,
the one with the higher 8-bit weight value has higher priority. */
if (heard_partition_leader_data->weighting > current_leader_data->weighting) {
tr_debug("Heard a greater weighting");
return 2;
}

Expand Down Expand Up @@ -526,7 +529,8 @@ int thread_leader_data_validation(protocol_interface_info_entry_t *cur, thread_l
if (!thread_info(cur)->thread_leader_data) {
return -1;
}
if (thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) {
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) ||
(thread_info(cur)->thread_leader_data->weighting != leaderData->weighting)) {
uint8_t routers_in_route_tlv = thread_get_router_count_from_route_tlv(routeTlv);
//partition checks
return thread_bootstrap_partition_process(cur,routers_in_route_tlv,leaderData, routeTlv);
Expand All @@ -535,10 +539,10 @@ int thread_leader_data_validation(protocol_interface_info_entry_t *cur, thread_l
//Should check is there new version numbers
if (common_serial_number_greater_8(leaderData->dataVersion, thread_info(cur)->thread_leader_data->dataVersion) ||
common_serial_number_greater_8(leaderData->stableDataVersion, thread_info(cur)->thread_leader_data->stableDataVersion)) {
// Version number increased
// Version number increased by some-one else -> there is leader in the network
if (thread_info(cur)->leader_private_data) {
tr_error("SEq synch error");
// MUST restart partition
tr_error("Another leader detected -> bootstrap");
thread_bootstrap_reset_restart(cur->id);
return -1;
}
tr_debug("NEW Network Data available");
Expand Down Expand Up @@ -1344,6 +1348,7 @@ static int thread_bootstrap_attach_start(int8_t interface_id, thread_bootsrap_st
tr_debug("Thread ReAttach");
//save the current partition id and sequence number before trying reattach
cur->thread_info->previous_partition_info.partitionId = cur->thread_info->thread_leader_data->partitionId;
cur->thread_info->previous_partition_info.weighting = cur->thread_info->thread_leader_data->weighting;
cur->thread_info->previous_partition_info.idSequence = cur->thread_info->routing.router_id_sequence;
cur->thread_info->routerShortAddress = mac_helper_mac16_address_get(cur);
if(cur->thread_info->thread_attached_state != THREAD_STATE_REATTACH_RETRY){
Expand Down
2 changes: 2 additions & 0 deletions source/6LoWPAN/Thread/thread_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ struct thread_extension_credentials;
typedef struct thread_previous_partition_info_s {
uint32_t partitionId; //partition ID of the previous partition
uint8_t idSequence; //idSequence last heard from the previous partition
uint8_t weighting; //weighting last heard from the previous partition
} thread_previous_partition_t;


Expand Down Expand Up @@ -294,6 +295,7 @@ typedef struct thread_info_s {
uint8_t version;
uint8_t testMaxActiveRouterIdLimit; //Default for this is 32
uint8_t maxChildCount; //Default for this is 24
uint8_t partition_weighting;
bool rfc6775: 1;
bool requestFullNetworkData: 1;
bool leaderCab: 1;
Expand Down
22 changes: 17 additions & 5 deletions source/6LoWPAN/Thread/thread_host_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,9 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
if (thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH || thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH_RETRY) {
tr_debug("Reattach");
if (thread_info(cur)->thread_leader_data) {
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) { //accept only same ID at reattach phase
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) ||
(thread_info(cur)->thread_leader_data->weighting != leaderData.weighting)) {
//accept only same ID at reattach phase
return;
}
//Compare ID - when downgrading, accept all
Expand All @@ -549,7 +551,9 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED ||
thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) {
if (thread_info(cur)->thread_leader_data) {
if (thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) { //accept only different ID at anyattach phase
if ((thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) &&
(thread_info(cur)->thread_leader_data->weighting == leaderData.weighting)) {
//accept only different ID at anyattach phase
tr_debug("Drop old partition");
return;
}
Expand Down Expand Up @@ -584,6 +588,10 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
}
}

if (leaderData.weighting < thread_info(cur)->partition_weighting) {
tr_debug("Drop parent due weighting %d<%d", leaderData.weighting, thread_info(cur)->partition_weighting);
return;
}

if (accept_response) {
if (thread_info(cur)->thread_attach_scanned_parent == NULL) {
Expand All @@ -596,12 +604,16 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
tr_debug("Partition %"PRIu32, leaderData.partitionId);
} else {
uint32_t currentPartitionId = thread_info(cur)->thread_attach_scanned_parent->leader_data.partitionId;
tr_debug("Current %"PRIu32" RX %"PRIu32, currentPartitionId, leaderData.partitionId);
uint8_t currentWeighting = thread_info(cur)->thread_attach_scanned_parent->leader_data.weighting;
tr_debug("Current partition %"PRIu32" old:%"PRIu32" weighting %"PRIu8" old:%"PRIu8,
currentPartitionId, leaderData.partitionId, currentWeighting, leaderData.weighting);

if (leaderData.partitionId != currentPartitionId) {
if ((leaderData.partitionId != currentPartitionId) ||
(leaderData.weighting != currentWeighting)) {
int retVal = thread_bootstrap_partition_process(cur, connectivityTlv.activeRouters, &leaderData,NULL);
if (retVal > 0)
if (retVal > 0) {
scan_result = thread_info(cur)->thread_attach_scanned_parent;
}
}
else if (leaderData.partitionId == currentPartitionId) {
thread_link_quality_e currentLqi;
Expand Down
11 changes: 6 additions & 5 deletions source/6LoWPAN/Thread/thread_leader_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -1274,14 +1274,16 @@ static int thread_leader_service_leader_init(protocol_interface_info_entry_t *cu
return thread_leader_service_leader_start(cur);
}

static void thread_leader_service_leader_data_initialize(thread_leader_data_t *leader_data, uint8_t routerId)
static void thread_leader_service_leader_data_initialize(protocol_interface_info_entry_t *cur, uint8_t routerId)
{
if (leader_data) {
thread_leader_data_t *leader_data = cur->thread_info->thread_leader_data;

if (cur->thread_info->thread_leader_data) {
leader_data->partitionId = randLIB_get_32bit(); //Generate Random Instance
leader_data->leaderRouterId = routerId; //Set leader data to zero by Default
leader_data->dataVersion = randLIB_get_8bit();
leader_data->stableDataVersion = randLIB_get_8bit();
leader_data->weighting = THREAD_DEFAULT_WEIGHTING;
leader_data->weighting = cur->thread_info->partition_weighting;
}
}

Expand All @@ -1303,7 +1305,7 @@ static void thread_leader_service_interface_setup_activate(protocol_interface_in

routerId = thread_router_id_from_addr(cur->thread_info->routerShortAddress);

thread_leader_service_leader_data_initialize(cur->thread_info->thread_leader_data, routerId);
thread_leader_service_leader_data_initialize(cur, routerId);
// Test code
if(cur->thread_info->testRandomPartitionId != 0){
cur->thread_info->thread_leader_data->partitionId = cur->thread_info->testRandomPartitionId;
Expand Down Expand Up @@ -1810,5 +1812,4 @@ void thread_leader_service_router_state_changed(thread_info_t *thread_info, uint
}
}


#endif // HAVE_THREAD_LEADER_SERVICE */
32 changes: 32 additions & 0 deletions source/6LoWPAN/Thread/thread_management_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "6LoWPAN/Thread/thread_routing.h"
#include "6LoWPAN/Thread/thread_network_data_lib.h"
#include "6LoWPAN/Thread/thread_network_data_storage.h"
#include "6LoWPAN/Thread/thread_leader_service.h"
#include "6LoWPAN/Thread/thread_nd.h"
#include "thread_diagnostic.h"
#include "6LoWPAN/Thread/thread_dhcpv6_client.h"
Expand Down Expand Up @@ -915,6 +916,9 @@ int thread_management_node_init(
/* Thread will manage the address query timing, and report negatives. Set this high so as not to interfere. */
cur->ipv6_neighbour_cache.retrans_timer = 10000;

// Set default partition weighting
cur->thread_info->partition_weighting = THREAD_DEFAULT_WEIGHTING;

/* IP forwarding is off by default */
cur->ip_forwarding = false;

Expand Down Expand Up @@ -1390,3 +1394,31 @@ int thread_management_network_certificate_set(int8_t interface_id, const unsigne
#endif
}

int thread_management_partition_weighting_set(int8_t interface_id, uint8_t partition_weighting)
{
(void) interface_id;
(void) partition_weighting;
#ifdef HAVE_THREAD
protocol_interface_info_entry_t *cur;

cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !cur->thread_info) {
tr_debug("Invalid interface id");
return -1;
}

if (cur->thread_info->partition_weighting == partition_weighting) {
return 0;
}

cur->thread_info->partition_weighting = partition_weighting;
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
// bootstrap active and weighting has changed
thread_bootstrap_reset_restart(interface_id);
}

return 0;
#else
return -1;
#endif
}
9 changes: 5 additions & 4 deletions source/6LoWPAN/Thread/thread_mle_message_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,9 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
//processing for non routers
if (thread_check_is_this_my_parent(cur, entry_temp)) {
//advertisement from parent
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) {
//parent changed partition - reset own routing information
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) ||
(thread_info(cur)->thread_leader_data->weighting != leaderData.weighting)) {
//parent changed partition/weight - reset own routing information
thread_old_partition_data_purge(cur->thread_info);
}
//check if network data needs to be requested
Expand All @@ -333,7 +334,6 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
return;
}

}
}

Expand All @@ -345,7 +345,8 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
if (!thread_attach_active_router(cur)) {
// REED and FED
if (!entry_temp && thread_bootstrap_link_create_check(cur, shortAddress) && thread_bootstrap_link_create_allowed(cur, shortAddress, mle_msg->packet_src_address)) {
if (thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) {
if ((thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) &&
(thread_info(cur)->thread_leader_data->weighting == leaderData.weighting)) {
// Create link to new neighbor no other processing allowed
thread_link_request_start(cur, mle_msg->packet_src_address);
return;
Expand Down

0 comments on commit d5e2198

Please sign in to comment.