Skip to content

Commit 5227398

Browse files
author
Jarkko Paso
committed
Merge branch 'master' into koli
* master: updated mleid rloc sync in leader. (ARMmbed#1645) Added filter callback for MLE messages (ARMmbed#1638) Security bits handled correctly (ARMmbed#1642) Update Thread MLE neighbor list cleanup, attempt ARMmbed#2 (ARMmbed#1640) file version checking handled after other errors. (ARMmbed#1641) added nvm support for leader router id allocation. (ARMmbed#1626) Revert "Update Thread MLE neighbor list cleanup (ARMmbed#1637)" (ARMmbed#1639) Update Thread MLE neighbor list cleanup (ARMmbed#1637) Fix to partition selection rules (ARMmbed#1633) Update MLE receiver in Child ID req timeout error (ARMmbed#1634) Discard late Child ID responses (ARMmbed#1630) Multicast registration time fix (ARMmbed#1631) Thread key ID change during attach (ARMmbed#1627) Skip discovery request if MLE table is full (ARMmbed#1625) Add new test API for clearing Thread stack values (ARMmbed#1624) additional reed advertisement (ARMmbed#1609) Thread tx failure handling update (ARMmbed#1620)
2 parents c0e8673 + 5af4a39 commit 5227398

29 files changed

+394
-69
lines changed

nanostack/net_test_api.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#define NET_TEST_API_H_
2525

2626
#include "ns_types.h"
27+
#include "Service_Libs/mle_service/mle_service_api.h"
2728

2829
/**
2930
* \brief Makes TCP protocol drop given number of packets from a particular state (TX side).
@@ -56,4 +57,11 @@ int8_t arm_nwk_test_tcp_drop_rx(int state, uint8_t count);
5657
*/
5758
void arm_nwk_test_tcp_drop_reset(void);
5859

60+
/**
61+
* \brief Set callback for MLE message receiving filter.
62+
*
63+
* Testing API for setting MLE receive callback for message filtering purposes.
64+
*/
65+
void arm_nwk_test_mle_receive_filter_set(mle_service_filter_cb *response_filter_cb);
66+
5967
#endif //NET_TEST_API_H_

nanostack/net_thread_test.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,19 @@ int thread_test_increment_key_sequence_counter(int8_t interface_id);
274274
*/
275275
int thread_test_key_sequence_counter_update(int8_t interface_id, uint32_t thrKeySequenceCounter);
276276

277+
/**
278+
* \brief Resets cached values from stack
279+
*
280+
Resets link configuration from cache and from NVM.
281+
*
282+
*
283+
* \param interface_id Network Interface
284+
*
285+
* \return 0, OK
286+
* \return <0 Error
287+
*/
288+
int thread_test_stack_cache_reset(int8_t interface_id);
289+
277290
/**
278291
* \brief Set new Thread key rotation value
279292
*

source/6LoWPAN/Thread/thread_bootstrap.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,14 @@ int thread_bootstrap_partition_process(protocol_interface_info_entry_t *cur, uin
341341
/*Rule 0: If we are going to form Higher partition than heard we dont try to attach to lower ones
342342
*/
343343
if (thread_extension_enabled(cur) &&
344-
thread_info(cur)->thread_device_mode == THREAD_DEVICE_MODE_ROUTER &&
345-
heard_partition_leader_data->weighting < thread_info(cur)->partition_weighting) {
346-
return -2;
344+
thread_info(cur)->thread_device_mode == THREAD_DEVICE_MODE_ROUTER) {
345+
if (heard_partition_leader_data->weighting < thread_info(cur)->partition_weighting) {
346+
tr_debug("Heard a lower weight partition");
347+
return -2;
348+
}
349+
if (heard_partition_leader_data->weighting > thread_info(cur)->partition_weighting) {
350+
return 2;
351+
}
347352
}
348353

349354
//Rule 1: A non-singleton Thread Network Partition always has higher priority than a singleton Thread Network Partition
@@ -1162,14 +1167,14 @@ void thread_bootstrap_ready(protocol_interface_info_entry_t *cur)
11621167
mac_data_poll_protocol_poll_mode_decrement(cur);
11631168
}
11641169

1165-
void thread_clean_all_routers_from_neighbor_list(int8_t interface_id)
1170+
void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur)
11661171
{
1167-
mle_neigh_table_list_t *neig_list = mle_class_active_list_get(interface_id);
1168-
/* Init Double linked Routing Table */
1169-
ns_list_foreach_safe(mle_neigh_table_entry_t, cur, neig_list) {
1170-
if (thread_is_router_addr(cur->short_adr)) {
1171-
tr_debug("Free Router %x", cur->short_adr);
1172-
mle_class_remove_entry(interface_id, cur);
1172+
mle_neigh_table_list_t *neig_list = mle_class_active_list_get(cur->id);
1173+
1174+
ns_list_foreach_safe(mle_neigh_table_entry_t, cur_entry, neig_list) {
1175+
if (!thread_addr_is_equal_or_child(cur->thread_info->routerShortAddress, cur_entry->short_adr)) {
1176+
tr_debug("Free ID %x", cur_entry->short_adr);
1177+
mle_class_remove_entry(cur->id, cur_entry);
11731178
}
11741179
}
11751180
}

source/6LoWPAN/Thread/thread_bootstrap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg,
106106
int thread_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mle_neigh_table_entry_t *child);
107107
void thread_bootstrap_ready(struct protocol_interface_info_entry *cur);
108108
int thread_bootstrap_reset(struct protocol_interface_info_entry *cur);
109-
void thread_clean_all_routers_from_neighbor_list(int8_t interface_id);
109+
void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur);
110110
bool thread_bootstrap_request_network_data(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, uint16_t short_address);
111111
bool thread_check_is_this_my_parent(struct protocol_interface_info_entry *cur, struct mle_neigh_table_entry_t *entry_temp);
112112
void thread_clean_old_16_bit_address_based_addresses(struct protocol_interface_info_entry *cur);

source/6LoWPAN/Thread/thread_common.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,8 @@ int8_t thread_bootstrap_down(protocol_interface_info_entry_t *cur)
233233
tr_debug("SET thread Idle");
234234
//stop polling
235235
mac_data_poll_disable(cur);
236-
//Clean routers from mle table
237-
thread_clean_all_routers_from_neighbor_list(cur->id);
236+
//Clean mle table
237+
thread_neighbor_list_clean(cur);
238238
// store frame counters
239239
if (cur->thread_info) {
240240
thread_nvm_fast_data_t fast_data;
@@ -249,6 +249,7 @@ int8_t thread_bootstrap_down(protocol_interface_info_entry_t *cur)
249249
thread_joiner_application_configuration_nvm_save(cur->id);
250250
mac_pairwise_key_flush_list(cur->id);
251251
thread_discovery_reset(cur->id);
252+
thread_leader_mleid_rloc_map_to_nvm_write(cur);
252253
thread_bootstrap_stop(cur);
253254
mle_service_interface_unregister(cur->id);
254255
thread_management_server_delete(cur->id);
@@ -524,6 +525,7 @@ thread_leader_info_t *thread_allocate_and_init_leader_private_data(void)
524525
thread_leader_info_t *leader_info = ns_dyn_mem_alloc(sizeof(thread_leader_info_t));
525526
if (leader_info) {
526527
leader_info->leader_id_seq_timer = ID_SEQUENCE_PERIOD;
528+
leader_info->leader_nvm_sync_timer = 0;
527529
}
528530
return leader_info;
529531
}
@@ -1843,7 +1845,7 @@ static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failure
18431845
}
18441846

18451847
if (accumulated_failures >= THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
1846-
thread_reset_neighbour_info(cur, neighbor);
1848+
mle_class_remove_entry(cur->id, neighbor);
18471849
}
18481850
}
18491851

@@ -1853,8 +1855,8 @@ void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh
18531855
thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent;
18541856

18551857
if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->short_adr) {
1856-
tr_warn("End device lost Parent!\n");
18571858
if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) {
1859+
tr_warn("End device lost parent, reset!\n");
18581860
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
18591861
}
18601862
}

source/6LoWPAN/Thread/thread_common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
*/
4949
#define ROUTER_ID_REUSE_DELAY 100 //Seconds
5050

51+
#define LEADER_NVM_SYNC_DELAY 30 // Leader router ids write delay to NVM
52+
5153
#define ROUTER_ID_INFINITY_DELAY 90 //Seconds
5254

5355
#define NETWORK_ID_TIMEOUT 120 //seconds
@@ -145,6 +147,7 @@ typedef struct thread_leader_info_s {
145147
uint8_t leader_id_seq_timer;
146148
uint8_t master_router_id_mask[8];
147149
uint8_t maskSeq;
150+
uint8_t leader_nvm_sync_timer;
148151
} thread_leader_info_t;
149152

150153
typedef struct thread_leader_data_s {
@@ -286,6 +289,7 @@ typedef struct thread_info_s {
286289
uint16_t native_commissioner_port;
287290
uint16_t routerShortAddress;
288291
uint16_t reedJitterTimer;
292+
uint16_t reedMergeAdvTimer;
289293
uint16_t routerIdReqCoapID; // COAP msg id of RouterID request
290294
int16_t childUpdateReqTimer;
291295
uint16_t childUpdateReqMsgId;

source/6LoWPAN/Thread/thread_constants.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@
164164

165165
#define THREAD_ENTERPRISE_NUMBER 44970
166166

167-
#define THREAD_ADDR_REG_TIMEOUT_BASE 300
167+
#define THREAD_ADDR_REG_RETRY_INTERVAL 300
168168
#define THREAD_PROACTIVE_AN_INTERVAL 3600
169169

170170
// Router defines
@@ -174,6 +174,10 @@
174174
#define MIN_DOWNGRADE_NEIGHBORS 7
175175
#define THREAD_REED_ADVERTISEMENT_DELAY 5000
176176

177+
// Interval after which REED can send an advertisement to help others merge to higher partition.
178+
// This is not related to default REED advertisements.
179+
#define THREAD_REED_MERGE_ADVERTISEMENT_INTERVAL 120
180+
177181
/** Default Threshold for router Selection */
178182
#define ROUTER_DOWNGRADE_THRESHOLD 23 // Define downGrade Threshold when active router is higher than this
179183
#define ROUTER_UPGRADE_THRESHOLD 16 // Define upgrade Threshold fort REED when Active Router Count is smaller than this upgrade is possible

source/6LoWPAN/Thread/thread_discovery.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,12 @@ static void thread_discovery_request_msg_handler(thread_discovery_class_t * disc
817817
}
818818
tr_debug("Thread discovery request message RX");
819819

820+
// Check if we have room for new neighbor
821+
if (mle_class_free_entry_count_get(discovery_class->interface_id) < 1) {
822+
tr_debug("MLE table full, skip request");
823+
return;
824+
}
825+
820826
//validate message
821827
mle_tlv_info_t discovery_tlv;
822828
//Parse Message

source/6LoWPAN/Thread/thread_extension.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464

6565
#define TRACE_GROUP "comm"
6666

67-
#define SECURITY_POLICY_CCM_ENABLED 0x04 /* Thread Commercial Commissioning Mode is enabled when this bit is set. This is Thread 1.2 feature. */
67+
#define SECURITY_POLICY_CCM_DISABLED 0x04 /* Thread Commercial Commissioning Mode is enabled when this bit is set. This is Thread 1.2 feature. */
6868

6969
typedef struct thread_extension_info {
7070
int8_t coap_service_id;
@@ -271,6 +271,9 @@ int thread_extension_primary_bbr_get(struct protocol_interface_info_entry *cur,
271271
}
272272
if (mlr_timer_ptr) {
273273
*mlr_timer_ptr = common_read_32_bit(&found_tlv[7]);
274+
if (*mlr_timer_ptr < THREAD_DEFAULT_MIN_MLR_TIMEOUT) {
275+
*mlr_timer_ptr = THREAD_DEFAULT_MIN_MLR_TIMEOUT;
276+
}
274277
}
275278
return 0;
276279
}
@@ -496,14 +499,16 @@ void thread_extension_mcast_subscrition_change(protocol_interface_info_entry_t *
496499
if (addr_ipv6_multicast_scope(group->group) < IPV6_SCOPE_ADMIN_LOCAL) {
497500
return;
498501
}
499-
// Default timer added.
500-
group->mld_timer = added ? THREAD_ADDR_REG_TIMEOUT_BASE + randLIB_get_random_in_range(1, 30) : 0;
501502

502-
if (0 !=thread_extension_primary_bbr_get(interface, br_ml_addr, NULL, &mlr_timer, NULL )) {
503+
if (0 != thread_extension_primary_bbr_get(interface, br_ml_addr, NULL, &mlr_timer, NULL )) {
504+
// No BBR, try again later if adding address.
505+
group->mld_timer = added ? THREAD_ADDR_REG_RETRY_INTERVAL + randLIB_get_random_in_range(1, 30) : 0;
503506
return;
504507
}
505-
// follow the Primary BBR set timeout + Small jitter added
506-
group->mld_timer = added ? mlr_timer: 0;
508+
509+
// follow the Primary BBR set timeout.
510+
group->mld_timer = added ? (mlr_timer - randLIB_get_random_in_range(30, 40)) : 0;
511+
507512
// MLR is sent only for primary BBR for now, but this might change
508513
thread_extension_mlr_req_send(interface, br_ml_addr, group->group);
509514

@@ -576,7 +581,7 @@ bool thread_extension_enabled(protocol_interface_info_entry_t *cur)
576581
}
577582
uint16_t securityPolicy = thread_joiner_application_security_policy_get(cur->id);
578583

579-
if (securityPolicy & SECURITY_POLICY_CCM_ENABLED) {
584+
if (!(securityPolicy & SECURITY_POLICY_CCM_DISABLED)) {
580585
return true;
581586
}
582587

@@ -615,11 +620,9 @@ void thread_extension_discover_response_read(discovery_response_list_t *nwk_info
615620

616621
void thread_extension_discover_response_tlv_write(uint16_t *data, uint8_t version, uint16_t securityPolicy)
617622
{
618-
619-
if (version == 3 && !(securityPolicy & SECURITY_POLICY_CCM_ENABLED)) {
623+
if (version == 3 && !(securityPolicy & SECURITY_POLICY_CCM_DISABLED)) {
620624
*data |= (uint16_t) (1 << 10);
621625
}
622-
return;
623626
}
624627

625628
#ifdef HAVE_THREAD_ROUTER

source/6LoWPAN/Thread/thread_extension_bbr.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,10 @@ typedef struct {
9898
static NS_LIST_DEFINE(pbbr_instance_list, thread_pbbr_t, link);
9999
static NS_LIST_DEFINE(duplicate_dua_tr_list, duplicate_dua_tr_t, link);
100100

101-
102-
#define THREAD_BBR_MLR_REGISTRATION_TIMEOUT 120
101+
#define THREAD_BBR_MLR_REGISTRATION_TIMEOUT 600 //<* Default MLR timeout in seconds
103102
#define THREAD_BBR_DUA_REGISTRATION_TIMEOUT 3600
104-
#define THREAD_BBR_DUA_REGISTRATION_DELAY 5000 // 5 seconds in ms
105-
#define THREAD_BBR_BACKBONE_PORT 5683 //<* Backbone border router
103+
#define THREAD_BBR_DUA_REGISTRATION_DELAY 5000 // 5 seconds in ms
104+
#define THREAD_BBR_BACKBONE_PORT 5683 //<* Backbone border router
106105

107106
/*
108107
0 – Successful registration
@@ -608,8 +607,9 @@ static int thread_extension_bbr_mlr_cb(int8_t service_id, uint8_t source_address
608607
bbr_status = THREAD_BBR_STATUS_NOT_PRIMARY_BBR;
609608
goto send_response;
610609
}
610+
611+
//check if commissioner
611612
if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) {
612-
//check if commissioner
613613
// Session id present must be valid
614614
tr_info("message from commissioner");
615615
if (cur->thread_info->registered_commissioner.session_id != session_id) {
@@ -630,8 +630,10 @@ static int thread_extension_bbr_mlr_cb(int8_t service_id, uint8_t source_address
630630
response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
631631
goto send_response;
632632
}
633+
633634
int16_t remaining = addr_len;
634635
uint8_t *addr_ptr = addr_data_ptr;
636+
635637
while (remaining > 0) {
636638
//Go through all addresses
637639
if (timeout_value == 0) {

source/6LoWPAN/Thread/thread_extension_constants.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ typedef struct discovery_additional_info {
3838
bool ccm_supported:1;
3939
}discovery_additional_info_t;
4040

41+
/**
42+
* Minimum specified MLR timeout in seconds
43+
*/
44+
#define THREAD_DEFAULT_MIN_MLR_TIMEOUT 300
45+
4146
/**
4247
* Default Autonomous enrollment port.
4348
*/

source/6LoWPAN/Thread/thread_host_bootstrap.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ static void thread_child_synch_receive_cb(int8_t interface_id, mle_message_t *ml
398398
messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length);
399399

400400
if (messageId == 0) {
401-
tr_debug("Not for me");
401+
tr_debug("No matching challenge");
402402
return;
403403
}
404404

@@ -476,7 +476,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
476476
return;
477477
}
478478

479-
tr_debug("Thread MLE Parent request response Handler");
479+
tr_debug("MLE Parent response handler");
480480
//State machine What packet should accept in this case
481481
switch (mle_msg->message_type) {
482482
case MLE_COMMAND_PARENT_RESPONSE: {
@@ -501,7 +501,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
501501
messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length);
502502

503503
if (messageId == 0) {
504-
tr_debug("Not for me");
504+
tr_debug("No matching challenge");
505505
return;
506506
}
507507

@@ -752,11 +752,12 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message
752752
return;
753753
}
754754

755-
tr_debug("Thread MLE Child request response Handler");
755+
tr_debug("Thread MLE Child ID response handler");
756756

757757
switch (mle_msg->message_type) {
758758

759759
case MLE_COMMAND_CHILD_ID_RESPONSE: {
760+
uint8_t src_mac64[8];
760761
uint8_t shortAddress[2];
761762
uint16_t childId;
762763
mle_tlv_info_t routeTlv, addressRegisteredTlv, networkDataTlv;
@@ -766,15 +767,24 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message
766767
thread_scanned_parent_t *scan_result = thread_info(cur)->thread_attach_scanned_parent;
767768
bool new_entry_created;
768769

769-
tr_info("Received Child ID Response");
770+
tr_info("Recv Child ID Response");
771+
772+
// Validate that response is coming from the scanned parent candidate
773+
memcpy(src_mac64, (mle_msg->packet_src_address + 8), 8);
774+
src_mac64[0] ^= 2;
775+
if (memcmp(src_mac64, scan_result->mac64, 8) != 0) {
776+
tr_debug("Drop Child ID response from previous request");
777+
return;
778+
}
770779

771780
// Clear old data
772781
if (cur->thread_info->releaseRouterId) {
773782
thread_bootstrap_clear_neighbor_entries(cur);
774-
cur->thread_info->localServerDataBase.release_old_address = true;
775783
}
776784

777-
thread_clean_all_routers_from_neighbor_list(cur->id);
785+
cur->thread_info->localServerDataBase.release_old_address = true;
786+
787+
thread_neighbor_list_clean(cur);
778788
thread_leader_service_stop(interface_id);
779789
thread_leader_service_leader_data_free(cur->thread_info);
780790
thread_merge_prepare(cur);
@@ -838,6 +848,11 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message
838848
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress);
839849
mle_entry_timeout_update(entry_temp, thread_info(cur)->host_link_timeout);
840850

851+
if (scan_result->security_key_index != security_headers->KeyIndex) {
852+
// KeyIndex has been changed between parent_response and child_id_response, reset link layer frame counter
853+
scan_result->linLayerFrameCounter = 0;
854+
scan_result->security_key_index = security_headers->KeyIndex;
855+
}
841856
mlme_device_descriptor_t device_desc;
842857
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->short_adr,scan_result->linLayerFrameCounter, false);
843858
mac_helper_devicetable_set(&device_desc, cur, entry_temp->attribute_index, security_headers->KeyIndex, new_entry_created);
@@ -1030,9 +1045,10 @@ static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, boo
10301045
cur->thread_info->releaseRouterId = false;
10311046

10321047
cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE;
1033-
mle_service_interface_receiver_handler_update(cur->id, thread_general_mle_receive_cb);
10341048

10351049
exit:
1050+
mle_service_interface_receiver_handler_update(cur->id, thread_general_mle_receive_cb);
1051+
10361052
ns_dyn_mem_free(cur->thread_info->thread_attach_scanned_parent);
10371053
cur->thread_info->thread_attach_scanned_parent = NULL;
10381054

0 commit comments

Comments
 (0)