Skip to content

Commit d5e2198

Browse files
author
Arto Kinnunen
authored
Add API for partition weighting set (ARMmbed#1513)
Add new API for setting partition weighting value.
1 parent 8811d6f commit d5e2198

File tree

7 files changed

+87
-20
lines changed

7 files changed

+87
-20
lines changed

nanostack/thread_management_if.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,20 @@ int thread_management_device_certificate_set(int8_t interface_id, const unsigned
399399
*/
400400
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);
401401

402+
/**
403+
* Set Thread partition weighting.
404+
*
405+
* This function sets weighting value for Thread network partition. Interface will be restarted if interface is active and
406+
* new weighting value is different than previous weighting value.
407+
*
408+
* \param interface_id Network interface ID.
409+
* \param partition_weighting New weighting value for Thread partition
410+
*
411+
* \return 0, OK.
412+
* \return <0 fail.
413+
*/
414+
int thread_management_partition_weighting_set(int8_t interface_id, uint8_t partition_weighting);
415+
402416
#ifdef __cplusplus
403417
}
404418
#endif

source/6LoWPAN/Thread/thread_bootstrap.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,10 @@ static int thread_router_check_previous_partition_info(protocol_interface_info_e
448448
//check for parameters
449449
return -1;
450450
}
451-
if ((leaderData->partitionId == cur->thread_info->previous_partition_info.partitionId) && (routeTlv->dataPtr[0] == cur->thread_info->previous_partition_info.idSequence)) {
452-
//drop the advertisement
451+
if ((leaderData->partitionId == cur->thread_info->previous_partition_info.partitionId) &&
452+
(leaderData->weighting == cur->thread_info->previous_partition_info.weighting) &&
453+
(routeTlv->dataPtr[0] == cur->thread_info->previous_partition_info.idSequence)) {
454+
//drop the advertisement from previuos partition
453455
return 1;
454456
}
455457
else {
@@ -499,6 +501,7 @@ int thread_bootstrap_partition_process(protocol_interface_info_entry_t *cur, uin
499501
/*Rule 2: When comparing two singleton or two non-singleton Thread Network Partitions,
500502
the one with the higher 8-bit weight value has higher priority. */
501503
if (heard_partition_leader_data->weighting > current_leader_data->weighting) {
504+
tr_debug("Heard a greater weighting");
502505
return 2;
503506
}
504507

@@ -526,7 +529,8 @@ int thread_leader_data_validation(protocol_interface_info_entry_t *cur, thread_l
526529
if (!thread_info(cur)->thread_leader_data) {
527530
return -1;
528531
}
529-
if (thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) {
532+
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) ||
533+
(thread_info(cur)->thread_leader_data->weighting != leaderData->weighting)) {
530534
uint8_t routers_in_route_tlv = thread_get_router_count_from_route_tlv(routeTlv);
531535
//partition checks
532536
return thread_bootstrap_partition_process(cur,routers_in_route_tlv,leaderData, routeTlv);
@@ -535,10 +539,10 @@ int thread_leader_data_validation(protocol_interface_info_entry_t *cur, thread_l
535539
//Should check is there new version numbers
536540
if (common_serial_number_greater_8(leaderData->dataVersion, thread_info(cur)->thread_leader_data->dataVersion) ||
537541
common_serial_number_greater_8(leaderData->stableDataVersion, thread_info(cur)->thread_leader_data->stableDataVersion)) {
538-
// Version number increased
542+
// Version number increased by some-one else -> there is leader in the network
539543
if (thread_info(cur)->leader_private_data) {
540-
tr_error("SEq synch error");
541-
// MUST restart partition
544+
tr_error("Another leader detected -> bootstrap");
545+
thread_bootstrap_reset_restart(cur->id);
542546
return -1;
543547
}
544548
tr_debug("NEW Network Data available");
@@ -1344,6 +1348,7 @@ static int thread_bootstrap_attach_start(int8_t interface_id, thread_bootsrap_st
13441348
tr_debug("Thread ReAttach");
13451349
//save the current partition id and sequence number before trying reattach
13461350
cur->thread_info->previous_partition_info.partitionId = cur->thread_info->thread_leader_data->partitionId;
1351+
cur->thread_info->previous_partition_info.weighting = cur->thread_info->thread_leader_data->weighting;
13471352
cur->thread_info->previous_partition_info.idSequence = cur->thread_info->routing.router_id_sequence;
13481353
cur->thread_info->routerShortAddress = mac_helper_mac16_address_get(cur);
13491354
if(cur->thread_info->thread_attached_state != THREAD_STATE_REATTACH_RETRY){

source/6LoWPAN/Thread/thread_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ struct thread_extension_credentials;
253253
typedef struct thread_previous_partition_info_s {
254254
uint32_t partitionId; //partition ID of the previous partition
255255
uint8_t idSequence; //idSequence last heard from the previous partition
256+
uint8_t weighting; //weighting last heard from the previous partition
256257
} thread_previous_partition_t;
257258

258259

@@ -294,6 +295,7 @@ typedef struct thread_info_s {
294295
uint8_t version;
295296
uint8_t testMaxActiveRouterIdLimit; //Default for this is 32
296297
uint8_t maxChildCount; //Default for this is 24
298+
uint8_t partition_weighting;
297299
bool rfc6775: 1;
298300
bool requestFullNetworkData: 1;
299301
bool leaderCab: 1;

source/6LoWPAN/Thread/thread_host_bootstrap.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,9 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
532532
if (thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH || thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH_RETRY) {
533533
tr_debug("Reattach");
534534
if (thread_info(cur)->thread_leader_data) {
535-
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) { //accept only same ID at reattach phase
535+
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) ||
536+
(thread_info(cur)->thread_leader_data->weighting != leaderData.weighting)) {
537+
//accept only same ID at reattach phase
536538
return;
537539
}
538540
//Compare ID - when downgrading, accept all
@@ -549,7 +551,9 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
549551
thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED ||
550552
thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) {
551553
if (thread_info(cur)->thread_leader_data) {
552-
if (thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) { //accept only different ID at anyattach phase
554+
if ((thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) &&
555+
(thread_info(cur)->thread_leader_data->weighting == leaderData.weighting)) {
556+
//accept only different ID at anyattach phase
553557
tr_debug("Drop old partition");
554558
return;
555559
}
@@ -584,6 +588,10 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
584588
}
585589
}
586590

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

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

601-
if (leaderData.partitionId != currentPartitionId) {
611+
if ((leaderData.partitionId != currentPartitionId) ||
612+
(leaderData.weighting != currentWeighting)) {
602613
int retVal = thread_bootstrap_partition_process(cur, connectivityTlv.activeRouters, &leaderData,NULL);
603-
if (retVal > 0)
614+
if (retVal > 0) {
604615
scan_result = thread_info(cur)->thread_attach_scanned_parent;
616+
}
605617
}
606618
else if (leaderData.partitionId == currentPartitionId) {
607619
thread_link_quality_e currentLqi;

source/6LoWPAN/Thread/thread_leader_service.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,14 +1274,16 @@ static int thread_leader_service_leader_init(protocol_interface_info_entry_t *cu
12741274
return thread_leader_service_leader_start(cur);
12751275
}
12761276

1277-
static void thread_leader_service_leader_data_initialize(thread_leader_data_t *leader_data, uint8_t routerId)
1277+
static void thread_leader_service_leader_data_initialize(protocol_interface_info_entry_t *cur, uint8_t routerId)
12781278
{
1279-
if (leader_data) {
1279+
thread_leader_data_t *leader_data = cur->thread_info->thread_leader_data;
1280+
1281+
if (cur->thread_info->thread_leader_data) {
12801282
leader_data->partitionId = randLIB_get_32bit(); //Generate Random Instance
12811283
leader_data->leaderRouterId = routerId; //Set leader data to zero by Default
12821284
leader_data->dataVersion = randLIB_get_8bit();
12831285
leader_data->stableDataVersion = randLIB_get_8bit();
1284-
leader_data->weighting = THREAD_DEFAULT_WEIGHTING;
1286+
leader_data->weighting = cur->thread_info->partition_weighting;
12851287
}
12861288
}
12871289

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

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

1306-
thread_leader_service_leader_data_initialize(cur->thread_info->thread_leader_data, routerId);
1308+
thread_leader_service_leader_data_initialize(cur, routerId);
13071309
// Test code
13081310
if(cur->thread_info->testRandomPartitionId != 0){
13091311
cur->thread_info->thread_leader_data->partitionId = cur->thread_info->testRandomPartitionId;
@@ -1810,5 +1812,4 @@ void thread_leader_service_router_state_changed(thread_info_t *thread_info, uint
18101812
}
18111813
}
18121814

1813-
18141815
#endif // HAVE_THREAD_LEADER_SERVICE */

source/6LoWPAN/Thread/thread_management_if.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "6LoWPAN/Thread/thread_routing.h"
4848
#include "6LoWPAN/Thread/thread_network_data_lib.h"
4949
#include "6LoWPAN/Thread/thread_network_data_storage.h"
50+
#include "6LoWPAN/Thread/thread_leader_service.h"
5051
#include "6LoWPAN/Thread/thread_nd.h"
5152
#include "thread_diagnostic.h"
5253
#include "6LoWPAN/Thread/thread_dhcpv6_client.h"
@@ -915,6 +916,9 @@ int thread_management_node_init(
915916
/* Thread will manage the address query timing, and report negatives. Set this high so as not to interfere. */
916917
cur->ipv6_neighbour_cache.retrans_timer = 10000;
917918

919+
// Set default partition weighting
920+
cur->thread_info->partition_weighting = THREAD_DEFAULT_WEIGHTING;
921+
918922
/* IP forwarding is off by default */
919923
cur->ip_forwarding = false;
920924

@@ -1390,3 +1394,31 @@ int thread_management_network_certificate_set(int8_t interface_id, const unsigne
13901394
#endif
13911395
}
13921396

1397+
int thread_management_partition_weighting_set(int8_t interface_id, uint8_t partition_weighting)
1398+
{
1399+
(void) interface_id;
1400+
(void) partition_weighting;
1401+
#ifdef HAVE_THREAD
1402+
protocol_interface_info_entry_t *cur;
1403+
1404+
cur = protocol_stack_interface_info_get_by_id(interface_id);
1405+
if (!cur || !cur->thread_info) {
1406+
tr_debug("Invalid interface id");
1407+
return -1;
1408+
}
1409+
1410+
if (cur->thread_info->partition_weighting == partition_weighting) {
1411+
return 0;
1412+
}
1413+
1414+
cur->thread_info->partition_weighting = partition_weighting;
1415+
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
1416+
// bootstrap active and weighting has changed
1417+
thread_bootstrap_reset_restart(interface_id);
1418+
}
1419+
1420+
return 0;
1421+
#else
1422+
return -1;
1423+
#endif
1424+
}

source/6LoWPAN/Thread/thread_mle_message_handler.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,9 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
323323
//processing for non routers
324324
if (thread_check_is_this_my_parent(cur, entry_temp)) {
325325
//advertisement from parent
326-
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) {
327-
//parent changed partition - reset own routing information
326+
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) ||
327+
(thread_info(cur)->thread_leader_data->weighting != leaderData.weighting)) {
328+
//parent changed partition/weight - reset own routing information
328329
thread_old_partition_data_purge(cur->thread_info);
329330
}
330331
//check if network data needs to be requested
@@ -333,7 +334,6 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
333334
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
334335
return;
335336
}
336-
337337
}
338338
}
339339

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

0 commit comments

Comments
 (0)