Skip to content

Commit b78a370

Browse files
author
Jarkko Paso
committed
Merge branch 'master' into koli
* master: dereference null value issue fixed. (ARMmbed#1557) Clear IPv6 neighbor cache in partition change (ARMmbed#1554) Child neighbor entry updates (ARMmbed#1550) cleared neighbours with child address that are not ours (ARMmbed#1549) Thread partition merge mode TLV change (ARMmbed#1546) RLOC was updated before clearing child info (ARMmbed#1547) router short address set to 0xfffe for non routers (ARMmbed#1543) delete route set and link set entries for a router ID (ARMmbed#1540) REED advertisement handling (Thread spec 5.16.3): (ARMmbed#1535) added active and pending timestamps to child update response (ARMmbed#1533) Fix error case memory leak (ARMmbed#1537)
2 parents 8b43c6e + 6122d24 commit b78a370

15 files changed

+193
-137
lines changed

source/6LoWPAN/Thread/thread_bootstrap.c

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -115,21 +115,6 @@ static void thread_bootsrap_network_join_start(struct protocol_interface_info_en
115115
static int8_t thread_child_keep_alive(int8_t interface_id, const uint8_t *mac64);
116116

117117

118-
int thread_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child)
119-
{
120-
thread_dynamic_storage_child_info_clear(cur->id, child);
121-
122-
// If Child's RLOC16 appears in the Network Data send the RLOC16 to the Leader
123-
if (thread_network_data_services_registered(&cur->thread_info->networkDataStorage, child->short_adr)) {
124-
tr_debug("Remove references to Child's RLOC16 from the Network Data");
125-
thread_management_client_network_data_unregister(cur->id, child->short_adr);
126-
}
127-
128-
// Clear all (sleepy) child registrations to multicast groups
129-
thread_child_mcast_entries_remove(cur, child->mac64);
130-
131-
return 0;
132-
}
133118

134119
static bool thread_interface_is_active(int8_t interface_id) {
135120
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
@@ -146,57 +131,7 @@ static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t
146131
if (!cur_interface) {
147132
return;
148133
}
149-
if (thread_info(cur_interface)->thread_device_mode == THREAD_DEVICE_MODE_END_DEVICE || thread_info(cur_interface)->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) {
150-
thread_parent_info_t *thread_endnode_parent = thread_info(cur_interface)->thread_endnode_parent;
151-
//Compare Parent
152-
if (thread_endnode_parent) {
153-
if (thread_endnode_parent->shortAddress == cur->short_adr) {
154-
tr_warn("End device lost Parent!\n");
155-
thread_bootstrap_connection_error(cur_interface->id, CON_PARENT_CONNECT_DOWN, NULL);
156-
}
157-
}
158-
}
159-
else {
160-
if (thread_info(cur_interface)->thread_attached_state == THREAD_STATE_CONNECTED)
161-
{
162-
thread_parent_info_t *thread_endnode_parent = thread_info(cur_interface)->thread_endnode_parent;
163-
if (thread_endnode_parent->shortAddress == cur->short_adr) {
164-
tr_warn("REED has lost Parent!\n");
165-
thread_routing_remove_link(cur_interface, cur->short_adr);
166-
if(cur_interface->nwk_bootstrap_state != ER_CHILD_ID_REQ) {
167-
thread_bootstrap_connection_error(cur_interface->id, CON_PARENT_CONNECT_DOWN, NULL);
168-
}
169-
}
170-
else{
171-
tr_debug("Delete REED Neighbor");
172-
if (thread_is_router_addr(cur->short_adr)) {
173-
tr_debug("Router Free");
174-
thread_routing_remove_link(cur_interface, cur->short_adr);
175-
}
176-
}
177-
}
178-
else if (thread_info(cur_interface)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER)
179-
{
180-
tr_debug("Delete Router Neighbor %x", cur->short_adr);
181-
if (thread_is_router_addr(cur->short_adr)) {
182-
tr_debug("Router free");
183-
thread_routing_remove_link(cur_interface, cur->short_adr);
184-
} else if (thread_addr_is_child(mac_helper_mac16_address_get(cur_interface), cur->short_adr)) {
185-
tr_debug("Child free");
186-
/* 16-bit neighbour cache entries are mesh addresses, so remain potentially valid even if an
187-
* MLE link fails. This is the only exception - if it was the link from us as a router to a
188-
* child. That means that device must be off the mesh (at that 16-bit address, at least).
189-
* This will actually clear either a GC cache entry for a FTD or a registered entry
190-
* for a MTD.
191-
*/
192-
protocol_6lowpan_release_short_link_address_from_neighcache(cur_interface, cur->short_adr);
193-
thread_bootstrap_reset_child_info(cur_interface, cur);
194-
}
195-
}
196-
}
197-
198-
protocol_6lowpan_release_long_link_address_from_neighcache(cur_interface, cur->mac64);
199-
mac_helper_devicetable_remove(cur_interface->mac_api, cur->attribute_index);
134+
thread_reset_neighbour_info(cur_interface, cur);
200135
}
201136

202137

source/6LoWPAN/Thread/thread_common.c

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,36 +1837,27 @@ static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failure
18371837
return;
18381838
}
18391839

1840-
if (thread_i_am_router(cur)) {
1841-
if (thread_addr_is_child(mac_helper_mac16_address_get(cur), neighbor->short_adr)) {
1842-
if (accumulated_failures < THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
1843-
return;
1844-
}
1845-
1846-
tr_debug("Free the Child node, mac16=%d", neighbor->short_adr);
1847-
thread_bootstrap_reset_child_info(cur, neighbor);
1848-
1849-
protocol_6lowpan_release_short_link_address_from_neighcache(cur, neighbor->short_adr);
1850-
protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbor->mac64);
1851-
mac_helper_devicetable_remove(cur->mac_api, neighbor->attribute_index);
1852-
} else if (thread_is_router_addr(neighbor->short_adr)) {
1853-
if (accumulated_failures < THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_ROUTER_TRANSMISSIONS) {
1854-
return;
1855-
}
1856-
1857-
tr_debug("Set link quality to neighbor router to zero...");
1858-
thread_routing_force_link_margin(cur, neighbor->short_adr, 0);
1859-
}
1860-
} else { // We are a Child
1861-
if (thread_check_is_this_my_parent(cur, neighbor)) {
1862-
if (accumulated_failures < THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
1863-
return;
1864-
}
1865-
1866-
tr_debug("Consider the parent gone...");
1867-
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
1868-
}
1869-
}
1840+
if (accumulated_failures >= THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
1841+
thread_reset_neighbour_info(cur, neighbor);
1842+
}
1843+
}
1844+
1845+
/* Called when MLE link to neighbour lost, or ETX callback says link is bad */
1846+
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour)
1847+
{
1848+
thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent;
1849+
1850+
if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->short_adr) {
1851+
tr_warn("End device lost Parent!\n");
1852+
if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) {
1853+
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
1854+
}
1855+
}
1856+
1857+
thread_routing_remove_link(cur, neighbour->short_adr);
1858+
thread_router_bootstrap_reset_child_info(cur, neighbour);
1859+
protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbour->mac64);
1860+
mac_helper_devicetable_remove(cur->mac_api, neighbour->attribute_index);
18701861
}
18711862

18721863
uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv)
@@ -1929,14 +1920,17 @@ void thread_mcast_group_change(struct protocol_interface_info_entry *interface,
19291920
}
19301921
}
19311922

1932-
void thread_old_partition_data_purge(thread_info_t *thread_info)
1923+
void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur)
19331924
{
19341925
/* Partition has been changed. Wipe out data related to old partition */
1935-
thread_management_client_pending_coap_request_kill(thread_info->interface_id);
1926+
thread_management_client_pending_coap_request_kill(cur->id);
1927+
1928+
/* Reset previous routing information */
1929+
thread_routing_reset(&cur->thread_info->routing);
1930+
1931+
/* Flush address cache */
1932+
ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache);
19361933

1937-
/* Reset/init previous routing information */
1938-
thread_routing_reset(&thread_info->routing);
1939-
thread_routing_init(&thread_info->routing);
19401934
}
19411935

19421936
#endif

source/6LoWPAN/Thread/thread_common.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ extern uint16_t thread_joiner_port;
7070

7171
typedef enum {
7272
THREAD_STATE_NETWORK_DISCOVER, // Not commissioned to Thread network
73-
THREAD_STATE_REATTACH, // Connected to thread network, searching for better partition
74-
THREAD_STATE_REATTACH_RETRY, // Connected to thread network, searching for better partition with REED bit is set
75-
THREAD_STATE_ATTACH_ANY, // Connected to thread network, searching for all partitions with leader connectivity
73+
THREAD_STATE_REATTACH, // Connection to leader lost, searching for new parent
74+
THREAD_STATE_REATTACH_RETRY, // Connection to leader lost, searching for new parent with REED bit is set
75+
THREAD_STATE_ATTACH_ANY, // Searching for all partitions with leader connectivity
7676
THREAD_STATE_CONNECTED, // Attached to Thread network - can't route
7777
THREAD_STATE_CONNECTED_ROUTER, // Attached to Thread network - Routing enabled
7878
} thread_attach_state_e;
@@ -359,6 +359,7 @@ uint16_t thread_network_data_generate_stable_set(protocol_interface_info_entry_t
359359

360360
void thread_set_active_router(protocol_interface_info_entry_t *cur, if_address_entry_t *address_entry, uint8_t *routerId);
361361
uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv);
362+
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour);
362363

363364
void thread_child_id_request_entry_clean(protocol_interface_info_entry_t *cur);
364365
thread_pending_child_id_req_t *thread_child_id_request_entry_get(protocol_interface_info_entry_t *cur, uint8_t *euid64);
@@ -411,7 +412,7 @@ uint8_t thread_pending_timestamp_tlv_size(protocol_interface_info_entry_t *cur);
411412
void thread_calculate_key_guard_timer(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init);
412413
void thread_set_link_local_address(protocol_interface_info_entry_t *cur);
413414
void thread_mcast_group_change(struct protocol_interface_info_entry *interface, struct if_group_entry *group, bool group_added);
414-
void thread_old_partition_data_purge(thread_info_t *thread_info);
415+
void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur);
415416

416417
#else // HAVE_THREAD
417418

source/6LoWPAN/Thread/thread_host_bootstrap.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,9 @@ static int thread_parent_request_build(protocol_interface_info_entry_t *cur)
230230
}
231231

232232
if (cur->thread_info->thread_attached_state == THREAD_STATE_REATTACH ||
233-
cur->thread_info->thread_attached_state == THREAD_STATE_REATTACH_RETRY) {
233+
cur->thread_info->thread_attached_state == THREAD_STATE_REATTACH_RETRY ||
234+
cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED ||
235+
cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) {
234236
// When doing re-attach End devices are immediately accepted as parents
235237
scanMask |= 0x40;
236238
}
@@ -835,6 +837,9 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message
835837
thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED;
836838

837839
thread_bootstrap_update_ml16_address(cur, childId);
840+
if (!thread_is_router_addr(thread_info(cur)->routerShortAddress)) {
841+
thread_info(cur)->routerShortAddress = 0xfffe;
842+
}
838843

839844
mle_service_msg_free(scan_result->child_id_request_id);
840845

source/6LoWPAN/Thread/thread_leader_service.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1317,7 +1317,7 @@ static void thread_leader_service_interface_setup_activate(protocol_interface_in
13171317
thread_leader_service_private_routemask_init(private);
13181318
//SET Router ID
13191319
thread_leader_allocate_router_id_by_allocated_id(private, routerId, cur->mac);
1320-
thread_old_partition_data_purge(cur->thread_info);
1320+
thread_old_partition_data_purge(cur);
13211321
cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS;
13221322
thread_bootstrap_update_ml16_address(cur, cur->thread_info->routerShortAddress);
13231323
thread_generate_ml64_address(cur);

source/6LoWPAN/Thread/thread_lowpower_api.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,6 @@ void thread_lowpower_process_response(uint8_t *src_address,int8_t instance_id, u
444444
(void) instance_id;
445445
mle_tlv_info_t linkMetricsReport;
446446
if (memcmp(src_address, data_response_ptr->destination_address, 16) != 0) {
447-
tr_debug("Data response not for me");
448447
return;
449448
}
450449

source/6LoWPAN/Thread/thread_management_server.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,7 @@ static int thread_management_server_panid_query_cb(int8_t service_id, uint8_t so
857857
this->scan_ptr->timer = eventOS_timeout_ms(thread_panid_scan_timeout_cb, 500, this);// Delay for the confirm response message
858858
if (!this->scan_ptr->timer) {
859859
ns_dyn_mem_free(this->scan_ptr);
860+
this->scan_ptr = NULL;
860861
response_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
861862
goto error_exit;
862863
}
@@ -875,7 +876,6 @@ static int thread_management_server_panid_query_cb(int8_t service_id, uint8_t so
875876
}
876877
return -1;
877878
error_exit:
878-
this->scan_ptr = NULL;
879879
if (request_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE ){
880880
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, NULL, 0);
881881
return 0;

source/6LoWPAN/Thread/thread_mle_message_handler.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "6LoWPAN/Thread/thread_leader_service.h"
4646
#include "6LoWPAN/Thread/thread_tmfcop_lib.h"
4747
#include "6LoWPAN/Thread/thread_host_bootstrap.h"
48+
#include "6LoWPAN/Thread/thread_extension.h"
4849
#include "6LoWPAN/Thread/thread_router_bootstrap.h"
4950
#include "6LoWPAN/Thread/thread_network_synch.h"
5051
#include "6LoWPAN/MAC/mac_helper.h"
@@ -238,6 +239,29 @@ static bool thread_router_leader_data_process(protocol_interface_info_entry_t *c
238239
return true;
239240
}
240241

242+
static bool thread_reed_partitions_merge(protocol_interface_info_entry_t *cur, uint16_t shortAddress, thread_leader_data_t heard_partition_leader_data)
243+
{
244+
if (thread_is_router_addr(shortAddress)) {
245+
return false;
246+
}
247+
if (thread_extension_version_check(thread_info(cur)->version)) {
248+
// lower weighting heard
249+
if (thread_info(cur)->thread_leader_data->weighting > heard_partition_leader_data.weighting) {
250+
return false;
251+
}
252+
// lower/same partition id heard
253+
if (thread_info(cur)->thread_leader_data->weighting == heard_partition_leader_data.weighting &&
254+
thread_info(cur)->thread_leader_data->partitionId >= heard_partition_leader_data.partitionId ) {
255+
return false;
256+
}
257+
} else if (thread_info(cur)->thread_leader_data->partitionId >= heard_partition_leader_data.partitionId){
258+
return false;
259+
}
260+
// can merge to a higher weighting/partition id
261+
thread_bootstrap_connection_error(cur->id, CON_ERROR_PARTITION_MERGE, NULL);
262+
return true;
263+
}
264+
241265
static bool thread_router_advertiment_tlv_analyze(uint8_t *ptr, uint16_t data_length, thread_leader_data_t *leaderData, uint16_t *shortAddress, mle_tlv_info_t *routeTlv)
242266
{
243267
//Read Leader Data and verify connectivity
@@ -327,7 +351,7 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
327351
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) ||
328352
(thread_info(cur)->thread_leader_data->weighting != leaderData.weighting)) {
329353
//parent changed partition/weight - reset own routing information
330-
thread_old_partition_data_purge(cur->thread_info);
354+
thread_old_partition_data_purge(cur);
331355
}
332356
//check if network data needs to be requested
333357
if (!thread_bootstrap_request_network_data(cur, &leaderData, shortAddress)) {
@@ -347,7 +371,7 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
347371
// REED and FED
348372
if (!entry_temp && thread_bootstrap_link_create_check(cur, shortAddress) && thread_bootstrap_link_create_allowed(cur, shortAddress, mle_msg->packet_src_address)) {
349373
if ((thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) &&
350-
(thread_info(cur)->thread_leader_data->weighting == leaderData.weighting)) {
374+
(thread_info(cur)->thread_leader_data->weighting == leaderData.weighting)) {
351375
// Create link to new neighbor no other processing allowed
352376
thread_link_request_start(cur, mle_msg->packet_src_address);
353377
return;
@@ -357,6 +381,10 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
357381
return;
358382
}
359383
}
384+
// process REED advertisement from higher partition
385+
if (thread_reed_partitions_merge(cur, shortAddress, leaderData)) {
386+
return;
387+
}
360388
} else {
361389
//Router
362390
if (!thread_router_leader_data_process(cur, mle_msg->packet_src_address, &leaderData, &routeTlv, entry_temp) ) {
@@ -549,7 +577,7 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle
549577
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) {
550578
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData.leaderRouterId;
551579
thread_info(cur)->thread_leader_data->partitionId = leaderData.partitionId;
552-
thread_old_partition_data_purge(cur->thread_info);
580+
thread_old_partition_data_purge(cur);
553581
accept_new_data = true;
554582
}
555583

@@ -688,7 +716,7 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent
688716
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) {
689717
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData.leaderRouterId;
690718
thread_info(cur)->thread_leader_data->partitionId = leaderData.partitionId;
691-
thread_old_partition_data_purge(cur->thread_info);
719+
thread_old_partition_data_purge(cur);
692720
}
693721
//Check Network Data TLV
694722
if (mle_tlv_read_tlv(MLE_TYPE_NETWORK_DATA, mle_msg->data_ptr, mle_msg->data_length, &networkDataTlv)) {

0 commit comments

Comments
 (0)