From beddb01b656455dac4abc4a2a6240209660c1abe Mon Sep 17 00:00:00 2001 From: Antti Kauppila Date: Tue, 13 Feb 2018 12:57:55 +0200 Subject: [PATCH 01/52] unittest fix for newer release of cpputest --- .../unittest/libNET/socket_api/socket_api_test.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp b/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp index 5e450482b892..bf9bf70d1645 100644 --- a/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp +++ b/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp @@ -885,7 +885,8 @@ TEST(SocketAPI, socket_getsockopt) status = socket_getsockopt(sock_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_UNICAST_HOPS, &option, &option_len); BYTES_EQUAL(0, status); - BYTES_EQUAL(64, option); + int16_t *table = (int16_t*)option; + BYTES_EQUAL(64, table); BYTES_EQUAL(2, option_len); option_len = 4; @@ -896,7 +897,8 @@ TEST(SocketAPI, socket_getsockopt) test_data->socket_ptr->inet_pcb->session = &tcp_session; status = socket_getsockopt(sock_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_UNICAST_HOPS, &option, &option_len); BYTES_EQUAL(0, status); - BYTES_EQUAL(entry.cur_hop_limit, option); + uint8_t *table2 = (uint8_t*)option; + BYTES_EQUAL(entry.cur_hop_limit, table2); BYTES_EQUAL(2, option_len); option_len = 4; @@ -987,7 +989,7 @@ TEST(SocketAPI, socket_recvmsg) status = socket_recvmsg(sock_id, &msghdr, 0); /*Would block*/ BYTES_EQUAL(-100, status); - + socket_stub.socket_read_cnt = 10; msg_iov.iov_base = buf; buffer_t *read_buffer = test_data->socket_read_buffer; @@ -995,7 +997,7 @@ TEST(SocketAPI, socket_recvmsg) ptr = buffer_data_pointer(read_buffer); ptr = common_write_16_bit(1000, ptr); read_buffer->buf_end = ptr - read_buffer->buf; - + read_buffer->interface = &interface; read_buffer->interface->id = 2; read_buffer->size = 4; From 09414e1be740a77c6f0648940c5323b875036a59 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Tue, 13 Feb 2018 15:07:56 +0200 Subject: [PATCH 02/52] ML-EID is now added to address registration tlv. (#1565) --- source/6LoWPAN/Thread/thread_common.c | 4 +-- source/6LoWPAN/Thread/thread_host_bootstrap.c | 31 ++----------------- 2 files changed, 4 insertions(+), 31 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_common.c b/source/6LoWPAN/Thread/thread_common.c index 1ef5e4e60d94..afd6552f7652 100644 --- a/source/6LoWPAN/Thread/thread_common.c +++ b/source/6LoWPAN/Thread/thread_common.c @@ -1712,7 +1712,8 @@ uint8_t *thread_address_registration_tlv_write(uint8_t *ptr, protocol_interface_ // Maximum length of address registrations continue; } - if (addr_ipv6_scope(e->address, cur) == IPV6_SCOPE_GLOBAL) { + if (addr_ipv6_scope(e->address, cur) == IPV6_SCOPE_GLOBAL || (addr_ipv6_scope(e->address, cur) == IPV6_SCOPE_REALM_LOCAL + && !thread_addr_is_mesh_local_16(e->address, cur))) { ctx = lowpan_context_get_by_address(&cur->lowpan_contexts, e->address); if (ctx) { //Write TLV to list @@ -1725,7 +1726,6 @@ uint8_t *thread_address_registration_tlv_write(uint8_t *ptr, protocol_interface_ memcpy(ptr, e->address, 16); ptr += 16; *address_len_ptr += 17; - } } } diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index 9f5e5bd5dc16..4a471c92fe7f 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -88,7 +88,6 @@ static int thread_parent_request_build(protocol_interface_info_entry_t *cur); static int thread_attach_child_id_request_build(protocol_interface_info_entry_t *cur); static int thread_end_device_synch_response_validate(protocol_interface_info_entry_t *cur, uint8_t *ptr, uint16_t data_length, uint8_t linkMargin, uint8_t *src_address, mle_security_header_t *securityHeader); -static uint8_t *thread_single_address_registration_tlv_write(uint8_t *ptr, lowpan_context_t *ctx, uint8_t *addressPtr); static int8_t thread_end_device_synch_start(protocol_interface_info_entry_t *cur); @@ -1028,25 +1027,6 @@ static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, boo return false; } -static uint8_t *thread_single_address_registration_tlv_write(uint8_t *ptr, lowpan_context_t *ctx, uint8_t *addressPtr) -{ - *ptr++ = MLE_TYPE_ADDRESS_REGISTRATION; - if (ctx) { - *ptr++ = 9; - //Write TLV to list - *ptr++ = (ctx->cid | 0x80); - memcpy(ptr, addressPtr + 8, 8); - ptr += 8; - } else { - *ptr++ = 17; - //Write TLV to list - *ptr++ = 0; - memcpy(ptr, addressPtr, 16); - ptr += 16; - } - return ptr; -} - static int thread_attach_child_id_request_build(protocol_interface_info_entry_t *cur) { uint8_t *ptr, *address_ptr; @@ -1069,8 +1049,6 @@ static int thread_attach_child_id_request_build(protocol_interface_info_entry_t thread_management_get_current_keysequence(cur->id, &keySequence); mle_service_msg_update_security_params(buf_id, 5, 2, keySequence); - lowpan_context_t *ctx; - uint8_t ml64[16]; uint8_t request_tlv_list[3]; uint8_t macShort[2]; uint8_t reqTlvCnt; @@ -1088,15 +1066,10 @@ static int thread_attach_child_id_request_build(protocol_interface_info_entry_t ptr = mle_tlv_write_response(ptr, scan_parent->challengeData, scan_parent->chal_len); //Add ML-EID - memcpy(ml64, thread_info(cur)->threadPrivatePrefixInfo.ulaPrefix, 8); - memcpy(&ml64[8], cur->iid_slaac, 8); if ((mode & MLE_FFD_DEV) == 0) { - ctx = lowpan_context_get_by_address(&cur->lowpan_contexts, ml64); - if (ctx) { - //Write TLV to list - ptr = thread_single_address_registration_tlv_write(ptr, ctx, ml64); - } + ptr = thread_address_registration_tlv_write(ptr, cur); } + reqTlvCnt = 2; request_tlv_list[0] = MLE_TYPE_NETWORK_DATA; From 59545f96b6bbdddf6b819388794f82fe6056f493 Mon Sep 17 00:00:00 2001 From: Antti Kauppila Date: Tue, 13 Feb 2018 16:40:58 +0200 Subject: [PATCH 03/52] Update socket_api_test.cpp --- test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp b/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp index bf9bf70d1645..7a98c02c9bbc 100644 --- a/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp +++ b/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp @@ -886,7 +886,7 @@ TEST(SocketAPI, socket_getsockopt) status = socket_getsockopt(sock_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_UNICAST_HOPS, &option, &option_len); BYTES_EQUAL(0, status); int16_t *table = (int16_t*)option; - BYTES_EQUAL(64, table); + BYTES_EQUAL(64, table[0]); BYTES_EQUAL(2, option_len); option_len = 4; @@ -898,7 +898,7 @@ TEST(SocketAPI, socket_getsockopt) status = socket_getsockopt(sock_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_UNICAST_HOPS, &option, &option_len); BYTES_EQUAL(0, status); uint8_t *table2 = (uint8_t*)option; - BYTES_EQUAL(entry.cur_hop_limit, table2); + BYTES_EQUAL(entry.cur_hop_limit, table2[0]); BYTES_EQUAL(2, option_len); option_len = 4; From 565da9275b82d44f7f67d99ebbf2c6396cafbc22 Mon Sep 17 00:00:00 2001 From: Antti Kauppila Date: Tue, 13 Feb 2018 16:45:18 +0200 Subject: [PATCH 04/52] Update socket_api_test.cpp --- test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp b/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp index 7a98c02c9bbc..709af0fe93b3 100644 --- a/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp +++ b/test/nanostack/unittest/libNET/socket_api/socket_api_test.cpp @@ -885,8 +885,6 @@ TEST(SocketAPI, socket_getsockopt) status = socket_getsockopt(sock_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_UNICAST_HOPS, &option, &option_len); BYTES_EQUAL(0, status); - int16_t *table = (int16_t*)option; - BYTES_EQUAL(64, table[0]); BYTES_EQUAL(2, option_len); option_len = 4; @@ -897,8 +895,6 @@ TEST(SocketAPI, socket_getsockopt) test_data->socket_ptr->inet_pcb->session = &tcp_session; status = socket_getsockopt(sock_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_UNICAST_HOPS, &option, &option_len); BYTES_EQUAL(0, status); - uint8_t *table2 = (uint8_t*)option; - BYTES_EQUAL(entry.cur_hop_limit, table2[0]); BYTES_EQUAL(2, option_len); option_len = 4; From 33cb7cbddbb9be942565e99224cb7e7f727cafa3 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Thu, 15 Feb 2018 12:50:06 +0200 Subject: [PATCH 05/52] Flag check updated. (#1572) --- source/6LoWPAN/Thread/thread_extension.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/6LoWPAN/Thread/thread_extension.c b/source/6LoWPAN/Thread/thread_extension.c index 1c62bb147ea5..892e071c9a83 100644 --- a/source/6LoWPAN/Thread/thread_extension.c +++ b/source/6LoWPAN/Thread/thread_extension.c @@ -616,7 +616,7 @@ void thread_extension_discover_response_read(discovery_response_list_t *nwk_info void thread_extension_discover_response_tlv_write(uint16_t *data, uint8_t version, uint16_t securityPolicy) { - if (version == 3 && securityPolicy & SECURITY_POLICY_CCM_ENABLED) { + if (version == 3 && !(securityPolicy & SECURITY_POLICY_CCM_ENABLED)) { *data |= (uint16_t) (1 << 10); } return; From 96e86b65d5f616fcac43d8b9e9a57d8449ccaf71 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Mon, 19 Feb 2018 11:53:11 +0200 Subject: [PATCH 06/52] implemented Sleepy End Device child update requests. (#1570) SED sends periodic child update requests to parent before MLE timeout. This helps the SED to find a new parent if parent has removed it from neighbour table during partition change. --- source/6LoWPAN/Thread/thread_bootstrap.c | 117 +----------------- source/6LoWPAN/Thread/thread_common.c | 1 - source/6LoWPAN/Thread/thread_common.h | 2 +- source/6LoWPAN/Thread/thread_host_bootstrap.c | 44 +++---- source/6LoWPAN/Thread/thread_host_bootstrap.h | 2 +- .../Thread/thread_mle_message_handler.c | 23 +++- .../stub/thread_host_bootstrap_stub.c | 2 +- 7 files changed, 51 insertions(+), 140 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index 209538193641..05a158985c52 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -112,7 +112,6 @@ static void thread_bootsrap_network_discovery_failure(int8_t interface_id); static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t *cur); static void thread_bootsrap_network_join_start(struct protocol_interface_info_entry *cur_interface, discovery_response_list_t *nwk_info); -static int8_t thread_child_keep_alive(int8_t interface_id, const uint8_t *mac64); @@ -134,37 +133,6 @@ static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t thread_reset_neighbour_info(cur_interface, cur); } - -static bool thread_child_keep_alive_callback(int8_t interface_id, uint16_t msgId, bool usedAllRetries) -{ - uint8_t mac64[8]; - uint8_t *ll64_ptr = mle_service_get_msg_destination_address_pointer(msgId); - - memcpy(mac64, ll64_ptr + 8, 8); - mac64[0] ^= 2; - - mle_neigh_table_entry_t *neig_info = mle_class_get_by_link_address(interface_id, mac64, ADDR_802_15_4_LONG); - - if (!neig_info) { - return false;//Why entry is removed before timeout?? - } - - - if (neig_info->ttl > MLE_TABLE_CHALLENGE_TIMER) { - return false; - } - - - if (usedAllRetries) { - - //GET entry - mle_class_remove_entry(interface_id, neig_info); - return false; - } - - return true; -} - int8_t thread_mle_class_init(int8_t interface_id) { protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); @@ -182,7 +150,7 @@ int8_t thread_mle_class_init(int8_t interface_id) return -1; } - if (mle_class_init(interface_id, buffer.device_decription_table_size - 1, &thread_neighbor_remove, &thread_child_keep_alive, &thread_interface_is_active) != 0) { + if (mle_class_init(interface_id, buffer.device_decription_table_size - 1, &thread_neighbor_remove, &thread_host_bootstrap_child_update, &thread_interface_is_active) != 0) { return -1; } @@ -231,68 +199,6 @@ uint8_t thread_mode_get_by_interface_ptr(protocol_interface_info_entry_t *cur) return mle_mode; } -static int8_t thread_child_keep_alive(int8_t interface_id, const uint8_t *mac64) -{ - mle_message_timeout_params_t timeout; - uint8_t ll64[16]; - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - uint32_t keySequence; - uint16_t bufId; - uint8_t mode; - if (!cur) { - return -1; - } - - if (!thread_info(cur)) { - return -1; - } - - //routers do not send keep alive - if (thread_i_am_router(cur)){ - return -1; - } - - tr_debug("Child Keep Alive"); - bufId = mle_service_msg_allocate(cur->id, 150 + 3 + 6 + 10, false,MLE_COMMAND_CHILD_UPDATE_REQUEST); - if (bufId == 0) { - return -1; - } - - thread_management_get_current_keysequence(cur->id, &keySequence); - mle_service_msg_update_security_params(bufId, 5, 2, keySequence); - mode = thread_mode_get_by_interface_ptr(cur); - - uint8_t *ptr = mle_service_get_data_pointer(bufId); - ptr = mle_general_write_source_address(ptr, cur); - ptr = mle_tlv_write_mode(ptr, mode); - - ptr = thread_leader_data_tlv_write(ptr, cur); - - //Set Addresss TLV - if ((mode & MLE_FFD_DEV) == 0) { - ptr = thread_address_registration_tlv_write(ptr, cur); - } - - memcpy(ll64, ADDR_LINK_LOCAL_PREFIX, 8); - memcpy(&ll64[8], mac64, 8); - ll64[8] ^= 2; - if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { - tr_debug("Buffer overflow at message write"); - } - timeout.retrans_max = 3; - timeout.timeout_init = 1; - timeout.timeout_max = 4; - timeout.delay = MLE_NO_DELAY; - - //SET Destination address - mle_service_set_msg_destination_address(bufId, ll64); - //Set Callback - mle_service_set_packet_callback(bufId, thread_child_keep_alive_callback); - mle_service_set_msg_timeout_parameters(bufId, &timeout); - mle_service_send_message(bufId); - return 0; -} - /** * Return lower (worse) of the two margins. */ @@ -1014,6 +920,7 @@ static void thread_interface_bootsrap_mode_init(protocol_interface_info_entry_t cur->thread_info->thread_device_mode = THREAD_DEVICE_MODE_SLEEPY_END_DEVICE; //SET Sleepy Host To RX on Idle mode for bootsrap nwk_thread_host_control(cur, NET_HOST_RX_ON_IDLE, 0); + cur->thread_info->childUpdateReqTimer = 0.8 * cur->thread_info->host_link_timeout; } else { tr_debug("Set End node Mode"); cur->thread_info->thread_device_mode = THREAD_DEVICE_MODE_END_DEVICE; @@ -1134,7 +1041,9 @@ void thread_tasklet(arm_event_s *event) case THREAD_CHILD_UPDATE: tr_debug_extra("Thread SM THREAD_CHILD_UPDATE"); - thread_bootstrap_child_update(cur); + if (thread_info(cur)->thread_endnode_parent) { + thread_host_bootstrap_child_update(cur->id, cur->thread_info->thread_endnode_parent->mac64); + } break; case THREAD_ANNOUNCE_ACTIVE: { tr_debug_extra("Thread SM THREAD_ANNOUNCE_ACTIVE"); @@ -2333,21 +2242,7 @@ void thread_bootstrap_stop(protocol_interface_info_entry_t *cur) void thread_bootstrap_child_update_trig(protocol_interface_info_entry_t *cur) { - if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED) { - if (cur->thread_info->thread_endnode_parent == NULL) { - return; - } - - if (cur->thread_info->thread_endnode_parent->childUpdateProcessActive) { - //Set Pending if earlier proces is already started - cur->thread_info->thread_endnode_parent->childUpdatePending = true; - return; - } - //Trig event - cur->thread_info->thread_endnode_parent->childUpdatePending = false; - cur->thread_info->thread_endnode_parent->childUpdateProcessActive = true; - cur->thread_info->thread_endnode_parent->childUpdateProcessStatus = false; - + if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED && cur->thread_info->thread_endnode_parent) { thread_bootsrap_event_trig(THREAD_CHILD_UPDATE, cur->bootStrapId, ARM_LIB_HIGH_PRIORITY_EVENT); } } diff --git a/source/6LoWPAN/Thread/thread_common.c b/source/6LoWPAN/Thread/thread_common.c index afd6552f7652..7f5b52fac688 100644 --- a/source/6LoWPAN/Thread/thread_common.c +++ b/source/6LoWPAN/Thread/thread_common.c @@ -880,7 +880,6 @@ static void thread_child_update_req_timer(protocol_interface_info_entry_t *cur, if (cur->thread_info->childUpdateReqTimer == -1) { return; } - if (cur->thread_info->childUpdateReqTimer > seconds) { cur->thread_info->childUpdateReqTimer -= seconds; } else { diff --git a/source/6LoWPAN/Thread/thread_common.h b/source/6LoWPAN/Thread/thread_common.h index 9cadc1b5ed3e..8a70e5661bd5 100644 --- a/source/6LoWPAN/Thread/thread_common.h +++ b/source/6LoWPAN/Thread/thread_common.h @@ -174,7 +174,6 @@ typedef struct thread_parent_info_s { uint8_t pathCostToLeader; bool childUpdatePending: 1; bool childUpdateProcessActive: 1; - bool childUpdateProcessStatus: 1; } thread_parent_info_t; @@ -289,6 +288,7 @@ typedef struct thread_info_s { uint16_t reedJitterTimer; uint16_t routerIdReqCoapID; // COAP msg id of RouterID request int16_t childUpdateReqTimer; + uint16_t childUpdateReqMsgId; uint16_t proactive_an_timer; //uint8_t lastValidRouteMask[8]; int8_t interface_id; //Thread Interface ID diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index 4a471c92fe7f..02d052c86fbc 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -1106,45 +1106,35 @@ static int thread_attach_child_id_request_build(protocol_interface_info_entry_t static bool thread_child_update_timeout_cb(int8_t interface_id, uint16_t msgId, bool usedAllRerties) { protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - (void)msgId; if (!cur || !cur->thread_info->thread_endnode_parent) { return false; } - tr_debug("Child Update CB"); - if (cur->thread_info->thread_endnode_parent->childUpdateProcessStatus) { - //This process is ready - cur->thread_info->thread_endnode_parent->childUpdateProcessStatus = false; - if (!cur->thread_info->thread_endnode_parent->childUpdatePending) { - - cur->thread_info->thread_endnode_parent->childUpdateProcessActive = false; - //Disable Poll - mac_data_poll_protocol_poll_mode_decrement(cur); - tr_debug("Child Update ready"); - } else { - cur->thread_info->thread_endnode_parent->childUpdatePending = false; - tr_debug("Child Update Pending"); - thread_bootsrap_event_trig(THREAD_CHILD_UPDATE, cur->bootStrapId, ARM_LIB_HIGH_PRIORITY_EVENT); - } + if (msgId != cur->thread_info->childUpdateReqMsgId) { + //Wrong message id return false; } if (usedAllRerties) { - + tr_debug("Child Update timed out"); cur->thread_info->thread_endnode_parent->childUpdatePending = false; cur->thread_info->thread_endnode_parent->childUpdateProcessActive = false; - cur->thread_info->thread_endnode_parent->childUpdateProcessStatus = false; mac_data_poll_protocol_poll_mode_decrement(cur); thread_bootstrap_reset_restart(cur->id); tr_debug("Restart attachment"); return false; } + if (cur->thread_info->thread_endnode_parent->childUpdateProcessActive) { + // we have not received response so re-send + return true; + } - return true; + return false; } -int8_t thread_bootstrap_child_update(protocol_interface_info_entry_t *cur) +int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *mac64) { + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); mle_message_timeout_params_t timeout; uint8_t mode; uint32_t keySequence; @@ -1153,6 +1143,16 @@ int8_t thread_bootstrap_child_update(protocol_interface_info_entry_t *cur) return -1; } + if (cur->thread_info->thread_endnode_parent->childUpdateProcessActive) { + //Set Pending if earlier process is already started + cur->thread_info->thread_endnode_parent->childUpdatePending = true; + return -1; + } + //Trig event + cur->thread_info->thread_endnode_parent->childUpdatePending = false; + cur->thread_info->thread_endnode_parent->childUpdateProcessActive = true; + + tr_debug("Child Update Request"); mode = thread_mode_get_by_interface_ptr(cur); @@ -1169,11 +1169,12 @@ int8_t thread_bootstrap_child_update(protocol_interface_info_entry_t *cur) uint8_t *address_ptr = mle_service_get_msg_destination_address_pointer(bufId); memcpy(address_ptr, ADDR_LINK_LOCAL_PREFIX, 8); - memcpy(address_ptr + 8, cur->thread_info->thread_endnode_parent->mac64, 8); + memcpy(address_ptr + 8, mac64, 8); address_ptr[8] ^= 2; uint8_t *ptr = mle_service_get_data_pointer(bufId); ptr = mle_tlv_write_mode(ptr, mode); + ptr = mle_general_write_source_address(ptr, cur); ptr = mle_tlv_write_timeout(ptr, cur->thread_info->host_link_timeout); ptr = thread_leader_data_tlv_write(ptr, cur); @@ -1194,6 +1195,7 @@ int8_t thread_bootstrap_child_update(protocol_interface_info_entry_t *cur) thread_end_device_mode_set(cur, false); } mac_data_poll_init_protocol_poll(cur); + cur->thread_info->childUpdateReqMsgId = bufId; mle_service_set_packet_callback(bufId, thread_child_update_timeout_cb); mle_service_set_msg_timeout_parameters(bufId, &timeout); mle_service_send_message(bufId); diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.h b/source/6LoWPAN/Thread/thread_host_bootstrap.h index 89b73f1abb43..e154208540d6 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.h +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.h @@ -42,7 +42,7 @@ struct protocol_interface_info_entry; struct mle_security_header; void thread_network_attach_start(struct protocol_interface_info_entry *cur); -int8_t thread_bootstrap_child_update(struct protocol_interface_info_entry *cur); +int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *mac64); int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge); void thread_child_set_default_route(struct protocol_interface_info_entry *cur); diff --git a/source/6LoWPAN/Thread/thread_mle_message_handler.c b/source/6LoWPAN/Thread/thread_mle_message_handler.c index e56475279143..8f891b4a74cb 100644 --- a/source/6LoWPAN/Thread/thread_mle_message_handler.c +++ b/source/6LoWPAN/Thread/thread_mle_message_handler.c @@ -764,7 +764,7 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t * bool leader_data_received; tr_debug("Child Update Response"); - + //mle_service_buffer_find leader_data_received = thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData); entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); @@ -783,8 +783,7 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t * return; } - if ((security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) - && (thread_instance_id_matches(cur, &leaderData))) { + if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); } else { tr_debug("Key ID Mode 2 not used; dropped."); @@ -796,12 +795,13 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t * return; } + timeout = cur->thread_info->host_link_timeout; if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) { entry_temp->holdTime = 90; tr_debug("Setting child timeout, value=%"PRIu32, timeout); mle_entry_timeout_update(entry_temp, timeout); - thread_info(cur)->thread_endnode_parent->childUpdateProcessStatus = true; } + tr_debug("Keep-Alive -->Respond from Parent"); mle_entry_timeout_refresh(entry_temp); @@ -809,7 +809,22 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t * if (leader_data_received) { thread_save_leader_data(cur, &leaderData); } + + if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) { + if (cur->thread_info->childUpdateReqTimer < 1) { + cur->thread_info->childUpdateReqTimer = 0.8 * timeout; + } + } + //This process is ready + cur->thread_info->thread_endnode_parent->childUpdateProcessActive = false; + if (cur->thread_info->thread_endnode_parent->childUpdatePending) { + tr_debug("Child Update Pending"); + thread_bootsrap_event_trig(THREAD_CHILD_UPDATE, cur->bootStrapId, ARM_LIB_HIGH_PRIORITY_EVENT); + return; + } + mac_data_poll_protocol_poll_mode_decrement(cur); + } #endif diff --git a/test/nanostack/unittest/stub/thread_host_bootstrap_stub.c b/test/nanostack/unittest/stub/thread_host_bootstrap_stub.c index 4b1ce56b948b..cc4c457c25cc 100644 --- a/test/nanostack/unittest/stub/thread_host_bootstrap_stub.c +++ b/test/nanostack/unittest/stub/thread_host_bootstrap_stub.c @@ -83,7 +83,7 @@ void thread_endevice_synch_start(protocol_interface_info_entry_t *cur) { } -int8_t thread_bootstrap_child_update(protocol_interface_info_entry_t *cur) +int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *mac64) { return 0; } From c18d1fd27191eac23811e4ebf9d587a5a2a12e4e Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Mon, 19 Feb 2018 13:39:29 +0200 Subject: [PATCH 07/52] added check for parent info before processing child update (#1577) --- source/6LoWPAN/Thread/thread_mle_message_handler.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/6LoWPAN/Thread/thread_mle_message_handler.c b/source/6LoWPAN/Thread/thread_mle_message_handler.c index 8f891b4a74cb..0e9cb8f09721 100644 --- a/source/6LoWPAN/Thread/thread_mle_message_handler.c +++ b/source/6LoWPAN/Thread/thread_mle_message_handler.c @@ -763,7 +763,12 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t * uint8_t status; bool leader_data_received; + if (cur->thread_info->thread_endnode_parent == NULL) { + return; + } + tr_debug("Child Update Response"); + //mle_service_buffer_find leader_data_received = thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData); entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); From d2ddb1a13a74e5576ee566411f89a3523d8413f0 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Tue, 20 Feb 2018 17:02:25 +0200 Subject: [PATCH 08/52] Send new a/sd immediately after address change (#1576) When new address is assigned to Thread BR it will: - cancel previous a/sd and a/as messages - send a/sd (Server Data Notification) immediately --- source/6LoWPAN/Thread/thread_bootstrap.c | 8 +++++++- source/6LoWPAN/Thread/thread_border_router_api.c | 13 ++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index 05a158985c52..6e691f63d962 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -1010,7 +1010,13 @@ void thread_tasklet(arm_event_s *event) thread_bootstrap_child_id_request(cur); if (thread_nd_own_service_list_data_size(&cur->thread_info->localServerDataBase)) { // publish our services to allow leader to remove old ones - thread_border_router_publish(cur->id); + if (!cur->thread_info->localServerDataBase.publish_active) { + /* + * publish only when publish is not active, otherwise let resubmit timer check + * handle publish after short time period. + */ + thread_border_router_publish(cur->id); + } } thread_router_bootstrap_address_change_notify_send(cur); // Validate network data after a short period diff --git a/source/6LoWPAN/Thread/thread_border_router_api.c b/source/6LoWPAN/Thread/thread_border_router_api.c index 00bdc8484109..d1b29937efd8 100644 --- a/source/6LoWPAN/Thread/thread_border_router_api.c +++ b/source/6LoWPAN/Thread/thread_border_router_api.c @@ -884,9 +884,16 @@ int thread_border_router_publish(int8_t interface_id) tr_debug("Border router old: %x, new: %x", cur->thread_info->localServerDataBase.registered_rloc16, rloc16); if (cur->thread_info->localServerDataBase.publish_active) { - cur->thread_info->localServerDataBase.publish_pending = true; - tr_debug("Activate pending status for publish"); - return 0; + if (rloc16 != cur->thread_info->localServerDataBase.registered_rloc16) { + /* + * Device short address has changed, cancel previous a/sd and a/as requests + * */ + thread_management_client_pending_coap_request_kill(cur->id); + } else { + cur->thread_info->localServerDataBase.publish_pending = true; + tr_debug("Activate pending status for publish"); + return 0; + } } //Allocate Memory for Data From a1acffceea20580e6a1b2b4bdb0ff0033d132ea9 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Thu, 22 Feb 2018 10:00:41 +0200 Subject: [PATCH 09/52] Update Thread publishing during address change (#1581) Pending request is cancelled if device address has changed. Following publish will trigger new a/sd. --- source/6LoWPAN/Thread/thread_bootstrap.c | 8 +------- source/6LoWPAN/Thread/thread_border_router_api.c | 4 ++++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index 6e691f63d962..05a158985c52 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -1010,13 +1010,7 @@ void thread_tasklet(arm_event_s *event) thread_bootstrap_child_id_request(cur); if (thread_nd_own_service_list_data_size(&cur->thread_info->localServerDataBase)) { // publish our services to allow leader to remove old ones - if (!cur->thread_info->localServerDataBase.publish_active) { - /* - * publish only when publish is not active, otherwise let resubmit timer check - * handle publish after short time period. - */ - thread_border_router_publish(cur->id); - } + thread_border_router_publish(cur->id); } thread_router_bootstrap_address_change_notify_send(cur); // Validate network data after a short period diff --git a/source/6LoWPAN/Thread/thread_border_router_api.c b/source/6LoWPAN/Thread/thread_border_router_api.c index d1b29937efd8..acad9e474cf1 100644 --- a/source/6LoWPAN/Thread/thread_border_router_api.c +++ b/source/6LoWPAN/Thread/thread_border_router_api.c @@ -887,8 +887,12 @@ int thread_border_router_publish(int8_t interface_id) if (rloc16 != cur->thread_info->localServerDataBase.registered_rloc16) { /* * Device short address has changed, cancel previous a/sd and a/as requests + * and start resubmit timer * */ + tr_debug("address changed, kill pending reuqests"); thread_management_client_pending_coap_request_kill(cur->id); + thread_border_router_resubmit_timer_set(interface_id, 5); + return 0; } else { cur->thread_info->localServerDataBase.publish_pending = true; tr_debug("Activate pending status for publish"); From 09cff0e14ef7cee102fd545e764b47ceadedd536 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Thu, 22 Feb 2018 14:16:30 +0200 Subject: [PATCH 10/52] Fix uninitialised memory defect found by valgrind (#1582) Fix "Conditional jump or move depends on uninitialised value(s)" by initializing eiid after allocation. --- source/6LoWPAN/Thread/thread_common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/6LoWPAN/Thread/thread_common.c b/source/6LoWPAN/Thread/thread_common.c index 7f5b52fac688..936bef63058b 100644 --- a/source/6LoWPAN/Thread/thread_common.c +++ b/source/6LoWPAN/Thread/thread_common.c @@ -717,6 +717,7 @@ void thread_child_id_request_info_init(thread_pending_child_id_req_t *child_info thread_pending_child_id_req_t *thread_child_id_request_allocate(void) { thread_pending_child_id_req_t *req = ns_dyn_mem_alloc(sizeof(thread_pending_child_id_req_t)); + memset(req->eiid, 0 , 8); thread_child_id_request_info_init(req); return req; } From 648ef890e720709eafb4b6264bd89847d4314e66 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Fri, 23 Feb 2018 09:50:51 +0200 Subject: [PATCH 11/52] Remove unnecessary call to mac (#1583) Remove additional call to mac_helper_devicetable_set. --- source/6LoWPAN/Thread/thread_router_bootstrap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/6LoWPAN/Thread/thread_router_bootstrap.c b/source/6LoWPAN/Thread/thread_router_bootstrap.c index c6e8cd185f0b..4a6ded84ce23 100644 --- a/source/6LoWPAN/Thread/thread_router_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_router_bootstrap.c @@ -361,7 +361,6 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m //Free Response mle_service_msg_free(messageId); entry_temp->threadNeighbor = true; - mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex); entry_temp->short_adr = shortAddress; //when allocating neighbour entry, use MLE Frame counter if present to validate further advertisements from the neighbour entry_temp->mle_frame_counter = mleFrameCounter; From 912cf02473c08fc0e91f7eb91d9d144042b89dcf Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Wed, 28 Feb 2018 08:53:02 +0200 Subject: [PATCH 12/52] purge old partition data when child id response is received (#1588) --- source/6LoWPAN/Thread/thread_host_bootstrap.c | 8 ++++---- source/6LoWPAN/Thread/thread_routing.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index 02d052c86fbc..3a5c3be660f3 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -121,12 +121,10 @@ static void thread_merge_prepare(protocol_interface_info_entry_t *cur) { thread_clean_old_16_bit_address_based_addresses(cur); mpl_clear_realm_scope_seeds(cur); - ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache); ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL); - thread_routing_deactivate(&cur->thread_info->routing); - thread_routing_init(&cur->thread_info->routing); - cur->nwk_mode = ARM_NWK_GP_IP_MODE; + thread_old_partition_data_purge(cur); thread_network_data_clean(cur); + cur->nwk_mode = ARM_NWK_GP_IP_MODE; } //This function is for Thread Parent scan callback @@ -1139,6 +1137,7 @@ int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *ma uint8_t mode; uint32_t keySequence; + if (!cur->thread_info->thread_endnode_parent) { return -1; } @@ -1199,6 +1198,7 @@ int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *ma mle_service_set_packet_callback(bufId, thread_child_update_timeout_cb); mle_service_set_msg_timeout_parameters(bufId, &timeout); mle_service_send_message(bufId); + return 0; } int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge) diff --git a/source/6LoWPAN/Thread/thread_routing.c b/source/6LoWPAN/Thread/thread_routing.c index ec672ae26aa9..1f8455e7a2b8 100644 --- a/source/6LoWPAN/Thread/thread_routing.c +++ b/source/6LoWPAN/Thread/thread_routing.c @@ -879,7 +879,6 @@ void thread_routing_init(thread_routing_info_t *routing) { ns_list_init(&routing->route_set); ns_list_init(&routing->link_set); - routing->networkIdTimeout = NETWORK_ID_TIMEOUT; thread_routing_reset(routing); } @@ -887,6 +886,7 @@ void thread_routing_reset(thread_routing_info_t *routing) { thread_routing_free(routing); routing->router_id_sequence_valid = false; + routing->networkIdTimeout = NETWORK_ID_TIMEOUT; memset(routing->fast_route_table, FAST_ROUTE_INVALID_ID, sizeof routing->fast_route_table); trickle_start(&routing->mle_advert_timer, &thread_mle_advert_trickle_params); } From f2cd4cfb96856ee060b86caaffb560f49a020208 Mon Sep 17 00:00:00 2001 From: Kari Severinkangas Date: Thu, 1 Mar 2018 11:44:29 +0200 Subject: [PATCH 13/52] Read the short addr as 16-bit value before calling mac api (#1585) --- source/6LoWPAN/MAC/mac_helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/6LoWPAN/MAC/mac_helper.c b/source/6LoWPAN/MAC/mac_helper.c index d26140937b1f..75e2777833f3 100644 --- a/source/6LoWPAN/MAC/mac_helper.c +++ b/source/6LoWPAN/MAC/mac_helper.c @@ -433,8 +433,9 @@ void mac_helper_coordinator_address_set(protocol_interface_info_entry_t *interfa if (adr_type == ADDR_802_15_4_SHORT) { memcpy(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address, adr_ptr, 2); interface->mac_parameters->mac_cordinator_info.cord_adr_mode = MAC_ADDR_MODE_16_BIT; + uint16_t short_addr = common_read_16_bit(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address); set_req.attr = macCoordShortAddress; - set_req.value_pointer = &interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address; + set_req.value_pointer = &short_addr; set_req.value_size = 2; } else if (adr_type == ADDR_802_15_4_LONG) { memcpy(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address, adr_ptr, 8); From 0e850991201fbe9d97a5c01e4b2b32c6f6d5ad64 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Thu, 1 Mar 2018 13:52:49 +0200 Subject: [PATCH 14/52] Update router id sequence number in router sync (#1594) Router id sequence number updated in router sync to ensure that the number will be updated in case of power cycling leader. --- source/6LoWPAN/Thread/thread_leader_service.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/6LoWPAN/Thread/thread_leader_service.c b/source/6LoWPAN/Thread/thread_leader_service.c index 622f9de18e8c..4ad8f3d95d41 100644 --- a/source/6LoWPAN/Thread/thread_leader_service.c +++ b/source/6LoWPAN/Thread/thread_leader_service.c @@ -1483,6 +1483,7 @@ void thread_leader_service_timer(protocol_interface_info_entry_t *cur, uint32_t thread_bootstrap_network_data_update(cur); } } + if (cur->thread_info->leader_private_data->leader_id_seq_timer) { if (cur->thread_info->leader_private_data->leader_id_seq_timer > ticks) { cur->thread_info->leader_private_data->leader_id_seq_timer -= ticks; @@ -1637,6 +1638,9 @@ int thread_leader_service_thread_partitition_restart(int8_t interface_id, mle_tl // Clear network data (if exists) and propagate new empty network data thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage); thread_network_data_base_init(&cur->thread_info->networkDataStorage); + // Update router sequence id to prevent network fragmentation in case of Leader was temporarily down + // and routers were not able to get new sequence id for NETWORK_ID_TIMEOUT duration. + thread_leader_service_update_id_set(cur); return 0; } From b69ba04ab675cd395214b47649169c94b50e2318 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Wed, 7 Mar 2018 11:55:31 +0200 Subject: [PATCH 15/52] Allow MLE entry forced saving to MAC (#1600) New MLE entries are not saved to MAC layer if key indexes were not matching. When new MLE entry is created then make forced save to MAC. --- .../Generic/protocol_6lowpan_bootstrap.c | 12 +-- source/6LoWPAN/MAC/mac_helper.c | 4 +- source/6LoWPAN/MAC/mac_helper.h | 2 +- source/6LoWPAN/MAC/mac_pairwise_key.c | 8 +- source/6LoWPAN/Thread/thread_host_bootstrap.c | 22 +++-- .../Thread/thread_mle_message_handler.c | 16 ++-- source/6LoWPAN/Thread/thread_network_synch.c | 5 +- .../6LoWPAN/Thread/thread_router_bootstrap.c | 27 +++--- source/MLE/mle.c | 17 ++-- source/MLE/mle.h | 4 +- .../6lp_mac/mac_helper/test_mac_helper.c | 4 +- test/nanostack/unittest/mle/mle/test_mle.c | 92 ++++++++++++------- .../nanostack/unittest/stub/mac_helper_stub.c | 2 +- test/nanostack/unittest/stub/mle_stub.c | 4 +- 14 files changed, 125 insertions(+), 94 deletions(-) diff --git a/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c b/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c index 06dbf49f4176..4be6abcc2811 100644 --- a/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c +++ b/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c @@ -758,7 +758,7 @@ static int mle_router_accept_request_build(protocol_interface_info_entry_t *cur, static void protocol_6lowpan_link_reject_handler(protocol_interface_info_entry_t *cur, uint8_t *ll64) { - mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, 0, ll64, false); + mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, 0, ll64, false, NULL); tr_debug("MLE link reject"); if (entry_temp) { mle_class_remove_entry(cur->id, entry_temp); @@ -1081,7 +1081,7 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml mle_6lowpan_data->link_req_token_bucket--; } else { //Update only old information based on link request - entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL); if (entry_temp) { mle_neigh_time_and_mode_update(entry_temp,mle_msg->data_ptr, mle_msg->data_length); mle_neigh_entry_update_by_mle_tlv_list(interface_id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); @@ -1118,12 +1118,12 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml tr_debug("Accept & Request"); - entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL); if (!entry_temp) { // If there is space for neighbors try to allocate new entry if (mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, true)) { - entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, true); + entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, true, NULL); } } @@ -1185,7 +1185,7 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml mode = *t_ptr; } - entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL); if (!entry_temp) { if ((mode & MLE_DEV_MASK) == MLE_FFD_DEV) { // If there is space for neighbors synchronizes to new router @@ -2787,7 +2787,7 @@ bool lowpan_neighbour_data_clean(int8_t interface_id, const uint8_t *link_local_ { bool return_value = false; #ifndef NO_MLE - mle_neigh_table_entry_t * neigh_entry = mle_class_get_entry_by_ll64(interface_id, 0, link_local_address, false); + mle_neigh_table_entry_t * neigh_entry = mle_class_get_entry_by_ll64(interface_id, 0, link_local_address, false, NULL); if (neigh_entry) { //Remove entry if (neigh_entry->priorityFlag) { diff --git a/source/6LoWPAN/MAC/mac_helper.c b/source/6LoWPAN/MAC/mac_helper.c index 75e2777833f3..bf3e6c311514 100644 --- a/source/6LoWPAN/MAC/mac_helper.c +++ b/source/6LoWPAN/MAC/mac_helper.c @@ -831,13 +831,13 @@ void mac_helper_devicetable_remove(mac_api_t *mac_api, uint8_t attribute_index) mac_api->mlme_req(mac_api,MLME_SET , &set_req); } -void mac_helper_devicetable_set(mle_neigh_table_entry_t *entry_temp, protocol_interface_info_entry_t *cur, uint32_t frame_counter, uint8_t keyID) +void mac_helper_devicetable_set(mle_neigh_table_entry_t *entry_temp, protocol_interface_info_entry_t *cur, uint32_t frame_counter, uint8_t keyID, bool force_set) { if (!cur->mac_api) { return; } - if (cur->mac_parameters->SecurityEnabled && cur->mac_parameters->mac_default_key_index != keyID) { + if (!force_set && cur->mac_parameters->SecurityEnabled && cur->mac_parameters->mac_default_key_index != keyID) { tr_debug("Do not set counter by index %u != %u", cur->mac_parameters->mac_default_key_index, keyID); return; } diff --git a/source/6LoWPAN/MAC/mac_helper.h b/source/6LoWPAN/MAC/mac_helper.h index 28ea5331c3d9..a1fe37cd6812 100644 --- a/source/6LoWPAN/MAC/mac_helper.h +++ b/source/6LoWPAN/MAC/mac_helper.h @@ -110,7 +110,7 @@ int8_t mac_helper_link_frame_counter_set(int8_t interface_id, uint32_t seq_ptr); void mac_helper_devicetable_remove(struct mac_api_s *mac_api, uint8_t attribute_index); -void mac_helper_devicetable_set(struct mle_neigh_table_entry_t *entry_temp, struct protocol_interface_info_entry *cur, uint32_t frame_counter, uint8_t keyID); +void mac_helper_devicetable_set(struct mle_neigh_table_entry_t *entry_temp, struct protocol_interface_info_entry *cur, uint32_t frame_counter, uint8_t keyID, bool force_set); int8_t mac_helper_mac_mlme_max_retry_set(int8_t interface_id, uint8_t mac_retry_set); diff --git a/source/6LoWPAN/MAC/mac_pairwise_key.c b/source/6LoWPAN/MAC/mac_pairwise_key.c index 8a53457fac91..bb37e137fd66 100644 --- a/source/6LoWPAN/MAC/mac_pairwise_key.c +++ b/source/6LoWPAN/MAC/mac_pairwise_key.c @@ -252,6 +252,8 @@ int mac_pairwise_key_interface_unregister(int8_t interface_id) int mac_pairwise_key_add(int8_t interface_id, uint32_t valid_life_time, const uint8_t eui64[static 8], const uint8_t key[static 16]) { protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); + bool new_entry_created; + if (!interface || !interface->mac_api) { return -1; } @@ -264,7 +266,7 @@ int mac_pairwise_key_add(int8_t interface_id, uint32_t valid_life_time, const ui } //Allocate mle entry - mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(interface_id, 0, eui64, true); + mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(interface_id, 0, eui64, true, &new_entry_created); if (!mle_entry) { return -1; } @@ -282,7 +284,7 @@ int mac_pairwise_key_add(int8_t interface_id, uint32_t valid_life_time, const ui } //Set device descriptor - mac_helper_devicetable_set(mle_entry, interface, 0, interface->mac_parameters->mac_default_key_index); + mac_helper_devicetable_set(mle_entry, interface, 0, interface->mac_parameters->mac_default_key_index, new_entry_created); //set key descriptor if (mac_helper_security_pairwisekey_set(interface, key, eui64, key_desc->key_decriptor_attribute) != 0) { @@ -308,7 +310,7 @@ int mac_pairwise_key_del(int8_t interface_id, const uint8_t eui64[static 8]) return -1; } //Get from mle - mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(interface_id, 0, eui64, true); + mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(interface_id, 0, eui64, true, NULL); if (!mle_entry) { return -1; } diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index 3a5c3be660f3..e9a2ddc0faee 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -131,6 +131,7 @@ static void thread_merge_prepare(protocol_interface_info_entry_t *cur) static bool thread_parent_discover_timeout_cb(int8_t interface_id, uint16_t msgId, bool usedAllRetries) { protocol_interface_info_entry_t *cur; + bool new_entry_created; cur = protocol_stack_interface_info_get_by_id(interface_id); if (!cur) { @@ -156,7 +157,7 @@ static bool thread_parent_discover_timeout_cb(int8_t interface_id, uint16_t msgI memcpy(&ll64[8], parent->mac64 , 8); ll64[8] ^= 2; - entry_temp = mle_class_get_entry_by_ll64(interface_id, parent->linkMarginToParent,ll64, true); + entry_temp = mle_class_get_entry_by_ll64(interface_id, parent->linkMarginToParent,ll64, true, &new_entry_created); if (entry_temp == NULL) { return false; } @@ -169,7 +170,7 @@ static bool thread_parent_discover_timeout_cb(int8_t interface_id, uint16_t msgI thread_management_key_sets_calc(cur, linkConfiguration, cur->thread_info->thread_attach_scanned_parent->keySequence); thread_calculate_key_guard_timer(cur, linkConfiguration, true); - mac_helper_devicetable_set(entry_temp, cur, parent->linLayerFrameCounter, mac_helper_default_key_index_get(cur)); + mac_helper_devicetable_set(entry_temp, cur, parent->linLayerFrameCounter, mac_helper_default_key_index_get(cur), new_entry_created); mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME); if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) { @@ -292,6 +293,7 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent uint32_t llFrameCounter; thread_leader_data_t leaderData; mle_neigh_table_entry_t *entry_temp; + bool new_entry_created; tr_debug("Validate Link Synch Response"); //Check First Status @@ -322,7 +324,7 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent } //Update parent link information - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, src_address, true); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, src_address, true, &new_entry_created); if (!entry_temp) { tr_debug("Neighbor allocate fail"); @@ -340,7 +342,7 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress); mle_entry_timeout_update(entry_temp, thread_info(cur)->host_link_timeout); - mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, securityHeader->KeyIndex); + mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, securityHeader->KeyIndex, new_entry_created); thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED; thread_bootstrap_update_ml16_address(cur, address16); @@ -757,6 +759,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message uint64_t pending_timestamp = 0; uint64_t active_timestamp; thread_scanned_parent_t *scan_result = thread_info(cur)->thread_attach_scanned_parent; + bool new_entry_created; tr_info("Received Child ID Response"); @@ -772,7 +775,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message thread_merge_prepare(cur); // Create entry for new parent - entry_temp = mle_class_get_entry_by_ll64(cur->id, thread_compute_link_margin(mle_msg->dbm), mle_msg->packet_src_address, true); + entry_temp = mle_class_get_entry_by_ll64(cur->id, thread_compute_link_margin(mle_msg->dbm), mle_msg->packet_src_address, true, &new_entry_created); if (entry_temp == NULL) { // todo: what to do here? return; @@ -829,7 +832,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress); mle_entry_timeout_update(entry_temp, thread_info(cur)->host_link_timeout); - mac_helper_devicetable_set(entry_temp, cur, scan_result->linLayerFrameCounter, security_headers->KeyIndex); + mac_helper_devicetable_set(entry_temp, cur, scan_result->linLayerFrameCounter, security_headers->KeyIndex, new_entry_created); thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED; @@ -924,9 +927,10 @@ void thread_endevice_synch_start(protocol_interface_info_entry_t *cur) { if (cur->thread_info->thread_endnode_parent) { mle_neigh_table_entry_t *entry_temp; + bool new_entry_created; // Add the parent to the MLE neighbor table - entry_temp = mle_class_get_entry_by_mac64(cur->id, 64, cur->thread_info->thread_endnode_parent->mac64, true); + entry_temp = mle_class_get_entry_by_mac64(cur->id, 64, cur->thread_info->thread_endnode_parent->mac64, true, &new_entry_created); if (entry_temp) { entry_temp->short_adr = cur->thread_info->thread_endnode_parent->shortAddress; @@ -938,7 +942,7 @@ void thread_endevice_synch_start(protocol_interface_info_entry_t *cur) mle_entry_timeout_update(entry_temp, 20); // Add the parent to the MAC table (for e.g. secured/fragmented Child Update Response) - mac_helper_devicetable_set(entry_temp, cur, 0, cur->mac_parameters->mac_default_key_index); + mac_helper_devicetable_set(entry_temp, cur, 0, cur->mac_parameters->mac_default_key_index, new_entry_created); } } @@ -996,7 +1000,7 @@ static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, boo memcpy(&ll64[8], scanned_parent->mac64 , 8); ll64[8] ^= 2; - entry_temp = mle_class_get_entry_by_ll64(cur->id, scanned_parent->linkMarginToParent, ll64, false); + entry_temp = mle_class_get_entry_by_ll64(cur->id, scanned_parent->linkMarginToParent, ll64, false, NULL); if (entry_temp) { mle_class_remove_entry(cur->id, entry_temp); } diff --git a/source/6LoWPAN/Thread/thread_mle_message_handler.c b/source/6LoWPAN/Thread/thread_mle_message_handler.c index 0e9cb8f09721..b68592de8bb1 100644 --- a/source/6LoWPAN/Thread/thread_mle_message_handler.c +++ b/source/6LoWPAN/Thread/thread_mle_message_handler.c @@ -102,7 +102,7 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, case MLE_COMMAND_REJECT: { mle_neigh_table_entry_t *entry_temp; tr_warn("Reject Link"); - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); if (entry_temp) { mle_class_remove_entry(cur->id, entry_temp); } @@ -336,7 +336,7 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle } // Get MLE entry - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); if ((security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) && (thread_instance_id_matches(cur, &leaderData))) { @@ -409,7 +409,7 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag uint16_t messageId; uint8_t linkMarginfronNeigh; mle_neigh_table_entry_t *entry_temp; - bool createNew; + bool createNew, new_entry_created; tr_info("MLE LINK ACCEPT"); @@ -435,7 +435,7 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag /* Call to determine whether or not we should create a new link */ createNew = thread_bootstrap_link_create_check(cur, shortAddress); - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, createNew); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, createNew, &new_entry_created); if (!entry_temp) { thread_link_reject_send(cur, mle_msg->packet_src_address); @@ -457,7 +457,7 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag // Set full data as REED needs full data and SED will not make links entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET; - mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex); + mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_entry_created); if (entry_temp->timeout_rx) { mle_entry_timeout_refresh(entry_temp); @@ -551,7 +551,7 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle return; } - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); if(cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER || cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE) { @@ -700,7 +700,7 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent bool data_request_needed = false; tr_debug("Child update request"); - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData) || !entry_temp || @@ -771,7 +771,7 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t * //mle_service_buffer_find leader_data_received = thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData); - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status) && status == 1 && thread_check_is_this_my_parent(cur, entry_temp)) { diff --git a/source/6LoWPAN/Thread/thread_network_synch.c b/source/6LoWPAN/Thread/thread_network_synch.c index 586762760332..8528d0c8b87b 100644 --- a/source/6LoWPAN/Thread/thread_network_synch.c +++ b/source/6LoWPAN/Thread/thread_network_synch.c @@ -238,6 +238,7 @@ void thread_dynamic_storage_build_mle_table(int8_t interface_id) tr_debug("Dynamic storage: building MLE table."); thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); + bool new_entry_created; if (!storeEntry) { storeEntry = thread_network_synch_create(interface_id); @@ -261,7 +262,7 @@ void thread_dynamic_storage_build_mle_table(int8_t interface_id) } uint8_t *mac64 = storeEntry->networ_dynamic_data_parameters.children[i].long_addr; tr_debug("Child: %04x, %s", storeEntry->networ_dynamic_data_parameters.children[i].short_addr, trace_array(mac64, 8)); - mle_neigh_table_entry_t *entry = mle_class_get_entry_by_mac64(interface_id, 64, mac64, true); + mle_neigh_table_entry_t *entry = mle_class_get_entry_by_mac64(interface_id, 64, mac64, true, &new_entry_created); if (entry) { entry->short_adr = storeEntry->networ_dynamic_data_parameters.children[i].short_addr; entry->mle_frame_counter = storeEntry->networ_dynamic_data_parameters.children[i].mle_frame_counter; @@ -272,7 +273,7 @@ void thread_dynamic_storage_build_mle_table(int8_t interface_id) if (cur && cur->mac_parameters) { // Set MAC layer frame counter for the child - mac_helper_devicetable_set(entry, cur, storeEntry->networ_dynamic_data_parameters.children[i].mac_frame_counter, cur->mac_parameters->mac_default_key_index); + mac_helper_devicetable_set(entry, cur, storeEntry->networ_dynamic_data_parameters.children[i].mac_frame_counter, cur->mac_parameters->mac_default_key_index, new_entry_created); } } } diff --git a/source/6LoWPAN/Thread/thread_router_bootstrap.c b/source/6LoWPAN/Thread/thread_router_bootstrap.c index 4a6ded84ce23..0bcb7c4ad19c 100644 --- a/source/6LoWPAN/Thread/thread_router_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_router_bootstrap.c @@ -336,6 +336,7 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m case MLE_COMMAND_ACCEPT: { tr_info("Accept (ROUTER handler)"); uint32_t mleFrameCounter; + bool new_neigbour; uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { @@ -353,7 +354,7 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m } //Allocate neighbor entry - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, true); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, true, &new_neigbour); if (!entry_temp) { return; } @@ -387,7 +388,7 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh); } - mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex); + mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_neigbour); //Copy Leader Data *cur->thread_info->thread_leader_data = leaderData; @@ -1308,12 +1309,8 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c memcpy(&ll64[8], req->euid64 , 8); ll64[8] ^= 2; //Allocate entry - mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, req->linkMargin, ll64, false); + mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, req->linkMargin, ll64, true, &new_neigbour); - if (!entry_temp) { - entry_temp = mle_class_get_entry_by_ll64(cur->id, req->linkMargin, ll64, true); - new_neigbour = true; - } if (!entry_temp) { //Send link reject thread_link_reject_send(cur, ll64); @@ -1339,7 +1336,7 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c } } if (new_neigbour) { - mac_helper_devicetable_set(entry_temp, cur, req->frameCounter, req->keyId); + mac_helper_devicetable_set(entry_temp, cur, req->frameCounter, req->keyId, new_neigbour); } else { // in get response handler this will update the short address from MLE table mlme_get_t get_req; @@ -1473,7 +1470,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * } // parent request received - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); if (entry_temp) { entry_temp->mode = (MLE_FFD_DEV | MLE_RX_ON_IDLE | MLE_THREAD_REQ_FULL_DATA_SET); } @@ -1726,7 +1723,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * return; } - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) { @@ -1825,7 +1822,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * uint16_t version, shortAddress; uint32_t llFrameCounter; mle_tlv_info_t requestTlv, challengeTlv; - bool createNew; + bool createNew, new_entry; tr_info("Recv Router Accept & Request"); uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); @@ -1853,7 +1850,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * createNew = thread_bootstrap_link_create_check(cur, shortAddress); //Send Response - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, createNew); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, createNew, &new_entry); if (entry_temp) { if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { @@ -1862,7 +1859,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * entry_temp->threadNeighbor = true; entry_temp->short_adr = shortAddress; - mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex); + mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_entry); if (entry_temp->timeout_rx) { mle_entry_timeout_refresh(entry_temp); } else { @@ -1899,7 +1896,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * mle_tlv_info_t addressRegisterTlv = {0}; mle_tlv_info_t challengeTlv = {0}; mle_tlv_info_t tlv_req = {0}; - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status)) { if (1 == status && thread_check_is_this_my_parent(cur, entry_temp)) { @@ -1969,7 +1966,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * case MLE_COMMAND_DATA_REQUEST: { mle_tlv_info_t requestTlv; tr_info("Recv Router Data Request"); - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); + entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); if (!entry_temp || !mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &requestTlv)) { return; } diff --git a/source/MLE/mle.c b/source/MLE/mle.c index b70eb607999f..39177b1537d0 100644 --- a/source/MLE/mle.c +++ b/source/MLE/mle.c @@ -386,9 +386,8 @@ int16_t mle_class_rfd_entry_count_get(int8_t interface_id) return count; } -mle_neigh_table_entry_t *mle_class_get_entry_by_ll64(int8_t interface_id, uint8_t linkMargin, const uint8_t *ipv6Address, bool allocateNew) +mle_neigh_table_entry_t *mle_class_get_entry_by_ll64(int8_t interface_id, uint8_t linkMargin, const uint8_t *ipv6Address, bool allocateNew, bool *new_entry_allocated) { - // Check it really is LL64 (not LL16) if (memcmp(ipv6Address, ADDR_LINK_LOCAL_PREFIX , 8) != 0) { @@ -403,10 +402,9 @@ mle_neigh_table_entry_t *mle_class_get_entry_by_ll64(int8_t interface_id, uint8_ memcpy(temporary_mac64, (ipv6Address + 8), 8); temporary_mac64[0] ^= 2; - return mle_class_get_entry_by_mac64(interface_id, linkMargin, temporary_mac64,allocateNew); + return mle_class_get_entry_by_mac64(interface_id, linkMargin, temporary_mac64, allocateNew, new_entry_allocated); } - mle_neigh_table_entry_t *mle_class_discover_entry_by_ll64(int8_t interface_id, const uint8_t *ipv6Address) { @@ -428,7 +426,7 @@ mle_neigh_table_entry_t *mle_class_discover_entry_by_ll64(int8_t interface_id, c } -mle_neigh_table_entry_t *mle_class_get_entry_by_mac64(int8_t interface_id, uint8_t linkMargin, const uint8_t *mac64, bool allocateNew) +mle_neigh_table_entry_t *mle_class_get_entry_by_mac64(int8_t interface_id, uint8_t linkMargin, const uint8_t *mac64, bool allocateNew, bool *new_entry_allocated) { mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); //Clean list and set function pointer call backs @@ -436,6 +434,10 @@ mle_neigh_table_entry_t *mle_class_get_entry_by_mac64(int8_t interface_id, uint8 return NULL; } + if (new_entry_allocated) { + *new_entry_allocated = false; + } + mle_neigh_table_entry_t *ret_val = mle_class_neighbor_get(&mle_class_ptr->mle_table, mac64, ADDR_802_15_4_LONG); @@ -454,6 +456,9 @@ mle_neigh_table_entry_t *mle_class_get_entry_by_mac64(int8_t interface_id, uint8 topo_trace(TOPOLOGY_MLE, mac64, TOPO_ADD); ret_val->link_margin = linkMargin << THREAD_LINK_MARGIN_SCALING; memcpy(ret_val->mac64, mac64, 8); + if (new_entry_allocated) { + *new_entry_allocated = true; + } } } return ret_val; @@ -788,7 +793,7 @@ bool mle_neigh_entry_frame_counter_update(mle_neigh_table_entry_t *entry_temp, u frame_counter = common_read_32_bit(mle_tlv_info.dataPtr); } - mac_helper_devicetable_set(entry_temp, cur, frame_counter, key_id); + mac_helper_devicetable_set(entry_temp, cur, frame_counter, key_id, false); return true; } diff --git a/source/MLE/mle.h b/source/MLE/mle.h index 59600b5f0d5f..3d16cdec4050 100644 --- a/source/MLE/mle.h +++ b/source/MLE/mle.h @@ -211,11 +211,11 @@ int8_t mle_class_set_new_key_pending(int8_t interface_id); int16_t mle_class_free_entry_count_get(int8_t interface_id); -mle_neigh_table_entry_t *mle_class_get_entry_by_ll64(int8_t interface_id, uint8_t linkMargin, const uint8_t *ipv6Address, bool allocateNew); +mle_neigh_table_entry_t *mle_class_get_entry_by_ll64(int8_t interface_id, uint8_t linkMargin, const uint8_t *ipv6Address, bool allocateNew, bool *new_entry_allocated); mle_neigh_table_entry_t *mle_class_discover_entry_by_ll64(int8_t interface_id, const uint8_t *ipv6Address); -mle_neigh_table_entry_t *mle_class_get_entry_by_mac64(int8_t interface_id, uint8_t linkMargin, const uint8_t *mac64, bool allocateNew); +mle_neigh_table_entry_t *mle_class_get_entry_by_mac64(int8_t interface_id, uint8_t linkMargin, const uint8_t *mac64, bool allocateNew, bool *new_entry_allocated); mle_neigh_table_entry_t *mle_class_get_by_link_address(int8_t interface_id, const uint8_t *address, addrtype_t type); diff --git a/test/nanostack/unittest/6lp_mac/mac_helper/test_mac_helper.c b/test/nanostack/unittest/6lp_mac/mac_helper/test_mac_helper.c index 18f8fb206073..f151aa24f06a 100644 --- a/test/nanostack/unittest/6lp_mac/mac_helper/test_mac_helper.c +++ b/test/nanostack/unittest/6lp_mac/mac_helper/test_mac_helper.c @@ -855,12 +855,12 @@ bool test_mac_helper_devicetable_set() entry.mac_parameters->SecurityEnabled = false; - mac_helper_devicetable_set(&entry_temp, &entry, 10, 1); + mac_helper_devicetable_set(&entry_temp, &entry, 10, 1, true); entry.mac_parameters->SecurityEnabled = true; entry.mac_parameters->mac_default_key_index = 2; - mac_helper_devicetable_set(&entry_temp, &entry, 10, 1); + mac_helper_devicetable_set(&entry_temp, &entry, 10, 1, false); return true; diff --git a/test/nanostack/unittest/mle/mle/test_mle.c b/test/nanostack/unittest/mle/mle/test_mle.c index e06714054504..18675ffeeb89 100644 --- a/test/nanostack/unittest/mle/mle/test_mle.c +++ b/test/nanostack/unittest/mle/mle/test_mle.c @@ -189,7 +189,7 @@ bool test_mle_class_set_new_key_pending() return false; } - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true, NULL); if (!mle_entry) { return false; } @@ -210,6 +210,7 @@ bool test_mle_class_free_entry_count_get() ll64[0] = 0xfe; ll64[1] = 0x80; mle_neigh_table_entry_t *mle_entry; + bool new_entry; if (0 != mle_class_free_entry_count_get(0)) { return false; @@ -220,12 +221,16 @@ bool test_mle_class_free_entry_count_get() return false; } - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true, &new_entry); if (!mle_entry) { return false; } + if (!new_entry) { + return false; + } + if (0 == mle_class_free_entry_count_get(0)) { return false; } @@ -237,23 +242,28 @@ bool test_mle_class_free_entry_count_get() bool test_mle_class_get_entry_by_ll64() { uint8_t ll64[16]; + bool new_entry; + memset(ll64, 0, 16); mle_neigh_table_entry_t *mle_entry; - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,false); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,false, &new_entry); if (mle_entry) { return false; } + if (new_entry) { + return false; + } memset(ll64, 0, 16); ll64[0] = 0xfe; ll64[1] = 0x80; memcpy(&ll64[8], ADDR_SHORT_ADR_SUFFIC, 6); - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,false); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,false, NULL); if (mle_entry) { return false; } memset(&ll64[8], 0, 6); ll64[8] = 0x02; - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,false); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,false, NULL); if (mle_entry) { return false; } @@ -261,36 +271,39 @@ bool test_mle_class_get_entry_by_ll64() nsdynmemlib_stub.returnCounter = 2; mle_class_init(0, 32, &tester_mle_entry_user_entry_remove_notify, &tester_mle_entry_link_keep_alive, &tester_interface_is_active); - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,false); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,false, NULL); if (mle_entry) { return false; } - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true, &new_entry); if (!mle_entry) { return false; } + if (!new_entry) { + return false; + } uint8_t test_tribute = mle_entry->attribute_index; - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true, NULL); if (!mle_entry || test_tribute != mle_entry->attribute_index) { return false; } - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,false); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,false, NULL); if (!mle_entry || test_tribute != mle_entry->attribute_index) { return false; } for (uint8_t i= 1; i< 32; i++) { ll64[15] = i; - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true, NULL); if (!mle_entry ) { return false; } } ll64[15] = 33; - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true, NULL); if (mle_entry ) { return false; } @@ -332,7 +345,7 @@ bool test_mle_class_discover_entry_by_ll64() return false; } //add address - mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true); + mle_entry = mle_class_get_entry_by_ll64(0, 0,ll64 ,true, NULL); uint8_t test_tribute = mle_entry->attribute_index; mle_entry = mle_class_discover_entry_by_ll64(0,ll64); @@ -368,7 +381,7 @@ bool test_mle_class_get_by_link_address() return false; } - mle_class_get_entry_by_mac64(0,0,mac64, true); + mle_class_get_entry_by_mac64(0,0,mac64, true, NULL); mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(0,mac64, ADDR_802_15_4_LONG); @@ -399,7 +412,7 @@ bool test_mle_class_get_by_link_address() if (mle_class_get_by_link_address(0,mac64, ADDR_802_15_4_LONG)) { return false; } - mle_class_get_entry_by_mac64(0,0,mac64, true); + mle_class_get_entry_by_mac64(0,0,mac64, true, NULL); if (!mle_class_get_by_link_address(0,mac64, ADDR_802_15_4_LONG)) { return false; @@ -431,9 +444,9 @@ bool test_mle_class_get_by_device_attribute_id() } - mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(0,0,mac64_1, true); + mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(0,0,mac64_1, true, NULL); attribute1 = mle_entry->attribute_index; - mle_entry = mle_class_get_entry_by_mac64(0,0,mac64_2, true); + mle_entry = mle_class_get_entry_by_mac64(0,0,mac64_2, true, NULL); attribute2 = mle_entry->attribute_index; @@ -488,8 +501,8 @@ bool test_mle_class_remove_entry() return false; } - mle_neigh_table_entry_t *mle_entry_1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true); - mle_neigh_table_entry_t *mle_entry_2 = mle_class_get_entry_by_mac64(0,0,mac64_2, true); + mle_neigh_table_entry_t *mle_entry_1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true, NULL); + mle_neigh_table_entry_t *mle_entry_2 = mle_class_get_entry_by_mac64(0,0,mac64_2, true, NULL); tester_mle_entry = mle_entry_1; tester_remove_ok = false; @@ -566,9 +579,9 @@ bool test_mle_class_remove_neighbour() nsdynmemlib_stub.returnCounter = 2; mle_class_init(0, 32, &tester2_mle_entry_user_entry_remove_notify, &tester_mle_entry_link_keep_alive, &tester_interface_is_active); - mle_neigh_table_entry_t *mle_entry_1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true); - mle_neigh_table_entry_t *mle_entry_2 = mle_class_get_entry_by_mac64(0,0,mac64_2, true); - mle_neigh_table_entry_t *mle_entry_3 = mle_class_get_entry_by_mac64(0,0,mac64_3, true); + mle_neigh_table_entry_t *mle_entry_1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true, NULL); + mle_neigh_table_entry_t *mle_entry_2 = mle_class_get_entry_by_mac64(0,0,mac64_2, true, NULL); + mle_neigh_table_entry_t *mle_entry_3 = mle_class_get_entry_by_mac64(0,0,mac64_3, true, NULL); mle_entry_1->short_adr = 1; mle_entry_2->short_adr = 2; @@ -683,11 +696,11 @@ bool test_mle_class_active_neigh_counter() return false; } - mle_class_get_entry_by_mac64(0,0,mac64_1, true); + mle_class_get_entry_by_mac64(0,0,mac64_1, true, NULL); if (1 != mle_class_active_neigh_counter(0)) { return false; } - mle_class_get_entry_by_mac64(0,0,mac64_2, true); + mle_class_get_entry_by_mac64(0,0,mac64_2, true, NULL); if (2 != mle_class_active_neigh_counter(0)) { return false; } @@ -709,7 +722,7 @@ bool test_mle_refresh_entry_timeout() if (mle_refresh_entry_timeout(0, mac64_1, ADDR_802_15_4_LONG, false) ) { return false; } - mle_neigh_table_entry_t * entry1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true); + mle_neigh_table_entry_t * entry1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true, NULL); if (!mle_refresh_entry_timeout(0, mac64_1, ADDR_802_15_4_LONG, false) ) { return false; @@ -804,7 +817,7 @@ bool test_mle_event_handler() mle_class_mode_set(0, MLE_CLASS_ROUTER); - mle_neigh_table_entry_t * entry1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true); + mle_neigh_table_entry_t * entry1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true, NULL); entry1->timeout_rx = 6; entry1->ttl = 6; @@ -841,13 +854,13 @@ bool test_mle_event_handler() if (!tester2_remove_ok) { return false; } - if (mle_class_get_entry_by_mac64(0,0,mac64_1, false)) { + if (mle_class_get_entry_by_mac64(0,0,mac64_1, false, NULL)) { return false; } mle_class_mode_set(0, MLE_CLASS_END_DEVICE); - entry1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true); + entry1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true, NULL); entry1->ttl = 5; entry1->priorityFlag = true; @@ -884,11 +897,11 @@ bool test_mle_event_handler() eventOS_event_send(&event); - if (mle_class_get_entry_by_mac64(0,0,mac64_1, false)) { + if (mle_class_get_entry_by_mac64(0,0,mac64_1, false, NULL)) { return false; } - entry1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true); + entry1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true, NULL); entry1->ttl = 3; entry1->priorityFlag = false; @@ -898,13 +911,13 @@ bool test_mle_event_handler() } entry1->ttl = 1; eventOS_event_send(&event); - if (mle_class_get_entry_by_mac64(0,0,mac64_1, false)) { + if (mle_class_get_entry_by_mac64(0,0,mac64_1, false, NULL)) { return false; } mle_class_mode_set(0, MLE_CLASS_SLEEPY_END_DEVICE); - entry1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true); + entry1 = mle_class_get_entry_by_mac64(0,0,mac64_1, true, NULL); entry1->ttl = 5; entry1->priorityFlag = true; @@ -921,7 +934,7 @@ bool test_mle_event_handler() if (!tester2_remove_ok) { return false; } - if (mle_class_get_entry_by_mac64(0,0,mac64_1, false)) { + if (mle_class_get_entry_by_mac64(0,0,mac64_1, false, NULL)) { return false; } @@ -1026,6 +1039,7 @@ bool test_mle_class_list_clean() uint8_t mac64_1[8]; memset(mac64_1, 0, 8); mac64_1[7] = 1; + bool new_entry; if (-1 != mle_class_list_clean(0)) { return false; @@ -1040,8 +1054,12 @@ bool test_mle_class_list_clean() return false; } - mle_class_get_entry_by_mac64(0,0,mac64_1, true); - if (!mle_class_get_entry_by_mac64(0,0,mac64_1, false)) { + mle_class_get_entry_by_mac64(0,0,mac64_1, true, &new_entry); + if (!new_entry) { + return false; + } + + if (!mle_class_get_entry_by_mac64(0,0,mac64_1, false, NULL)) { return false; } @@ -1049,7 +1067,11 @@ bool test_mle_class_list_clean() return false; } - if (mle_class_get_entry_by_mac64(0,0,mac64_1, false)) { + if (mle_class_get_entry_by_mac64(0,0,mac64_1, false, &new_entry)) { + return false; + } + + if (new_entry) { return false; } diff --git a/test/nanostack/unittest/stub/mac_helper_stub.c b/test/nanostack/unittest/stub/mac_helper_stub.c index d47ae1b7af58..649425bf475d 100644 --- a/test/nanostack/unittest/stub/mac_helper_stub.c +++ b/test/nanostack/unittest/stub/mac_helper_stub.c @@ -244,7 +244,7 @@ void mac_helper_devicetable_remove(struct mac_api_s *mac_api, uint8_t attribute_ } -void mac_helper_devicetable_set(mle_neigh_table_entry_t *entry_temp, protocol_interface_info_entry_t *cur, uint32_t frame_counter, uint8_t keyID) +void mac_helper_devicetable_set(mle_neigh_table_entry_t *entry_temp, protocol_interface_info_entry_t *cur, uint32_t frame_counter, uint8_t keyID, bool force_set) { } diff --git a/test/nanostack/unittest/stub/mle_stub.c b/test/nanostack/unittest/stub/mle_stub.c index ee5d145ccc61..a9dc91f1c7d2 100644 --- a/test/nanostack/unittest/stub/mle_stub.c +++ b/test/nanostack/unittest/stub/mle_stub.c @@ -289,7 +289,7 @@ uint8_t *mle_general_write_source_address(uint8_t *ptr, protocol_interface_info_ return 0; } -mle_neigh_table_entry_t *mle_class_get_entry_by_mac64(int8_t interface_id, uint8_t linkMargin, const uint8_t *mac64, bool allocateNew) +mle_neigh_table_entry_t *mle_class_get_entry_by_mac64(int8_t interface_id, uint8_t linkMargin, const uint8_t *mac64, bool allocateNew, bool *new_entry_allocated) { return mle_stub.mle_neigh_table_entry_ptr; } @@ -313,7 +313,7 @@ int16_t mle_class_free_entry_count_get(int8_t interface_id) { return 0; } -mle_neigh_table_entry_t *mle_class_get_entry_by_ll64(int8_t interface_id, uint8_t linkMargin, const uint8_t *ipv6Address, bool allocateNew) +mle_neigh_table_entry_t *mle_class_get_entry_by_ll64(int8_t interface_id, uint8_t linkMargin, const uint8_t *ipv6Address, bool allocateNew, bool *new_entry_created) { return mle_stub.mle_neigh_table_entry_ptr; } From f8a39da944f7e44d61bee0d902586196280b10c1 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Thu, 8 Mar 2018 12:48:04 +0200 Subject: [PATCH 16/52] documentation fix: (#1608) added missing parameter --- nanostack/net_interface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/nanostack/net_interface.h b/nanostack/net_interface.h index e4b07583a042..ac3a48c4c661 100644 --- a/nanostack/net_interface.h +++ b/nanostack/net_interface.h @@ -995,6 +995,7 @@ extern void net_get_version_information(uint8_t *ptr); * * Note! In Thread mode parent buffer size is automatically set during Thread initialization. * + * \param interface_id Network interface ID. * \param big_packet_threshold Indicate how long packets are considered big. For Thread, must be 106 bytes. * \param small_packets_per_child_count Number of small packets stored for each sleepy children. For Thread, must be at least 1. * \param big_packets_total_count Total number of big packets parent can store for all sleepy children. For Thread, must be at least 1. From a5c67fd7b52f5f5473ed9a3f6546290124268873 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Mon, 12 Mar 2018 13:13:29 +0200 Subject: [PATCH 17/52] data request resent if leader after resync does not receive data response.(#1614) --- source/6LoWPAN/Thread/thread_bootstrap.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index 05a158985c52..66b4a5549823 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -1660,6 +1660,11 @@ bool thread_network_data_timeout(int8_t interface_id, uint16_t msgId, bool usedA return true; } + if(cur->thread_info->leader_synced && !usedAllRetries){ + tr_debug("retrying as leader data not yet synced"); + return true; + } + thread_info(cur)->networkDataRequested = false; mac_data_poll_protocol_poll_mode_decrement(cur); return false; From 15846ed6f28af2a6743977a6b9d3c2a3a257ed66 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Mon, 12 Mar 2018 15:51:01 +0200 Subject: [PATCH 18/52] refactored network data sync as leader (#1615) added reattach logic for REED when it fails to get data response. --- source/6LoWPAN/Thread/thread_bootstrap.c | 18 +++++++++++++++--- .../unittest/stub/thread_leader_service_stub.c | 3 +++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index 66b4a5549823..c8277df41218 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -1660,9 +1660,21 @@ bool thread_network_data_timeout(int8_t interface_id, uint16_t msgId, bool usedA return true; } - if(cur->thread_info->leader_synced && !usedAllRetries){ - tr_debug("retrying as leader data not yet synced"); - return true; + if(cur->thread_info->leader_synced) { + if(usedAllRetries) { + // could not learn network data from neighbour, everyone must reregister + cur->thread_info->leader_synced = false; + thread_leader_service_network_data_changed(cur,true,true); + return false; + } else { + tr_debug("retrying as leader data not yet synced"); + return true; + } + } + + // if REED fails to get updated network data, it reattaches + if (thread_info(cur)->networkDataRequested && !thread_attach_active_router(cur) && usedAllRetries) { + thread_bootstrap_reset_restart(interface_id); } thread_info(cur)->networkDataRequested = false; diff --git a/test/nanostack/unittest/stub/thread_leader_service_stub.c b/test/nanostack/unittest/stub/thread_leader_service_stub.c index 0bb91244553b..6735a6765a91 100644 --- a/test/nanostack/unittest/stub/thread_leader_service_stub.c +++ b/test/nanostack/unittest/stub/thread_leader_service_stub.c @@ -80,3 +80,6 @@ uint16_t thread_leader_service_child_id_from_networkdata_get(struct thread_info_ void thread_leader_service_thread_partitition_generate(int8_t interface_id, bool newPartition) { } +void thread_leader_service_network_data_changed(protocol_interface_info_entry_t *cur, bool force_stable_update, bool force_unstable_update) +{ +} From cfb1e81fcc695a2d9bd336913f1d3b5b46413f3f Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Wed, 14 Mar 2018 11:32:35 +0200 Subject: [PATCH 19/52] Thread tx failure handling update (#1620) When TX failure threshold is reached Thread cleaup is called, device information still remains in MLE layer causing routing problems later. Update Thread TX failure handler to clean entry information from MLE layer. MLE cleanup will trigger cleaning from MAC and Thread layers. --- source/6LoWPAN/Thread/thread_common.c | 2 +- source/6LoWPAN/Thread/thread_routing.c | 3 ++- source/6LoWPAN/adaptation_interface.c | 6 ++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_common.c b/source/6LoWPAN/Thread/thread_common.c index 936bef63058b..29b350f19f89 100644 --- a/source/6LoWPAN/Thread/thread_common.c +++ b/source/6LoWPAN/Thread/thread_common.c @@ -1838,7 +1838,7 @@ static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failure } if (accumulated_failures >= THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) { - thread_reset_neighbour_info(cur, neighbor); + mle_class_remove_entry(cur->id, neighbor); } } diff --git a/source/6LoWPAN/Thread/thread_routing.c b/source/6LoWPAN/Thread/thread_routing.c index 1f8455e7a2b8..8fdf01da7b66 100644 --- a/source/6LoWPAN/Thread/thread_routing.c +++ b/source/6LoWPAN/Thread/thread_routing.c @@ -768,6 +768,8 @@ static void delete_link(thread_info_t *thread, thread_router_link_t *link) thread_router_id_t id = link->router_id; thread_routing_info_t *routing = &thread->routing; + tr_debug("delete_link: router: %x", thread_router_addr_from_id(link->router_id)); + /* Remove entry from the link set */ ns_list_remove(&routing->link_set, link); ns_dyn_mem_free(link); @@ -779,7 +781,6 @@ static void delete_link(thread_info_t *thread, thread_router_link_t *link) ns_dyn_mem_free(route_entry); } } - thread_update_fast_route_table(thread); } diff --git a/source/6LoWPAN/adaptation_interface.c b/source/6LoWPAN/adaptation_interface.c index 3cb43a30a227..230a21893c06 100644 --- a/source/6LoWPAN/adaptation_interface.c +++ b/source/6LoWPAN/adaptation_interface.c @@ -1014,6 +1014,12 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c case MLME_TRANSACTION_EXPIRED: default: tr_error("MCPS Data fail by status %u", confirm->status); + if (buf->dst_sa.addr_type == ADDR_802_15_4_SHORT) { + tr_info("Dest addr: %x", common_read_16_bit(buf->dst_sa.address+2)); + } else if (buf->dst_sa.addr_type == ADDR_802_15_4_LONG) { + tr_info("Dest addr: %s", trace_array(buf->dst_sa.address+2, 8)); + } + #ifdef HAVE_RPL if (confirm->status == MLME_TX_NO_ACK) { if (buf->route && rpl_data_is_rpl_parent_route(buf->route->route_info.source)) { From ffb47a29ad1835c8040e5b5c079eddbd2c75706f Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Thu, 15 Mar 2018 13:13:15 +0200 Subject: [PATCH 20/52] additional reed advertisement (#1609) reed advertisement sent when an advertisement from lower partition is heard. --- source/6LoWPAN/Thread/thread_common.h | 1 + source/6LoWPAN/Thread/thread_constants.h | 4 +++ .../Thread/thread_mle_message_handler.c | 34 +++++++++++++------ .../6LoWPAN/Thread/thread_router_bootstrap.c | 16 +++++++++ .../6LoWPAN/Thread/thread_router_bootstrap.h | 2 ++ 5 files changed, 46 insertions(+), 11 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_common.h b/source/6LoWPAN/Thread/thread_common.h index 8a70e5661bd5..74214ca9ace3 100644 --- a/source/6LoWPAN/Thread/thread_common.h +++ b/source/6LoWPAN/Thread/thread_common.h @@ -286,6 +286,7 @@ typedef struct thread_info_s { uint16_t native_commissioner_port; uint16_t routerShortAddress; uint16_t reedJitterTimer; + uint16_t reedMergeAdvTimer; uint16_t routerIdReqCoapID; // COAP msg id of RouterID request int16_t childUpdateReqTimer; uint16_t childUpdateReqMsgId; diff --git a/source/6LoWPAN/Thread/thread_constants.h b/source/6LoWPAN/Thread/thread_constants.h index a854791ffa7d..71119051a641 100644 --- a/source/6LoWPAN/Thread/thread_constants.h +++ b/source/6LoWPAN/Thread/thread_constants.h @@ -174,6 +174,10 @@ #define MIN_DOWNGRADE_NEIGHBORS 7 #define THREAD_REED_ADVERTISEMENT_DELAY 5000 +// Interval after which REED can send an advertisement to help others merge to higher partition. +// This is not related to default REED advertisements. +#define THREAD_REED_MERGE_ADVERTISEMENT_INTERVAL 120 + /** Default Threshold for router Selection */ #define ROUTER_DOWNGRADE_THRESHOLD 23 // Define downGrade Threshold when active router is higher than this #define ROUTER_UPGRADE_THRESHOLD 16 // Define upgrade Threshold fort REED when Active Router Count is smaller than this upgrade is possible diff --git a/source/6LoWPAN/Thread/thread_mle_message_handler.c b/source/6LoWPAN/Thread/thread_mle_message_handler.c index b68592de8bb1..6dd9a25aa7ea 100644 --- a/source/6LoWPAN/Thread/thread_mle_message_handler.c +++ b/source/6LoWPAN/Thread/thread_mle_message_handler.c @@ -239,22 +239,30 @@ static bool thread_router_leader_data_process(protocol_interface_info_entry_t *c return true; } +static bool thread_heard_lower_partition(protocol_interface_info_entry_t *cur, thread_leader_data_t heard_partition_leader_data) +{ + if (heard_partition_leader_data.weighting < thread_info(cur)->thread_leader_data->weighting) { + return true; + } + if (heard_partition_leader_data.weighting == thread_info(cur)->thread_leader_data->weighting && + heard_partition_leader_data.partitionId < thread_info(cur)->thread_leader_data->partitionId) { + return true; + } + return false; +} + static bool thread_reed_partitions_merge(protocol_interface_info_entry_t *cur, uint16_t shortAddress, thread_leader_data_t heard_partition_leader_data) { if (thread_is_router_addr(shortAddress)) { return false; } - if (thread_extension_version_check(thread_info(cur)->version)) { - // lower weighting heard - if (thread_info(cur)->thread_leader_data->weighting > heard_partition_leader_data.weighting) { - return false; - } - // lower/same partition id heard - if (thread_info(cur)->thread_leader_data->weighting == heard_partition_leader_data.weighting && - thread_info(cur)->thread_leader_data->partitionId >= heard_partition_leader_data.partitionId ) { - return false; - } - } else if (thread_info(cur)->thread_leader_data->partitionId >= heard_partition_leader_data.partitionId){ + // lower weighting heard + if (thread_info(cur)->thread_leader_data->weighting > heard_partition_leader_data.weighting) { + return false; + } + // lower/same partition id heard + if (thread_info(cur)->thread_leader_data->weighting == heard_partition_leader_data.weighting && + thread_info(cur)->thread_leader_data->partitionId >= heard_partition_leader_data.partitionId ) { return false; } // can merge to a higher weighting/partition id @@ -385,6 +393,10 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle if (thread_reed_partitions_merge(cur, shortAddress, leaderData)) { return; } + // REED advertisement to lower partition to help merge faster + if (thread_heard_lower_partition(cur,leaderData)) { + thread_router_bootstrap_reed_merge_advertisement(cur); + } } else { //Router if (!thread_router_leader_data_process(cur, mle_msg->packet_src_address, &leaderData, &routeTlv, entry_temp) ) { diff --git a/source/6LoWPAN/Thread/thread_router_bootstrap.c b/source/6LoWPAN/Thread/thread_router_bootstrap.c index 0bcb7c4ad19c..d02f6dbdcc7c 100644 --- a/source/6LoWPAN/Thread/thread_router_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_router_bootstrap.c @@ -2368,6 +2368,16 @@ void thread_router_bootstrap_reed_advertisements_start(protocol_interface_info_e cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = eventOS_timeout_ms(thread_reed_advertisements_cb,timeout, cur); } +void thread_router_bootstrap_reed_merge_advertisement(protocol_interface_info_entry_t *cur) +{ + if (cur->thread_info->reedMergeAdvTimer > 1) { + return; + } + thread_reed_advertise(cur); + // 120s second timer reinitialised before next merge advertisement + cur->thread_info->reedMergeAdvTimer = THREAD_REED_MERGE_ADVERTISEMENT_INTERVAL; + +} void thread_router_bootstrap_router_id_release(protocol_interface_info_entry_t *cur) { tr_debug("Router ID Release"); @@ -2417,6 +2427,12 @@ void thread_router_bootstrap_timer(protocol_interface_info_entry_t *cur, uint32_ } } + if (cur->thread_info->reedMergeAdvTimer > ticks) { + cur->thread_info->reedMergeAdvTimer -= ticks; + } else { + cur->thread_info->reedMergeAdvTimer = 0; + } + if (!thread_info->leader_private_data && thread_info->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) { // Non leader router checks if (thread_info->routing.activated) { diff --git a/source/6LoWPAN/Thread/thread_router_bootstrap.h b/source/6LoWPAN/Thread/thread_router_bootstrap.h index 823655879d45..faf2f7db0d6b 100644 --- a/source/6LoWPAN/Thread/thread_router_bootstrap.h +++ b/source/6LoWPAN/Thread/thread_router_bootstrap.h @@ -45,6 +45,7 @@ struct mle_security_header; struct buffer; void thread_router_bootstrap_reed_advertisements_start(protocol_interface_info_entry_t *cur); +void thread_router_bootstrap_reed_merge_advertisement(protocol_interface_info_entry_t *cur); int thread_router_bootstrap_mle_advertise(struct protocol_interface_info_entry *cur); void thread_router_bootstrap_child_information_clear(protocol_interface_info_entry_t *cur); @@ -101,6 +102,7 @@ void thread_router_bootstrap_address_change_notify_send(protocol_interface_info_ #define thread_router_bootstrap_network_data_distribute(cur) #define thread_router_bootstrap_routing_allowed(cur) false #define thread_router_bootstrap_address_change_notify_send(cur) +#define thread_router_bootstrap_reed_merge_advertisement(cur) #endif/*HAVE_THREAD_ROUTER*/ From 4022ad97baadb1b9ceee8fd52d4f51628996dddb Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Mon, 19 Mar 2018 14:11:04 +0200 Subject: [PATCH 21/52] Add new test API for clearing Thread stack values (#1624) Reset Thread cached values: -link configuration --- nanostack/net_thread_test.h | 13 +++++++++++++ source/6LoWPAN/Thread/thread_test_api.c | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/nanostack/net_thread_test.h b/nanostack/net_thread_test.h index 1751be8ad778..648fb79a3d7c 100644 --- a/nanostack/net_thread_test.h +++ b/nanostack/net_thread_test.h @@ -274,6 +274,19 @@ int thread_test_increment_key_sequence_counter(int8_t interface_id); */ int thread_test_key_sequence_counter_update(int8_t interface_id, uint32_t thrKeySequenceCounter); +/** + * \brief Resets cached values from stack + * + Resets link configuration from cache and from NVM. + * + * + * \param interface_id Network Interface + * + * \return 0, OK + * \return <0 Error + */ +int thread_test_stack_cache_reset(int8_t interface_id); + /** * \brief Set new Thread key rotation value * diff --git a/source/6LoWPAN/Thread/thread_test_api.c b/source/6LoWPAN/Thread/thread_test_api.c index be81d1736c85..c6504beee849 100644 --- a/source/6LoWPAN/Thread/thread_test_api.c +++ b/source/6LoWPAN/Thread/thread_test_api.c @@ -47,6 +47,7 @@ #include "6LoWPAN/Thread/thread_bootstrap.h" #include "6LoWPAN/Thread/thread_router_bootstrap.h" #include "6LoWPAN/Thread/thread_discovery.h" +#include "6LoWPAN/Thread/thread_nvm_store.h" #include "6LoWPAN/Thread/thread_extension_bootstrap.h" #include "MLE/mle.h" #include "thread_meshcop_lib.h" @@ -413,6 +414,27 @@ int thread_test_key_sequence_counter_update(int8_t interface_id, uint32_t thrKey #endif } +int thread_test_stack_cache_reset(int8_t interface_id) +{ +#ifdef HAVE_THREAD + protocol_interface_info_entry_t *cur; + + cur = protocol_stack_interface_info_get_by_id(interface_id); + if (!cur) { + tr_warn("Invalid interface id"); + return -1; + } + + // Reset link information + (void) thread_nvm_store_link_info_clear(); + + return 0; +#else + (void)interface_id; + return -1; +#endif +} + int thread_test_key_rotation_update(int8_t interface_id, uint32_t thrKeyRotation) { #ifdef HAVE_THREAD From 1b7fdc0d8d795b29db57cabb72f2f912f3bf5e4a Mon Sep 17 00:00:00 2001 From: Tero Heinonen Date: Thu, 22 Mar 2018 08:38:56 +0200 Subject: [PATCH 22/52] Skip discovery request if MLE table is full (#1625) If MLE table is full, router must not respond to discovery request. --- source/6LoWPAN/Thread/thread_discovery.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/6LoWPAN/Thread/thread_discovery.c b/source/6LoWPAN/Thread/thread_discovery.c index ab552ccd17e7..b9e484f341a4 100644 --- a/source/6LoWPAN/Thread/thread_discovery.c +++ b/source/6LoWPAN/Thread/thread_discovery.c @@ -817,6 +817,12 @@ static void thread_discovery_request_msg_handler(thread_discovery_class_t * disc } tr_debug("Thread discovery request message RX"); + // Check if we have room for new neighbor + if (mle_class_free_entry_count_get(discovery_class->interface_id) < 1) { + tr_debug("MLE table full, skip request"); + return; + } + //validate message mle_tlv_info_t discovery_tlv; //Parse Message From f5530b15d73e583e384a1c3849df6f4a253bb202 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Tue, 27 Mar 2018 09:39:09 +0300 Subject: [PATCH 23/52] Thread key ID change during attach (#1627) Child ID response saves link layer frame counters that were learned when parent response was received. If key ID is changed between parent response and child id response then link layer frame counter should be cleared. --- source/6LoWPAN/Thread/thread_host_bootstrap.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index e9a2ddc0faee..3b5b16e6c95e 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -832,6 +832,13 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress); mle_entry_timeout_update(entry_temp, thread_info(cur)->host_link_timeout); + + if (scan_result->security_key_index != security_headers->KeyIndex) { + // KeyIndex has been changed between parent_response and child_id_response, reset link layer frame counter + scan_result->linLayerFrameCounter = 0; + scan_result->security_key_index = security_headers->KeyIndex; + } + mac_helper_devicetable_set(entry_temp, cur, scan_result->linLayerFrameCounter, security_headers->KeyIndex, new_entry_created); thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED; From 3e8b4ce41d2af1f2b2166751d457481cef432cb1 Mon Sep 17 00:00:00 2001 From: Tero Heinonen Date: Wed, 28 Mar 2018 11:56:19 +0300 Subject: [PATCH 24/52] Multicast registration time fix (#1631) Fix for multicast registration timeouts. --- source/6LoWPAN/Thread/thread_constants.h | 2 +- source/6LoWPAN/Thread/thread_extension.c | 15 ++++++++++----- source/6LoWPAN/Thread/thread_extension_bbr.c | 12 +++++++----- .../6LoWPAN/Thread/thread_extension_constants.h | 5 +++++ 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_constants.h b/source/6LoWPAN/Thread/thread_constants.h index 71119051a641..602f0dcf9103 100644 --- a/source/6LoWPAN/Thread/thread_constants.h +++ b/source/6LoWPAN/Thread/thread_constants.h @@ -164,7 +164,7 @@ #define THREAD_ENTERPRISE_NUMBER 44970 -#define THREAD_ADDR_REG_TIMEOUT_BASE 300 +#define THREAD_ADDR_REG_RETRY_INTERVAL 300 #define THREAD_PROACTIVE_AN_INTERVAL 3600 // Router defines diff --git a/source/6LoWPAN/Thread/thread_extension.c b/source/6LoWPAN/Thread/thread_extension.c index 892e071c9a83..dd734aeb7d9b 100644 --- a/source/6LoWPAN/Thread/thread_extension.c +++ b/source/6LoWPAN/Thread/thread_extension.c @@ -271,6 +271,9 @@ int thread_extension_primary_bbr_get(struct protocol_interface_info_entry *cur, } if (mlr_timer_ptr) { *mlr_timer_ptr = common_read_32_bit(&found_tlv[7]); + if (*mlr_timer_ptr < THREAD_DEFAULT_MIN_MLR_TIMEOUT) { + *mlr_timer_ptr = THREAD_DEFAULT_MIN_MLR_TIMEOUT; + } } return 0; } @@ -496,14 +499,16 @@ void thread_extension_mcast_subscrition_change(protocol_interface_info_entry_t * if (addr_ipv6_multicast_scope(group->group) < IPV6_SCOPE_ADMIN_LOCAL) { return; } - // Default timer added. - group->mld_timer = added ? THREAD_ADDR_REG_TIMEOUT_BASE + randLIB_get_random_in_range(1, 30) : 0; - if (0 !=thread_extension_primary_bbr_get(interface, br_ml_addr, NULL, &mlr_timer, NULL )) { + if (0 != thread_extension_primary_bbr_get(interface, br_ml_addr, NULL, &mlr_timer, NULL )) { + // No BBR, try again later if adding address. + group->mld_timer = added ? THREAD_ADDR_REG_RETRY_INTERVAL + randLIB_get_random_in_range(1, 30) : 0; return; } - // follow the Primary BBR set timeout + Small jitter added - group->mld_timer = added ? mlr_timer: 0; + + // follow the Primary BBR set timeout. + group->mld_timer = added ? (mlr_timer - randLIB_get_random_in_range(30, 40)) : 0; + // MLR is sent only for primary BBR for now, but this might change thread_extension_mlr_req_send(interface, br_ml_addr, group->group); diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.c b/source/6LoWPAN/Thread/thread_extension_bbr.c index e9fd69adf534..a2f402d07848 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.c +++ b/source/6LoWPAN/Thread/thread_extension_bbr.c @@ -98,11 +98,10 @@ typedef struct { static NS_LIST_DEFINE(pbbr_instance_list, thread_pbbr_t, link); static NS_LIST_DEFINE(duplicate_dua_tr_list, duplicate_dua_tr_t, link); - -#define THREAD_BBR_MLR_REGISTRATION_TIMEOUT 120 +#define THREAD_BBR_MLR_REGISTRATION_TIMEOUT 600 //<* Default MLR timeout in seconds #define THREAD_BBR_DUA_REGISTRATION_TIMEOUT 3600 -#define THREAD_BBR_DUA_REGISTRATION_DELAY 5000 // 5 seconds in ms -#define THREAD_BBR_BACKBONE_PORT 5683 //<* Backbone border router +#define THREAD_BBR_DUA_REGISTRATION_DELAY 5000 // 5 seconds in ms +#define THREAD_BBR_BACKBONE_PORT 5683 //<* Backbone border router /* 0 – Successful registration @@ -608,8 +607,9 @@ static int thread_extension_bbr_mlr_cb(int8_t service_id, uint8_t source_address bbr_status = THREAD_BBR_STATUS_NOT_PRIMARY_BBR; goto send_response; } + + //check if commissioner if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) { - //check if commissioner // Session id present must be valid tr_info("message from commissioner"); 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 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; goto send_response; } + int16_t remaining = addr_len; uint8_t *addr_ptr = addr_data_ptr; + while (remaining > 0) { //Go through all addresses if (timeout_value == 0) { diff --git a/source/6LoWPAN/Thread/thread_extension_constants.h b/source/6LoWPAN/Thread/thread_extension_constants.h index ba73134d7b92..b9af705957db 100644 --- a/source/6LoWPAN/Thread/thread_extension_constants.h +++ b/source/6LoWPAN/Thread/thread_extension_constants.h @@ -38,6 +38,11 @@ typedef struct discovery_additional_info { bool ccm_supported:1; }discovery_additional_info_t; +/** + * Minimum specified MLR timeout in seconds + */ +#define THREAD_DEFAULT_MIN_MLR_TIMEOUT 300 + /** * Default Autonomous enrollment port. */ From 2378dad5398e5c49ae3993b123c359020b44fd18 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Wed, 28 Mar 2018 12:10:30 +0300 Subject: [PATCH 25/52] Discard late Child ID responses (#1630) Child ID response can be accepted only from neighbor that was selected as parent in the latest parent scan. A device needs to discard child ID responses from old parents that are responding late. Old rloc can be released from network data when new rloc is received. --- source/6LoWPAN/Thread/thread_host_bootstrap.c | 12 +++++++++++- source/6LoWPAN/Thread/thread_network_data_storage.h | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index 3b5b16e6c95e..b6f8e0344de2 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -752,6 +752,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message switch (mle_msg->message_type) { case MLE_COMMAND_CHILD_ID_RESPONSE: { + uint8_t src_mac64[8]; uint8_t shortAddress[2]; uint16_t childId; mle_tlv_info_t routeTlv, addressRegisteredTlv, networkDataTlv; @@ -763,12 +764,21 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message tr_info("Received Child ID Response"); + // Validate that response is coming from the scanned parent candidate + memcpy(src_mac64, (mle_msg->packet_src_address + 8), 8); + src_mac64[0] ^= 2; + if (memcmp(src_mac64, scan_result->mac64, 8) != 0) { + tr_debug("Drop Child ID response from previous request"); + return; + } + // Clear old data if (cur->thread_info->releaseRouterId) { thread_bootstrap_clear_neighbor_entries(cur); - cur->thread_info->localServerDataBase.release_old_address = true; } + cur->thread_info->localServerDataBase.release_old_address = true; + thread_clean_all_routers_from_neighbor_list(cur->id); thread_leader_service_stop(interface_id); thread_leader_service_leader_data_free(cur->thread_info); diff --git a/source/6LoWPAN/Thread/thread_network_data_storage.h b/source/6LoWPAN/Thread/thread_network_data_storage.h index a4d2bf017631..33671a74cf36 100644 --- a/source/6LoWPAN/Thread/thread_network_data_storage.h +++ b/source/6LoWPAN/Thread/thread_network_data_storage.h @@ -184,7 +184,7 @@ typedef struct thread_network_local_data_cache_entry_s { thread_network_data_prefix_list_t prefix_list; /*!< Local parsed or generated service list */ thread_network_data_service_list_t service_list; uint16_t registered_rloc16;/*!< Address used for latest registration */ - bool release_old_address:1;/*!< true if release of old address is needed */ + bool release_old_address:1;/*!< true if network data can be released from old address */ bool publish_active:1;/*!< true when publish is active */ bool publish_pending:1;/*!< true when publish attempt made during active publish */ } thread_network_local_data_cache_entry_t; From 0d655ed6037ecc34582bfb698e223f6149e20258 Mon Sep 17 00:00:00 2001 From: Tero Heinonen Date: Wed, 28 Mar 2018 17:09:02 +0300 Subject: [PATCH 26/52] Update MLE receiver in Child ID req timeout error (#1634) When Child ID request times out and there is no route to leader, attaching is restarted. MLE receiver handler must be updated to avoid released thread_attach_scanned_parent pointer usage if Child ID response is received after this. --- source/6LoWPAN/Thread/thread_host_bootstrap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index b6f8e0344de2..83cc9ccc5dc7 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -1037,9 +1037,10 @@ static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, boo cur->thread_info->releaseRouterId = false; cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; - mle_service_interface_receiver_handler_update(cur->id, thread_general_mle_receive_cb); exit: + mle_service_interface_receiver_handler_update(cur->id, thread_general_mle_receive_cb); + ns_dyn_mem_free(cur->thread_info->thread_attach_scanned_parent); cur->thread_info->thread_attach_scanned_parent = NULL; From 32cfb6b4c8a38cd4959e0ff5ea1ba8f97c26919c Mon Sep 17 00:00:00 2001 From: katariinaliehu Date: Tue, 3 Apr 2018 10:41:23 +0300 Subject: [PATCH 27/52] Fix to partition selection rules (#1633) Fix the partition selection rule for the weight to enable merging when the heard partition weight is higher. --- source/6LoWPAN/Thread/thread_bootstrap.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index c8277df41218..3ad18e4d579a 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -333,9 +333,14 @@ int thread_bootstrap_partition_process(protocol_interface_info_entry_t *cur, uin /*Rule 0: If we are going to form Higher partition than heard we dont try to attach to lower ones */ if (thread_extension_enabled(cur) && - thread_info(cur)->thread_device_mode == THREAD_DEVICE_MODE_ROUTER && - heard_partition_leader_data->weighting < thread_info(cur)->partition_weighting) { - return -2; + thread_info(cur)->thread_device_mode == THREAD_DEVICE_MODE_ROUTER) { + if (heard_partition_leader_data->weighting < thread_info(cur)->partition_weighting) { + tr_debug("Heard a lower weight partition"); + return -2; + } + if (heard_partition_leader_data->weighting > thread_info(cur)->partition_weighting) { + return 2; + } } //Rule 1: A non-singleton Thread Network Partition always has higher priority than a singleton Thread Network Partition From a20a0bad5eae648ef5dda60ddac31bd5021ec40e Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Thu, 5 Apr 2018 11:13:53 +0300 Subject: [PATCH 28/52] Update Thread MLE neighbor list cleanup (#1637) -Device needs to clean MLE neighbors (routers and their children) when moving to new partition. Own children can be moved to new partition. -Device is not allowed to update MLE cache based on advertisements from other partition. MLE entries belonging to other partition can be removed from MLE table. -Update traces --- source/6LoWPAN/Thread/thread_bootstrap.c | 16 ++++++++-------- source/6LoWPAN/Thread/thread_bootstrap.h | 2 +- source/6LoWPAN/Thread/thread_common.c | 6 +++--- source/6LoWPAN/Thread/thread_host_bootstrap.c | 12 ++++++------ source/6LoWPAN/Thread/thread_leader_service.c | 2 +- .../6LoWPAN/Thread/thread_mle_message_handler.c | 8 +++++++- source/6LoWPAN/Thread/thread_router_bootstrap.c | 11 ++++++----- .../unittest/stub/thread_bootstrap_stub.c | 2 +- 8 files changed, 33 insertions(+), 26 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index 3ad18e4d579a..cfe6b3434e6e 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -1159,14 +1159,14 @@ void thread_bootstrap_ready(protocol_interface_info_entry_t *cur) mac_data_poll_protocol_poll_mode_decrement(cur); } -void thread_clean_all_routers_from_neighbor_list(int8_t interface_id) -{ - mle_neigh_table_list_t *neig_list = mle_class_active_list_get(interface_id); - /* Init Double linked Routing Table */ - ns_list_foreach_safe(mle_neigh_table_entry_t, cur, neig_list) { - if (thread_is_router_addr(cur->short_adr)) { - tr_debug("Free Router %x", cur->short_adr); - mle_class_remove_entry(interface_id, cur); +void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur) +{ + mle_neigh_table_list_t *neig_list = mle_class_active_list_get(cur->id); + + ns_list_foreach_safe(mle_neigh_table_entry_t, cur_entry, neig_list) { + if (!thread_addr_is_equal_or_child(cur->thread_info->routerShortAddress, cur_entry->short_adr)) { + tr_debug("Free ID %x", cur_entry->short_adr); + mle_class_remove_entry(cur->id, cur_entry); } } } diff --git a/source/6LoWPAN/Thread/thread_bootstrap.h b/source/6LoWPAN/Thread/thread_bootstrap.h index 09b07918521b..517321704b0e 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.h +++ b/source/6LoWPAN/Thread/thread_bootstrap.h @@ -106,7 +106,7 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, int thread_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mle_neigh_table_entry_t *child); void thread_bootstrap_ready(struct protocol_interface_info_entry *cur); int thread_bootstrap_reset(struct protocol_interface_info_entry *cur); -void thread_clean_all_routers_from_neighbor_list(int8_t interface_id); +void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur); bool thread_bootstrap_request_network_data(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, uint16_t short_address); bool thread_check_is_this_my_parent(struct protocol_interface_info_entry *cur, struct mle_neigh_table_entry_t *entry_temp); void thread_clean_old_16_bit_address_based_addresses(struct protocol_interface_info_entry *cur); diff --git a/source/6LoWPAN/Thread/thread_common.c b/source/6LoWPAN/Thread/thread_common.c index 29b350f19f89..ff61c08f1f7d 100644 --- a/source/6LoWPAN/Thread/thread_common.c +++ b/source/6LoWPAN/Thread/thread_common.c @@ -233,8 +233,8 @@ int8_t thread_bootstrap_down(protocol_interface_info_entry_t *cur) tr_debug("SET thread Idle"); //stop polling mac_data_poll_disable(cur); - //Clean routers from mle table - thread_clean_all_routers_from_neighbor_list(cur->id); + //Clean mle table + thread_neighbor_list_clean(cur); // store frame counters if (cur->thread_info) { thread_nvm_fast_data_t fast_data; @@ -1848,8 +1848,8 @@ void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent; if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->short_adr) { - tr_warn("End device lost Parent!\n"); if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) { + tr_warn("End device lost parent, reset!\n"); thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); } } diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index 83cc9ccc5dc7..ebed1f7b492d 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -393,7 +393,7 @@ static void thread_child_synch_receive_cb(int8_t interface_id, mle_message_t *ml messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } @@ -471,7 +471,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m return; } - tr_debug("Thread MLE Parent request response Handler"); + tr_debug("MLE Parent response handler"); //State machine What packet should accept in this case switch (mle_msg->message_type) { case MLE_COMMAND_PARENT_RESPONSE: { @@ -496,7 +496,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } @@ -747,7 +747,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message return; } - tr_debug("Thread MLE Child request response Handler"); + tr_debug("Thread MLE Child ID response handler"); switch (mle_msg->message_type) { @@ -762,7 +762,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message thread_scanned_parent_t *scan_result = thread_info(cur)->thread_attach_scanned_parent; bool new_entry_created; - tr_info("Received Child ID Response"); + tr_info("Recv Child ID Response"); // Validate that response is coming from the scanned parent candidate memcpy(src_mac64, (mle_msg->packet_src_address + 8), 8); @@ -779,7 +779,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message cur->thread_info->localServerDataBase.release_old_address = true; - thread_clean_all_routers_from_neighbor_list(cur->id); + thread_neighbor_list_clean(cur); thread_leader_service_stop(interface_id); thread_leader_service_leader_data_free(cur->thread_info); thread_merge_prepare(cur); diff --git a/source/6LoWPAN/Thread/thread_leader_service.c b/source/6LoWPAN/Thread/thread_leader_service.c index 4ad8f3d95d41..c72248e6dca8 100644 --- a/source/6LoWPAN/Thread/thread_leader_service.c +++ b/source/6LoWPAN/Thread/thread_leader_service.c @@ -1270,7 +1270,7 @@ static int thread_leader_service_leader_init(protocol_interface_info_entry_t *cu thread_nd_service_delete(cur->id); mpl_clear_realm_scope_seeds(cur); ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache); - thread_clean_all_routers_from_neighbor_list(cur->id); + thread_neighbor_list_clean(cur); cur->mesh_callbacks = NULL; cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; diff --git a/source/6LoWPAN/Thread/thread_mle_message_handler.c b/source/6LoWPAN/Thread/thread_mle_message_handler.c index 6dd9a25aa7ea..1b214017fb54 100644 --- a/source/6LoWPAN/Thread/thread_mle_message_handler.c +++ b/source/6LoWPAN/Thread/thread_mle_message_handler.c @@ -351,6 +351,12 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); } + if (entry_temp && !thread_instance_id_matches(cur, &leaderData)) { + // Remove MLE entries that are located in other partition + mle_class_remove_entry(cur->id, entry_temp); + entry_temp = NULL; + } + // Check parent status if (!thread_attach_active_router(cur)) { //processing for non routers @@ -428,7 +434,7 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } diff --git a/source/6LoWPAN/Thread/thread_router_bootstrap.c b/source/6LoWPAN/Thread/thread_router_bootstrap.c index d02f6dbdcc7c..1af1a8b7d6ad 100644 --- a/source/6LoWPAN/Thread/thread_router_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_router_bootstrap.c @@ -340,7 +340,7 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } /*Link accept command has an optional MLE Frame counter TLV, if this is not present use link layer frame counter TLV @@ -894,7 +894,7 @@ static int thread_attach_parent_response_build(protocol_interface_info_entry_t * if (bufId == 0) { return -1; } - tr_debug("MLE ATTACHED 2. Packet"); + tr_debug("Build MLE Parent response"); uint32_t keySequence; uint8_t *ptr = mle_service_get_data_pointer(bufId); @@ -1357,7 +1357,6 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c thread_nd_address_registration(cur, tempIPv6Address, entry_temp->short_adr, cur->mac_parameters->pan_id, entry_temp->mac64); } - tr_debug("Response Child Id Request"); mle_attach_child_id_response_build(cur,ll64,req, entry_temp); free_request: @@ -1591,7 +1590,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } @@ -1606,6 +1605,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * mle_msg->packet_src_address[8] ^= 2; if (!id_req) { + tr_debug("No room for child id req"); return; } @@ -1627,6 +1627,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * (!mle_tlv_read_32_bit_tlv(MLE_TYPE_LL_FRAME_COUNTER, mle_msg->data_ptr, mle_msg->data_length, &id_req->frameCounter)) || (!mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlvRequest))) { thread_child_id_request_entry_remove(cur, id_req); + tr_debug("Illegal child id req"); return; } //If MLE MLE_TYPE_MLE_FRAME_COUNTER TLV is present then use it for validating further messages else use link layer frame counter @@ -1827,7 +1828,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } diff --git a/test/nanostack/unittest/stub/thread_bootstrap_stub.c b/test/nanostack/unittest/stub/thread_bootstrap_stub.c index 714c2f278ab1..5f36cd0c53a1 100644 --- a/test/nanostack/unittest/stub/thread_bootstrap_stub.c +++ b/test/nanostack/unittest/stub/thread_bootstrap_stub.c @@ -257,7 +257,7 @@ int8_t thread_mle_class_init(int8_t interface_id) return 0; } -void thread_clean_all_routers_from_neighbor_list(int8_t interface_id) +void thread_neighbor_list_clean(protocol_interface_info_entry_t *cur) { } From 4f5e97dbbeac1a9cbf87fa4ea088f68ba68202d2 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Thu, 5 Apr 2018 13:52:41 +0300 Subject: [PATCH 29/52] Revert "Update Thread MLE neighbor list cleanup (#1637)" (#1639) This reverts commit a20a0bad5eae648ef5dda60ddac31bd5021ec40e. --- source/6LoWPAN/Thread/thread_bootstrap.c | 16 ++++++++-------- source/6LoWPAN/Thread/thread_bootstrap.h | 2 +- source/6LoWPAN/Thread/thread_common.c | 6 +++--- source/6LoWPAN/Thread/thread_host_bootstrap.c | 12 ++++++------ source/6LoWPAN/Thread/thread_leader_service.c | 2 +- .../6LoWPAN/Thread/thread_mle_message_handler.c | 8 +------- source/6LoWPAN/Thread/thread_router_bootstrap.c | 11 +++++------ .../unittest/stub/thread_bootstrap_stub.c | 2 +- 8 files changed, 26 insertions(+), 33 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index cfe6b3434e6e..3ad18e4d579a 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -1159,14 +1159,14 @@ void thread_bootstrap_ready(protocol_interface_info_entry_t *cur) mac_data_poll_protocol_poll_mode_decrement(cur); } -void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur) -{ - mle_neigh_table_list_t *neig_list = mle_class_active_list_get(cur->id); - - ns_list_foreach_safe(mle_neigh_table_entry_t, cur_entry, neig_list) { - if (!thread_addr_is_equal_or_child(cur->thread_info->routerShortAddress, cur_entry->short_adr)) { - tr_debug("Free ID %x", cur_entry->short_adr); - mle_class_remove_entry(cur->id, cur_entry); +void thread_clean_all_routers_from_neighbor_list(int8_t interface_id) +{ + mle_neigh_table_list_t *neig_list = mle_class_active_list_get(interface_id); + /* Init Double linked Routing Table */ + ns_list_foreach_safe(mle_neigh_table_entry_t, cur, neig_list) { + if (thread_is_router_addr(cur->short_adr)) { + tr_debug("Free Router %x", cur->short_adr); + mle_class_remove_entry(interface_id, cur); } } } diff --git a/source/6LoWPAN/Thread/thread_bootstrap.h b/source/6LoWPAN/Thread/thread_bootstrap.h index 517321704b0e..09b07918521b 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.h +++ b/source/6LoWPAN/Thread/thread_bootstrap.h @@ -106,7 +106,7 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, int thread_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mle_neigh_table_entry_t *child); void thread_bootstrap_ready(struct protocol_interface_info_entry *cur); int thread_bootstrap_reset(struct protocol_interface_info_entry *cur); -void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur); +void thread_clean_all_routers_from_neighbor_list(int8_t interface_id); bool thread_bootstrap_request_network_data(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, uint16_t short_address); bool thread_check_is_this_my_parent(struct protocol_interface_info_entry *cur, struct mle_neigh_table_entry_t *entry_temp); void thread_clean_old_16_bit_address_based_addresses(struct protocol_interface_info_entry *cur); diff --git a/source/6LoWPAN/Thread/thread_common.c b/source/6LoWPAN/Thread/thread_common.c index ff61c08f1f7d..29b350f19f89 100644 --- a/source/6LoWPAN/Thread/thread_common.c +++ b/source/6LoWPAN/Thread/thread_common.c @@ -233,8 +233,8 @@ int8_t thread_bootstrap_down(protocol_interface_info_entry_t *cur) tr_debug("SET thread Idle"); //stop polling mac_data_poll_disable(cur); - //Clean mle table - thread_neighbor_list_clean(cur); + //Clean routers from mle table + thread_clean_all_routers_from_neighbor_list(cur->id); // store frame counters if (cur->thread_info) { thread_nvm_fast_data_t fast_data; @@ -1848,8 +1848,8 @@ void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent; if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->short_adr) { + tr_warn("End device lost Parent!\n"); if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) { - tr_warn("End device lost parent, reset!\n"); thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); } } diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index ebed1f7b492d..83cc9ccc5dc7 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -393,7 +393,7 @@ static void thread_child_synch_receive_cb(int8_t interface_id, mle_message_t *ml messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("No matching challenge"); + tr_debug("Not for me"); return; } @@ -471,7 +471,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m return; } - tr_debug("MLE Parent response handler"); + tr_debug("Thread MLE Parent request response Handler"); //State machine What packet should accept in this case switch (mle_msg->message_type) { case MLE_COMMAND_PARENT_RESPONSE: { @@ -496,7 +496,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("No matching challenge"); + tr_debug("Not for me"); return; } @@ -747,7 +747,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message return; } - tr_debug("Thread MLE Child ID response handler"); + tr_debug("Thread MLE Child request response Handler"); switch (mle_msg->message_type) { @@ -762,7 +762,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message thread_scanned_parent_t *scan_result = thread_info(cur)->thread_attach_scanned_parent; bool new_entry_created; - tr_info("Recv Child ID Response"); + tr_info("Received Child ID Response"); // Validate that response is coming from the scanned parent candidate memcpy(src_mac64, (mle_msg->packet_src_address + 8), 8); @@ -779,7 +779,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message cur->thread_info->localServerDataBase.release_old_address = true; - thread_neighbor_list_clean(cur); + thread_clean_all_routers_from_neighbor_list(cur->id); thread_leader_service_stop(interface_id); thread_leader_service_leader_data_free(cur->thread_info); thread_merge_prepare(cur); diff --git a/source/6LoWPAN/Thread/thread_leader_service.c b/source/6LoWPAN/Thread/thread_leader_service.c index c72248e6dca8..4ad8f3d95d41 100644 --- a/source/6LoWPAN/Thread/thread_leader_service.c +++ b/source/6LoWPAN/Thread/thread_leader_service.c @@ -1270,7 +1270,7 @@ static int thread_leader_service_leader_init(protocol_interface_info_entry_t *cu thread_nd_service_delete(cur->id); mpl_clear_realm_scope_seeds(cur); ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache); - thread_neighbor_list_clean(cur); + thread_clean_all_routers_from_neighbor_list(cur->id); cur->mesh_callbacks = NULL; cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; diff --git a/source/6LoWPAN/Thread/thread_mle_message_handler.c b/source/6LoWPAN/Thread/thread_mle_message_handler.c index 1b214017fb54..6dd9a25aa7ea 100644 --- a/source/6LoWPAN/Thread/thread_mle_message_handler.c +++ b/source/6LoWPAN/Thread/thread_mle_message_handler.c @@ -351,12 +351,6 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); } - if (entry_temp && !thread_instance_id_matches(cur, &leaderData)) { - // Remove MLE entries that are located in other partition - mle_class_remove_entry(cur->id, entry_temp); - entry_temp = NULL; - } - // Check parent status if (!thread_attach_active_router(cur)) { //processing for non routers @@ -434,7 +428,7 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("No matching challenge"); + tr_debug("Not for me"); return; } diff --git a/source/6LoWPAN/Thread/thread_router_bootstrap.c b/source/6LoWPAN/Thread/thread_router_bootstrap.c index 1af1a8b7d6ad..d02f6dbdcc7c 100644 --- a/source/6LoWPAN/Thread/thread_router_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_router_bootstrap.c @@ -340,7 +340,7 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("No matching challenge"); + tr_debug("Not for me"); return; } /*Link accept command has an optional MLE Frame counter TLV, if this is not present use link layer frame counter TLV @@ -894,7 +894,7 @@ static int thread_attach_parent_response_build(protocol_interface_info_entry_t * if (bufId == 0) { return -1; } - tr_debug("Build MLE Parent response"); + tr_debug("MLE ATTACHED 2. Packet"); uint32_t keySequence; uint8_t *ptr = mle_service_get_data_pointer(bufId); @@ -1357,6 +1357,7 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c thread_nd_address_registration(cur, tempIPv6Address, entry_temp->short_adr, cur->mac_parameters->pan_id, entry_temp->mac64); } + tr_debug("Response Child Id Request"); mle_attach_child_id_response_build(cur,ll64,req, entry_temp); free_request: @@ -1590,7 +1591,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("No matching challenge"); + tr_debug("Not for me"); return; } @@ -1605,7 +1606,6 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * mle_msg->packet_src_address[8] ^= 2; if (!id_req) { - tr_debug("No room for child id req"); return; } @@ -1627,7 +1627,6 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * (!mle_tlv_read_32_bit_tlv(MLE_TYPE_LL_FRAME_COUNTER, mle_msg->data_ptr, mle_msg->data_length, &id_req->frameCounter)) || (!mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlvRequest))) { thread_child_id_request_entry_remove(cur, id_req); - tr_debug("Illegal child id req"); return; } //If MLE MLE_TYPE_MLE_FRAME_COUNTER TLV is present then use it for validating further messages else use link layer frame counter @@ -1828,7 +1827,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("No matching challenge"); + tr_debug("Not for me"); return; } diff --git a/test/nanostack/unittest/stub/thread_bootstrap_stub.c b/test/nanostack/unittest/stub/thread_bootstrap_stub.c index 5f36cd0c53a1..714c2f278ab1 100644 --- a/test/nanostack/unittest/stub/thread_bootstrap_stub.c +++ b/test/nanostack/unittest/stub/thread_bootstrap_stub.c @@ -257,7 +257,7 @@ int8_t thread_mle_class_init(int8_t interface_id) return 0; } -void thread_neighbor_list_clean(protocol_interface_info_entry_t *cur) +void thread_clean_all_routers_from_neighbor_list(int8_t interface_id) { } From 9c6b876266b7ff296b2df2b5ba5e3b8af29d98c3 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Thu, 5 Apr 2018 13:58:13 +0300 Subject: [PATCH 30/52] added nvm support for leader router id allocation. (#1626) nvm support for MLE-ID to router id mapping maintained by the leader. This enables the leader to reallocate router ids even after restart. --- source/6LoWPAN/Thread/thread_common.c | 1 + source/6LoWPAN/Thread/thread_common.h | 3 + source/6LoWPAN/Thread/thread_leader_service.c | 56 +++++++++++++++-- source/6LoWPAN/Thread/thread_nvm_store.c | 60 +++++++++++++++++++ source/6LoWPAN/Thread/thread_nvm_store.h | 12 ++++ .../6LoWPAN/Thread/thread_router_bootstrap.c | 2 + 6 files changed, 130 insertions(+), 4 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_common.c b/source/6LoWPAN/Thread/thread_common.c index 29b350f19f89..b3652d7b95ed 100644 --- a/source/6LoWPAN/Thread/thread_common.c +++ b/source/6LoWPAN/Thread/thread_common.c @@ -524,6 +524,7 @@ thread_leader_info_t *thread_allocate_and_init_leader_private_data(void) thread_leader_info_t *leader_info = ns_dyn_mem_alloc(sizeof(thread_leader_info_t)); if (leader_info) { leader_info->leader_id_seq_timer = ID_SEQUENCE_PERIOD; + leader_info->leader_nvm_sync_timer = 0; } return leader_info; } diff --git a/source/6LoWPAN/Thread/thread_common.h b/source/6LoWPAN/Thread/thread_common.h index 74214ca9ace3..b06b9454e442 100644 --- a/source/6LoWPAN/Thread/thread_common.h +++ b/source/6LoWPAN/Thread/thread_common.h @@ -48,6 +48,8 @@ */ #define ROUTER_ID_REUSE_DELAY 100 //Seconds +#define LEADER_NVM_SYNC_DELAY 30 // Leader router ids write delay to NVM + #define ROUTER_ID_INFINITY_DELAY 90 //Seconds #define NETWORK_ID_TIMEOUT 120 //seconds @@ -145,6 +147,7 @@ typedef struct thread_leader_info_s { uint8_t leader_id_seq_timer; uint8_t master_router_id_mask[8]; uint8_t maskSeq; + uint8_t leader_nvm_sync_timer; } thread_leader_info_t; typedef struct thread_leader_data_s { diff --git a/source/6LoWPAN/Thread/thread_leader_service.c b/source/6LoWPAN/Thread/thread_leader_service.c index 4ad8f3d95d41..02d24e859fac 100644 --- a/source/6LoWPAN/Thread/thread_leader_service.c +++ b/source/6LoWPAN/Thread/thread_leader_service.c @@ -733,6 +733,28 @@ static void thread_leader_allocate_router_id_by_allocated_id(thread_leader_info_ info->thread_router_id_list[router_id].reUsePossible = false; } +void thread_leader_mleid_rloc_map_populate(thread_nvm_mleid_rloc_map *mleid_rloc_map, thread_leader_info_t *leader_private_info) +{ + for (uint8_t i = 0; i < 64; i++) { + if (bit_test(leader_private_info->master_router_id_mask, i)) { + memcpy(mleid_rloc_map->mleid_rloc_map[i].mle_id, leader_private_info->thread_router_id_list[i].eui64, 8); + } + } +} + +static int thread_leader_update_mleid_rloc_map_in_nvm(protocol_interface_info_entry_t *cur) +{ + thread_nvm_mleid_rloc_map *mleid_rloc_map = ns_dyn_mem_temporary_alloc(sizeof(thread_nvm_mleid_rloc_map)); + if (!mleid_rloc_map) { + return -1; + } + memset(mleid_rloc_map, 0, sizeof(thread_nvm_mleid_rloc_map)); + thread_leader_mleid_rloc_map_populate(mleid_rloc_map, cur->thread_info->leader_private_data); + thread_nvm_store_mleid_rloc_map_write(mleid_rloc_map); + ns_dyn_mem_free(mleid_rloc_map); + return 0; +} + static int thread_leader_service_router_id_allocate(const uint8_t *eui64, protocol_interface_info_entry_t *cur, thread_leader_service_router_id_resp_t *reponse) { int ret_val = -1; @@ -793,6 +815,8 @@ static int thread_leader_service_router_id_allocate(const uint8_t *eui64, protoc if (!bit_test(leader_private_ptr->master_router_id_mask, id)) { if (leader_private_ptr->thread_router_id_list[id].reUsePossible) { allocated_id = id; + // new id allocated save to nvm after delay + leader_private_ptr->leader_nvm_sync_timer = LEADER_NVM_SYNC_DELAY; break; } } @@ -847,6 +871,7 @@ static int thread_leader_service_router_id_deallocate(const uint8_t *eui64, prot //Active ID if (memcmp(eui64, leader_private_ptr->thread_router_id_list[i].eui64, 8) == 0) { tr_debug("Release Router Id %d", i); + leader_private_ptr->leader_nvm_sync_timer = LEADER_NVM_SYNC_DELAY; thread_leader_service_route_mask_bit_clear(leader_private_ptr, i); leader_private_ptr->thread_router_id_list[i].reUsePossible = true; leader_private_ptr->thread_router_id_list[i].validLifeTime = 0; @@ -1318,6 +1343,8 @@ static void thread_leader_service_interface_setup_activate(protocol_interface_in //SET Router ID thread_leader_allocate_router_id_by_allocated_id(private, routerId, cur->mac); thread_old_partition_data_purge(cur); + // remove any existing rloc mapping in nvm + thread_nvm_store_mleid_rloc_map_remove(); cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS; thread_bootstrap_update_ml16_address(cur, cur->thread_info->routerShortAddress); thread_generate_ml64_address(cur); @@ -1500,6 +1527,16 @@ void thread_leader_service_timer(protocol_interface_info_entry_t *cur, uint32_t thread_leader_service_network_data_changed(cur, false, false); } + if (cur->thread_info->leader_private_data->leader_nvm_sync_timer) { + if ((cur->thread_info->leader_private_data->leader_nvm_sync_timer) > ticks) { + cur->thread_info->leader_private_data->leader_nvm_sync_timer -= ticks; + } + else { + cur->thread_info->leader_private_data->leader_nvm_sync_timer = 0; + thread_leader_update_mleid_rloc_map_in_nvm(cur); + } + } + thread_leader_service_router_id_valid_lifetime_update(cur, ticks); } @@ -1619,22 +1656,33 @@ int thread_leader_service_thread_partitition_restart(int8_t interface_id, mle_tl } //Learn network data, we remove own data from here it should be re given by application //thread_management_network_data_register(cur->id, networkData.dataPtr, networkData.tlvLen, address16 ); - + thread_nvm_mleid_rloc_map *mleid_rloc_map = ns_dyn_mem_temporary_alloc(sizeof(thread_nvm_mleid_rloc_map)); + if (!mleid_rloc_map) { + return -1; + } + if (thread_nvm_store_mleid_rloc_map_read(mleid_rloc_map) != THREAD_NVM_FILE_SUCCESS) { + memset(mleid_rloc_map, 0, sizeof(thread_nvm_mleid_rloc_map)); + } // initialize private data thread_info(cur)->leader_private_data->maskSeq = *routing->dataPtr; - memcpy(thread_info(cur)->leader_private_data->master_router_id_mask,routing->dataPtr + 1,8); + memcpy(thread_info(cur)->leader_private_data->master_router_id_mask,routing->dataPtr + 1, 8); for (int i = 0; i < 64; i++) { - memset(thread_info(cur)->leader_private_data->thread_router_id_list[i].eui64,0,8); if (bit_test(thread_info(cur)->leader_private_data->master_router_id_mask, i)) { //Active ID thread_info(cur)->leader_private_data->thread_router_id_list[i].reUsePossible = false; - + memcpy(thread_info(cur)->leader_private_data->thread_router_id_list[i].eui64, mleid_rloc_map->mleid_rloc_map[i].mle_id, 8); } else { // Free id thread_info(cur)->leader_private_data->thread_router_id_list[i].reUsePossible = true; + // clear the mleid in both local router id list and nvm + memset(thread_info(cur)->leader_private_data->thread_router_id_list[i].eui64, 0, 8); + memset(mleid_rloc_map->mleid_rloc_map[i].mle_id, 0, 8); } thread_info(cur)->leader_private_data->thread_router_id_list[i].validLifeTime = 0xffffffff; } + // write back updated map to store + thread_nvm_store_mleid_rloc_map_write(mleid_rloc_map); + ns_dyn_mem_free(mleid_rloc_map); // Clear network data (if exists) and propagate new empty network data thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage); thread_network_data_base_init(&cur->thread_info->networkDataStorage); diff --git a/source/6LoWPAN/Thread/thread_nvm_store.c b/source/6LoWPAN/Thread/thread_nvm_store.c index fdd644e846e4..4bc337788cc9 100644 --- a/source/6LoWPAN/Thread/thread_nvm_store.c +++ b/source/6LoWPAN/Thread/thread_nvm_store.c @@ -52,6 +52,9 @@ const char *FAST_DATA_FILE = "f_d"; const char *LINK_INFO_FILE = "l_i"; #define LINK_INFO_DATA_VERSION 1 +const char *LEADER_INFO_FILE = "ld_i"; +#define LEADER_INFO_DATA_VERSION 1 + typedef struct { uint8_t mac[8]; uint16_t short_addr; @@ -88,6 +91,7 @@ static void thread_nvm_store_link_info_delayed_write(uint32_t seconds); #define DEVICE_CONF_STRING_LEN (strlen(DEVICE_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1) #define PENDING_CONF_STRING_LEN (strlen(THREAD_NVM_PENDING_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1) #define LINK_INFO_STRING_LEN (strlen(LINK_INFO_FILE)+strlen(thread_nvm_store_get_root_path())+1) +#define LEADER_INFO_STRING_LEN (strlen(LEADER_INFO_FILE)+strlen(thread_nvm_store_get_root_path())+1) thread_nvm_fast_data_t cached_fast_data; @@ -117,6 +121,62 @@ static int root_path_valid(void) } return 1; } + +int thread_nvm_store_mleid_rloc_map_write(thread_nvm_mleid_rloc_map *mleid_rloc_map) +{ + char lc_data_path[LEADER_INFO_STRING_LEN]; + if (!root_path_valid()) { + return THREAD_NVM_FILE_ROOT_PATH_INVALID; + } + thread_nvm_store_create_path(lc_data_path, LEADER_INFO_FILE); + tr_debug("writing to store rloc mapping info"); + return thread_nvm_store_write(lc_data_path, mleid_rloc_map, sizeof(thread_nvm_mleid_rloc_map), LEADER_INFO_DATA_VERSION); +} + +int thread_nvm_store_mleid_rloc_map_read(thread_nvm_mleid_rloc_map *mleid_rloc_map) +{ + char lc_data_path[LEADER_INFO_STRING_LEN]; + uint32_t version; + if (NULL==mleid_rloc_map) { + return THREAD_NVM_FILE_PARAMETER_INVALID; + } + if (!root_path_valid()) { + return THREAD_NVM_FILE_ROOT_PATH_INVALID; + } + thread_nvm_store_create_path(lc_data_path, LEADER_INFO_FILE); + + int ret = thread_nvm_store_read(lc_data_path, mleid_rloc_map, sizeof(thread_nvm_mleid_rloc_map), &version); + + if (LEADER_INFO_DATA_VERSION!=version) { + tr_info("Leader data map version mismatch %"PRIu32, version); + thread_nvm_store_mleid_rloc_map_remove(); + return THREAD_NVM_FILE_VERSION_WRONG; + } + if (THREAD_NVM_FILE_SUCCESS!=ret) { + tr_info("Leader data map read failed"); + thread_nvm_store_mleid_rloc_map_remove(); + } + return ret; +} + +int thread_nvm_store_mleid_rloc_map_remove(void) +{ + int status; + tr_info("thread_nvm_store_leader_info_remove"); + + if (!ns_file_system_get_root_path()) { + return THREAD_NVM_FILE_ROOT_PATH_INVALID; + } + + char lc_data_path[LEADER_INFO_STRING_LEN]; + thread_nvm_store_create_path(lc_data_path, LEADER_INFO_FILE); + status = remove(lc_data_path); + if (status != 0) { + return THREAD_NVM_FILE_REMOVE_ERROR; + } + return THREAD_NVM_FILE_SUCCESS; +} + int thread_nvm_store_device_configuration_write(uint8_t *mac_ptr, uint8_t *mleid_ptr) { thread_nvm_device_conf_t d_c; diff --git a/source/6LoWPAN/Thread/thread_nvm_store.h b/source/6LoWPAN/Thread/thread_nvm_store.h index d01a1719f2ee..cd160590add4 100644 --- a/source/6LoWPAN/Thread/thread_nvm_store.h +++ b/source/6LoWPAN/Thread/thread_nvm_store.h @@ -67,6 +67,15 @@ typedef struct { uint8_t mle_id[8]; } thread_nvm_device_conf_t; +typedef struct { + uint8_t mle_id[8]; +} thread_nvm_rloc_map_entry_t; + +typedef struct { + // mapping is in order from 0 to 63 + thread_nvm_rloc_map_entry_t mleid_rloc_map[64]; +} thread_nvm_mleid_rloc_map; + /* reads all fast data from nvm, if the return values is THREAD_NVM_FILE_ROOT_PATH_INVALID, the cached values are returned. */ int thread_nvm_store_fast_data_read(thread_nvm_fast_data_t* fast_data); /* stores all fast data to nvm */ @@ -87,6 +96,9 @@ int thread_nvm_store_active_configuration_remove(void); int thread_nvm_store_device_configuration_write(uint8_t *mac_ptr, uint8_t *mleid_ptr); int thread_nvm_store_device_configuration_read(uint8_t *mac_ptr, uint8_t *mleid_ptr); +int thread_nvm_store_mleid_rloc_map_write(thread_nvm_mleid_rloc_map *mleid_rloc_map); +int thread_nvm_store_mleid_rloc_map_read(thread_nvm_mleid_rloc_map *mleid_rloc_map); +int thread_nvm_store_mleid_rloc_map_remove(void); int thread_nvm_store_pending_configuration_write(void *data, uint16_t size); int thread_nvm_store_pending_configuration_read(void *data, uint16_t size); int thread_nvm_store_pending_configuration_remove(void); diff --git a/source/6LoWPAN/Thread/thread_router_bootstrap.c b/source/6LoWPAN/Thread/thread_router_bootstrap.c index d02f6dbdcc7c..053b14fb5de2 100644 --- a/source/6LoWPAN/Thread/thread_router_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_router_bootstrap.c @@ -410,6 +410,8 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m cur->thread_info->thread_leader_data->dataVersion--; cur->thread_info->thread_leader_data->stableDataVersion--; thread_network_data_request_send(cur, mle_msg->packet_src_address, true); + // remove any existing rloc mapping in nvm + thread_nvm_store_mleid_rloc_map_remove(); tr_info("Router synch OK as Router"); } From 1060c344afe87bcc4d7756dc79f3a071de4d5632 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Fri, 6 Apr 2018 09:32:34 +0300 Subject: [PATCH 31/52] file version checking handled after other errors. (#1641) --- source/6LoWPAN/Thread/thread_nvm_store.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_nvm_store.c b/source/6LoWPAN/Thread/thread_nvm_store.c index 4bc337788cc9..e0c7c9224c94 100644 --- a/source/6LoWPAN/Thread/thread_nvm_store.c +++ b/source/6LoWPAN/Thread/thread_nvm_store.c @@ -147,15 +147,18 @@ int thread_nvm_store_mleid_rloc_map_read(thread_nvm_mleid_rloc_map *mleid_rloc_m int ret = thread_nvm_store_read(lc_data_path, mleid_rloc_map, sizeof(thread_nvm_mleid_rloc_map), &version); + if (THREAD_NVM_FILE_SUCCESS!=ret) { + tr_info("Leader data map read failed"); + thread_nvm_store_mleid_rloc_map_remove(); + return ret; + } + if (LEADER_INFO_DATA_VERSION!=version) { tr_info("Leader data map version mismatch %"PRIu32, version); thread_nvm_store_mleid_rloc_map_remove(); return THREAD_NVM_FILE_VERSION_WRONG; } - if (THREAD_NVM_FILE_SUCCESS!=ret) { - tr_info("Leader data map read failed"); - thread_nvm_store_mleid_rloc_map_remove(); - } + return ret; } From 9e6c3a13a678fb795ce01c046ca7b1bf6eb2b472 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Fri, 6 Apr 2018 09:42:59 +0300 Subject: [PATCH 32/52] Update Thread MLE neighbor list cleanup, attempt #2 (#1640) Update Thread MLE neighbor list cleanup (#1637) -Device needs to clean MLE neighbors (routers and their children) when moving to new partition. Own children can be moved to new partition. -Device is not allowed to update MLE cache based on advertisements from other partition. MLE entries belonging to other partition can be removed from MLE table. -Update traces --- source/6LoWPAN/Thread/thread_bootstrap.c | 16 +++++++-------- source/6LoWPAN/Thread/thread_bootstrap.h | 2 +- source/6LoWPAN/Thread/thread_common.c | 6 +++--- source/6LoWPAN/Thread/thread_host_bootstrap.c | 12 +++++------ source/6LoWPAN/Thread/thread_leader_service.c | 2 +- .../Thread/thread_mle_message_handler.c | 20 ++++++++++++++----- .../6LoWPAN/Thread/thread_router_bootstrap.c | 11 +++++----- .../unittest/stub/thread_bootstrap_stub.c | 2 +- 8 files changed, 41 insertions(+), 30 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index 3ad18e4d579a..cfe6b3434e6e 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -1159,14 +1159,14 @@ void thread_bootstrap_ready(protocol_interface_info_entry_t *cur) mac_data_poll_protocol_poll_mode_decrement(cur); } -void thread_clean_all_routers_from_neighbor_list(int8_t interface_id) -{ - mle_neigh_table_list_t *neig_list = mle_class_active_list_get(interface_id); - /* Init Double linked Routing Table */ - ns_list_foreach_safe(mle_neigh_table_entry_t, cur, neig_list) { - if (thread_is_router_addr(cur->short_adr)) { - tr_debug("Free Router %x", cur->short_adr); - mle_class_remove_entry(interface_id, cur); +void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur) +{ + mle_neigh_table_list_t *neig_list = mle_class_active_list_get(cur->id); + + ns_list_foreach_safe(mle_neigh_table_entry_t, cur_entry, neig_list) { + if (!thread_addr_is_equal_or_child(cur->thread_info->routerShortAddress, cur_entry->short_adr)) { + tr_debug("Free ID %x", cur_entry->short_adr); + mle_class_remove_entry(cur->id, cur_entry); } } } diff --git a/source/6LoWPAN/Thread/thread_bootstrap.h b/source/6LoWPAN/Thread/thread_bootstrap.h index 09b07918521b..517321704b0e 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.h +++ b/source/6LoWPAN/Thread/thread_bootstrap.h @@ -106,7 +106,7 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, int thread_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mle_neigh_table_entry_t *child); void thread_bootstrap_ready(struct protocol_interface_info_entry *cur); int thread_bootstrap_reset(struct protocol_interface_info_entry *cur); -void thread_clean_all_routers_from_neighbor_list(int8_t interface_id); +void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur); bool thread_bootstrap_request_network_data(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, uint16_t short_address); bool thread_check_is_this_my_parent(struct protocol_interface_info_entry *cur, struct mle_neigh_table_entry_t *entry_temp); void thread_clean_old_16_bit_address_based_addresses(struct protocol_interface_info_entry *cur); diff --git a/source/6LoWPAN/Thread/thread_common.c b/source/6LoWPAN/Thread/thread_common.c index b3652d7b95ed..58ee80c840f6 100644 --- a/source/6LoWPAN/Thread/thread_common.c +++ b/source/6LoWPAN/Thread/thread_common.c @@ -233,8 +233,8 @@ int8_t thread_bootstrap_down(protocol_interface_info_entry_t *cur) tr_debug("SET thread Idle"); //stop polling mac_data_poll_disable(cur); - //Clean routers from mle table - thread_clean_all_routers_from_neighbor_list(cur->id); + //Clean mle table + thread_neighbor_list_clean(cur); // store frame counters if (cur->thread_info) { thread_nvm_fast_data_t fast_data; @@ -1849,8 +1849,8 @@ void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent; if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->short_adr) { - tr_warn("End device lost Parent!\n"); if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) { + tr_warn("End device lost parent, reset!\n"); thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); } } diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index 83cc9ccc5dc7..ebed1f7b492d 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -393,7 +393,7 @@ static void thread_child_synch_receive_cb(int8_t interface_id, mle_message_t *ml messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } @@ -471,7 +471,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m return; } - tr_debug("Thread MLE Parent request response Handler"); + tr_debug("MLE Parent response handler"); //State machine What packet should accept in this case switch (mle_msg->message_type) { case MLE_COMMAND_PARENT_RESPONSE: { @@ -496,7 +496,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } @@ -747,7 +747,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message return; } - tr_debug("Thread MLE Child request response Handler"); + tr_debug("Thread MLE Child ID response handler"); switch (mle_msg->message_type) { @@ -762,7 +762,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message thread_scanned_parent_t *scan_result = thread_info(cur)->thread_attach_scanned_parent; bool new_entry_created; - tr_info("Received Child ID Response"); + tr_info("Recv Child ID Response"); // Validate that response is coming from the scanned parent candidate memcpy(src_mac64, (mle_msg->packet_src_address + 8), 8); @@ -779,7 +779,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message cur->thread_info->localServerDataBase.release_old_address = true; - thread_clean_all_routers_from_neighbor_list(cur->id); + thread_neighbor_list_clean(cur); thread_leader_service_stop(interface_id); thread_leader_service_leader_data_free(cur->thread_info); thread_merge_prepare(cur); diff --git a/source/6LoWPAN/Thread/thread_leader_service.c b/source/6LoWPAN/Thread/thread_leader_service.c index 02d24e859fac..6b43c7805c72 100644 --- a/source/6LoWPAN/Thread/thread_leader_service.c +++ b/source/6LoWPAN/Thread/thread_leader_service.c @@ -1295,7 +1295,7 @@ static int thread_leader_service_leader_init(protocol_interface_info_entry_t *cu thread_nd_service_delete(cur->id); mpl_clear_realm_scope_seeds(cur); ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache); - thread_clean_all_routers_from_neighbor_list(cur->id); + thread_neighbor_list_clean(cur); cur->mesh_callbacks = NULL; cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; diff --git a/source/6LoWPAN/Thread/thread_mle_message_handler.c b/source/6LoWPAN/Thread/thread_mle_message_handler.c index 6dd9a25aa7ea..1f9e2d2ef250 100644 --- a/source/6LoWPAN/Thread/thread_mle_message_handler.c +++ b/source/6LoWPAN/Thread/thread_mle_message_handler.c @@ -327,8 +327,10 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle { mle_tlv_info_t routeTlv; thread_leader_data_t leaderData; - uint16_t shortAddress; mle_neigh_table_entry_t *entry_temp; + uint16_t shortAddress; + bool my_parent; + bool adv_from_my_partition; // Check device mode & bootstrap state if ((thread_info(cur)->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) || @@ -346,15 +348,23 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle // Get MLE entry entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); - if ((security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) - && (thread_instance_id_matches(cur, &leaderData))) { + my_parent = thread_check_is_this_my_parent(cur, entry_temp); + adv_from_my_partition = thread_instance_id_matches(cur, &leaderData); + + if ((security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) && adv_from_my_partition) { thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); } + if (entry_temp && !adv_from_my_partition && !my_parent ) { + // Remove MLE entry that are located in other partition and is not my parent + mle_class_remove_entry(cur->id, entry_temp); + entry_temp = NULL; + } + // Check parent status if (!thread_attach_active_router(cur)) { //processing for non routers - if (thread_check_is_this_my_parent(cur, entry_temp)) { + if (my_parent) { //advertisement from parent if ((thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) || (thread_info(cur)->thread_leader_data->weighting != leaderData.weighting)) { @@ -428,7 +438,7 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } diff --git a/source/6LoWPAN/Thread/thread_router_bootstrap.c b/source/6LoWPAN/Thread/thread_router_bootstrap.c index 053b14fb5de2..ced6b84281ca 100644 --- a/source/6LoWPAN/Thread/thread_router_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_router_bootstrap.c @@ -340,7 +340,7 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } /*Link accept command has an optional MLE Frame counter TLV, if this is not present use link layer frame counter TLV @@ -896,7 +896,7 @@ static int thread_attach_parent_response_build(protocol_interface_info_entry_t * if (bufId == 0) { return -1; } - tr_debug("MLE ATTACHED 2. Packet"); + tr_debug("Build MLE Parent response"); uint32_t keySequence; uint8_t *ptr = mle_service_get_data_pointer(bufId); @@ -1359,7 +1359,6 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c thread_nd_address_registration(cur, tempIPv6Address, entry_temp->short_adr, cur->mac_parameters->pan_id, entry_temp->mac64); } - tr_debug("Response Child Id Request"); mle_attach_child_id_response_build(cur,ll64,req, entry_temp); free_request: @@ -1593,7 +1592,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } @@ -1608,6 +1607,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * mle_msg->packet_src_address[8] ^= 2; if (!id_req) { + tr_debug("No room for child id req"); return; } @@ -1629,6 +1629,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * (!mle_tlv_read_32_bit_tlv(MLE_TYPE_LL_FRAME_COUNTER, mle_msg->data_ptr, mle_msg->data_length, &id_req->frameCounter)) || (!mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlvRequest))) { thread_child_id_request_entry_remove(cur, id_req); + tr_debug("Illegal child id req"); return; } //If MLE MLE_TYPE_MLE_FRAME_COUNTER TLV is present then use it for validating further messages else use link layer frame counter @@ -1829,7 +1830,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); if (messageId == 0) { - tr_debug("Not for me"); + tr_debug("No matching challenge"); return; } diff --git a/test/nanostack/unittest/stub/thread_bootstrap_stub.c b/test/nanostack/unittest/stub/thread_bootstrap_stub.c index 714c2f278ab1..5f36cd0c53a1 100644 --- a/test/nanostack/unittest/stub/thread_bootstrap_stub.c +++ b/test/nanostack/unittest/stub/thread_bootstrap_stub.c @@ -257,7 +257,7 @@ int8_t thread_mle_class_init(int8_t interface_id) return 0; } -void thread_clean_all_routers_from_neighbor_list(int8_t interface_id) +void thread_neighbor_list_clean(protocol_interface_info_entry_t *cur) { } From 9f85599c85aabc8fed1027fe5cf8fb96f060ae33 Mon Sep 17 00:00:00 2001 From: Kari Severinkangas Date: Fri, 6 Apr 2018 10:37:27 +0300 Subject: [PATCH 33/52] Security bits handled correctly (#1642) --- source/6LoWPAN/Thread/thread_extension.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_extension.c b/source/6LoWPAN/Thread/thread_extension.c index dd734aeb7d9b..d03d55244831 100644 --- a/source/6LoWPAN/Thread/thread_extension.c +++ b/source/6LoWPAN/Thread/thread_extension.c @@ -64,7 +64,7 @@ #define TRACE_GROUP "comm" -#define SECURITY_POLICY_CCM_ENABLED 0x04 /* Thread Commercial Commissioning Mode is enabled when this bit is set. This is Thread 1.2 feature. */ +#define SECURITY_POLICY_CCM_DISABLED 0x04 /* Thread Commercial Commissioning Mode is enabled when this bit is set. This is Thread 1.2 feature. */ typedef struct thread_extension_info { int8_t coap_service_id; @@ -581,7 +581,7 @@ bool thread_extension_enabled(protocol_interface_info_entry_t *cur) } uint16_t securityPolicy = thread_joiner_application_security_policy_get(cur->id); - if (securityPolicy & SECURITY_POLICY_CCM_ENABLED) { + if (!(securityPolicy & SECURITY_POLICY_CCM_DISABLED)) { return true; } @@ -620,11 +620,9 @@ void thread_extension_discover_response_read(discovery_response_list_t *nwk_info void thread_extension_discover_response_tlv_write(uint16_t *data, uint8_t version, uint16_t securityPolicy) { - - if (version == 3 && !(securityPolicy & SECURITY_POLICY_CCM_ENABLED)) { + if (version == 3 && !(securityPolicy & SECURITY_POLICY_CCM_DISABLED)) { *data |= (uint16_t) (1 << 10); } - return; } #ifdef HAVE_THREAD_ROUTER From 564d3fe70168e65d94547f503fc7e82257d1543d Mon Sep 17 00:00:00 2001 From: Tero Heinonen Date: Fri, 6 Apr 2018 13:26:10 +0300 Subject: [PATCH 34/52] Added filter callback for MLE messages (#1638) Added test API to set callback to filter received MLE messages. --- nanostack/net_test_api.h | 8 ++++++ source/Service_Libs/mle_service/mle_service.c | 20 ++++++++++++++- .../mle_service/mle_service_api.h | 25 +++++++++++++++++++ source/configs/generic.cfg | 1 + source/libNET/src/net_test.c | 6 +++++ 5 files changed, 59 insertions(+), 1 deletion(-) diff --git a/nanostack/net_test_api.h b/nanostack/net_test_api.h index 8b797df305bc..78b2898da23b 100644 --- a/nanostack/net_test_api.h +++ b/nanostack/net_test_api.h @@ -24,6 +24,7 @@ #define NET_TEST_API_H_ #include "ns_types.h" +#include "Service_Libs/mle_service/mle_service_api.h" /** * \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); */ void arm_nwk_test_tcp_drop_reset(void); +/** + * \brief Set callback for MLE message receiving filter. + * + * Testing API for setting MLE receive callback for message filtering purposes. + */ +void arm_nwk_test_mle_receive_filter_set(mle_service_filter_cb *response_filter_cb); + #endif //NET_TEST_API_H_ diff --git a/source/Service_Libs/mle_service/mle_service.c b/source/Service_Libs/mle_service/mle_service.c index 9bded4cb8db3..88394d02aae7 100644 --- a/source/Service_Libs/mle_service/mle_service.c +++ b/source/Service_Libs/mle_service/mle_service.c @@ -68,6 +68,10 @@ typedef struct { mle_service_class_t *mle_service = NULL; +#ifdef MLE_TEST +static mle_service_filter_cb *receive_filter_cb = NULL; +#endif + static uint8_t *mle_security_aux_header_write(uint8_t *ptr, const mle_security_header_t *auxHeader); static void mle_security_aux_ccm_nonce_set(uint8_t *noncePtr, uint8_t *mac64, uint32_t securityFrameCounter, uint8_t securityLevel); static uint8_t mle_security_aux_header_size(uint8_t keyIdMode); @@ -802,6 +806,13 @@ static void mle_service_socket_callback(void *cb) mle_msg.dbm = buf->options.dbm; mle_msg.lqi = buf->options.lqi; +#ifdef MLE_TEST + if (receive_filter_cb) { + if (!receive_filter_cb(service_handler->interface_id, &mle_msg, &securityHeader)) { + goto error_handler; + } + } +#endif if (security_bypass) { /* Security by pass message handler call */ service_handler->recv_security_bypass_cb(service_handler->interface_id, &mle_msg); @@ -812,7 +823,7 @@ static void mle_service_socket_callback(void *cb) } } - error_handler: +error_handler: if (buf) { buffer_free(buf); } @@ -1497,3 +1508,10 @@ void mle_service_set_accept_invalid_frame_counter(bool value) } } +#ifdef MLE_TEST +void mle_service_receive_filter_cb_set(mle_service_filter_cb *filter_cb) +{ + receive_filter_cb = filter_cb; +} + +#endif diff --git a/source/Service_Libs/mle_service/mle_service_api.h b/source/Service_Libs/mle_service/mle_service_api.h index 974176638567..00e61f217fd1 100644 --- a/source/Service_Libs/mle_service/mle_service_api.h +++ b/source/Service_Libs/mle_service/mle_service_api.h @@ -189,6 +189,21 @@ typedef uint8_t * (mle_service_security_notify_cb)(int8_t interface_id, mle_secu */ typedef bool (mle_service_message_timeout_cb)(int8_t interface_id, uint16_t msgId, bool usedAllRetries); +/** + * A callback for receive MLE message filtering + * + * This function will be called when MLE message is received. Only for testing purposes. + * + * \param interface_id define interface id for receiver + * \param mle_msg received MLE message + * \param security_headers messages security parameters + * + * \return true continue MLE packet processing + * \return false drop MLE packet + * + */ +typedef bool (mle_service_filter_cb)(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers); + /* * Initialise server instance. * Creates and shares socket for other mle services. @@ -704,4 +719,14 @@ void mle_service_set_fragmented_msg_ll_security(bool value); */ void mle_service_set_accept_invalid_frame_counter(bool value); +#ifdef MLE_TEST +/** + * Set callback for MLE receiving packet filtering. + * + * If this is set, all received MLE messages will be passed to given callback. + */ +void mle_service_receive_filter_cb_set(mle_service_filter_cb *filter_cb); +#else +#define mle_service_receive_filter_cb_set(filter_cb) ((void) 0) +#endif /* MLE_TEST */ #endif /* MLE_SERVICE_API_H_ */ diff --git a/source/configs/generic.cfg b/source/configs/generic.cfg index 85018d8fe591..ea8216f7b76c 100644 --- a/source/configs/generic.cfg +++ b/source/configs/generic.cfg @@ -30,3 +30,4 @@ #define HAVE_DHCPV6_SERVER #define TCP_TEST #define THREAD_THCI_SUPPORT +#define MLE_TEST diff --git a/source/libNET/src/net_test.c b/source/libNET/src/net_test.c index 51c1408a056f..668ba809e4bd 100644 --- a/source/libNET/src/net_test.c +++ b/source/libNET/src/net_test.c @@ -20,6 +20,7 @@ #include #include "nsdynmemLIB.h" #include "NWK_INTERFACE/Include/protocol.h" +#include "Service_Libs/mle_service/mle_service_api.h" #include "net_test_api.h" #include "Common_Protocols/tcp.h" @@ -76,3 +77,8 @@ int8_t arm_nwk_test_tcp_drop_rx(int state, uint8_t count) void arm_nwk_test_tcp_drop_reset() { tcp_test_drop_reset(); } + +void arm_nwk_test_mle_receive_filter_set(mle_service_filter_cb *response_filter_cb) +{ + mle_service_receive_filter_cb_set(response_filter_cb); +} From 5af4a39d92c3d5e4596c62cbc0f8663fe4276447 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Mon, 9 Apr 2018 09:50:52 +0300 Subject: [PATCH 35/52] updated mleid rloc sync in leader. (#1645) --- source/6LoWPAN/Thread/thread_common.c | 1 + source/6LoWPAN/Thread/thread_leader_service.c | 10 +++++++--- source/6LoWPAN/Thread/thread_leader_service.h | 4 ++++ .../unittest/stub/thread_leader_service_stub.c | 4 ++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_common.c b/source/6LoWPAN/Thread/thread_common.c index 58ee80c840f6..db166f84cecc 100644 --- a/source/6LoWPAN/Thread/thread_common.c +++ b/source/6LoWPAN/Thread/thread_common.c @@ -249,6 +249,7 @@ int8_t thread_bootstrap_down(protocol_interface_info_entry_t *cur) thread_joiner_application_configuration_nvm_save(cur->id); mac_pairwise_key_flush_list(cur->id); thread_discovery_reset(cur->id); + thread_leader_mleid_rloc_map_to_nvm_write(cur); thread_bootstrap_stop(cur); mle_service_interface_unregister(cur->id); thread_management_server_delete(cur->id); diff --git a/source/6LoWPAN/Thread/thread_leader_service.c b/source/6LoWPAN/Thread/thread_leader_service.c index 6b43c7805c72..d1e21e7f6d66 100644 --- a/source/6LoWPAN/Thread/thread_leader_service.c +++ b/source/6LoWPAN/Thread/thread_leader_service.c @@ -742,11 +742,15 @@ void thread_leader_mleid_rloc_map_populate(thread_nvm_mleid_rloc_map *mleid_rloc } } -static int thread_leader_update_mleid_rloc_map_in_nvm(protocol_interface_info_entry_t *cur) +int thread_leader_mleid_rloc_map_to_nvm_write(protocol_interface_info_entry_t *cur) { + if (!cur->thread_info->leader_private_data) { + return -1; + } + thread_nvm_mleid_rloc_map *mleid_rloc_map = ns_dyn_mem_temporary_alloc(sizeof(thread_nvm_mleid_rloc_map)); if (!mleid_rloc_map) { - return -1; + return -2; } memset(mleid_rloc_map, 0, sizeof(thread_nvm_mleid_rloc_map)); thread_leader_mleid_rloc_map_populate(mleid_rloc_map, cur->thread_info->leader_private_data); @@ -1533,7 +1537,7 @@ void thread_leader_service_timer(protocol_interface_info_entry_t *cur, uint32_t } else { cur->thread_info->leader_private_data->leader_nvm_sync_timer = 0; - thread_leader_update_mleid_rloc_map_in_nvm(cur); + thread_leader_mleid_rloc_map_to_nvm_write(cur); } } diff --git a/source/6LoWPAN/Thread/thread_leader_service.h b/source/6LoWPAN/Thread/thread_leader_service.h index 465a027ce23e..7eabcb302832 100644 --- a/source/6LoWPAN/Thread/thread_leader_service.h +++ b/source/6LoWPAN/Thread/thread_leader_service.h @@ -118,6 +118,8 @@ void thread_leader_service_network_data_changed(protocol_interface_info_entry_t void thread_leader_service_timer(protocol_interface_info_entry_t *cur, uint32_t ticks); +int thread_leader_mleid_rloc_map_to_nvm_write(protocol_interface_info_entry_t *cur); + /** Get first child ID from network data based on parent ID * * \param thread_info @@ -161,6 +163,8 @@ void thread_leader_service_router_state_changed(thread_info_t *thread_info, uint #define thread_leader_service_router_state_changed(thread_info, router_id, available, interface_id) +#define thread_leader_mleid_rloc_map_to_nvm_write(cur) (0) + #endif /*HAVE_THREAD_LEADER_SERVICE*/ #endif /* _THREAD_LEADER_SERVICE_H_ */ diff --git a/test/nanostack/unittest/stub/thread_leader_service_stub.c b/test/nanostack/unittest/stub/thread_leader_service_stub.c index 6735a6765a91..a22ee345ce21 100644 --- a/test/nanostack/unittest/stub/thread_leader_service_stub.c +++ b/test/nanostack/unittest/stub/thread_leader_service_stub.c @@ -83,3 +83,7 @@ void thread_leader_service_thread_partitition_generate(int8_t interface_id, bool void thread_leader_service_network_data_changed(protocol_interface_info_entry_t *cur, bool force_stable_update, bool force_unstable_update) { } +int thread_leader_mleid_rloc_map_to_nvm_write(protocol_interface_info_entry_t *cur) +{ + return 0; +} From 4fda90e5cfed74c8de27b641a40b1f8c83a6781e Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Tue, 10 Apr 2018 17:11:36 +0300 Subject: [PATCH 36/52] Clear data request flag in child_id_req timeout (#1649) Clear data request flag when returning back to old partition due child_id_request timeout. --- source/6LoWPAN/Thread/thread_host_bootstrap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index ebed1f7b492d..fd384af728e2 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -1035,6 +1035,7 @@ static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, boo cur->thread_info->localServerDataBase.release_old_address = false; cur->thread_info->releaseRouterId = false; + cur->thread_info->networkDataRequested = false; cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; From 9e7e9e0e17ed142a47ea9eb571b600f3c43aba35 Mon Sep 17 00:00:00 2001 From: Tero Heinonen Date: Mon, 16 Apr 2018 09:50:28 +0300 Subject: [PATCH 37/52] REED parser refactoring for MLE advertisement (#1654) Refactored REED parser logic for MLE advertisement to make function more simpler, and some unneeded code removed. --- .../Thread/thread_mle_message_handler.c | 71 ++++++++++--------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_mle_message_handler.c b/source/6LoWPAN/Thread/thread_mle_message_handler.c index 1f9e2d2ef250..1d13af747563 100644 --- a/source/6LoWPAN/Thread/thread_mle_message_handler.c +++ b/source/6LoWPAN/Thread/thread_mle_message_handler.c @@ -224,8 +224,6 @@ static bool thread_router_leader_data_process(protocol_interface_info_entry_t *c // Request network data if we have a 2-way link tr_debug("Request New Network Data from %s", trace_ipv6(src_address)); thread_network_data_request_send(cur, src_address, true); - } else { - } } else if (leaderDataUpdate == 2) { tr_debug("Start Merge"); @@ -323,14 +321,31 @@ static void thread_update_mle_entry(protocol_interface_info_entry_t *cur, mle_me return; } +static bool thread_parse_advertisement_from_parent(protocol_interface_info_entry_t *cur, thread_leader_data_t *leader_data, uint16_t short_address) +{ + if ((thread_info(cur)->thread_leader_data->partitionId != leader_data->partitionId) || + (thread_info(cur)->thread_leader_data->weighting != leader_data->weighting)) { + //parent changed partition/weight - reset own routing information + thread_old_partition_data_purge(cur); + } + //check if network data needs to be requested + if (!thread_bootstrap_request_network_data(cur, leader_data, short_address)) { + tr_debug("Parent short address changed - re-attach"); + thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); + return false; + } + + return true; +} + static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, uint8_t linkMargin) { mle_tlv_info_t routeTlv; thread_leader_data_t leaderData; mle_neigh_table_entry_t *entry_temp; uint16_t shortAddress; - bool my_parent; bool adv_from_my_partition; + bool my_parent; // Check device mode & bootstrap state if ((thread_info(cur)->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) || @@ -348,7 +363,9 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle // Get MLE entry entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); + // Check if this is from my parent my_parent = thread_check_is_this_my_parent(cur, entry_temp); + adv_from_my_partition = thread_instance_id_matches(cur, &leaderData); if ((security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) && adv_from_my_partition) { @@ -361,22 +378,10 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle entry_temp = NULL; } - // Check parent status - if (!thread_attach_active_router(cur)) { - //processing for non routers - if (my_parent) { - //advertisement from parent - 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); - } - //check if network data needs to be requested - if (!thread_bootstrap_request_network_data(cur, &leaderData, shortAddress)) { - tr_debug("Parent short address changed - re-attach"); - thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); - return; - } + /* Check parent status */ + if (!thread_attach_active_router(cur) && my_parent) { + if (!thread_parse_advertisement_from_parent(cur, &leaderData, shortAddress)) { + return; } } @@ -385,30 +390,28 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle // Process advertisement if (thread_info(cur)->thread_device_mode != THREAD_DEVICE_MODE_END_DEVICE) { + /* REED and FED */ 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) && - (thread_info(cur)->thread_leader_data->weighting == leaderData.weighting)) { + /* Check if advertisement is from same partition */ + if (thread_info(cur)->thread_leader_data->weighting == leaderData.weighting && thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId ) { + if (!entry_temp && thread_bootstrap_link_create_check(cur, shortAddress) && thread_bootstrap_link_create_allowed(cur, shortAddress, mle_msg->packet_src_address)) { // Create link to new neighbor no other processing allowed thread_link_request_start(cur, mle_msg->packet_src_address); return; } - if (!thread_router_leader_data_process(cur, mle_msg->packet_src_address, &leaderData, &routeTlv, entry_temp)) { - // better partition found or new network data learn started + /* Advertisement from higher / lower partition */ + } else { + // process REED advertisement from higher partition + if (thread_reed_partitions_merge(cur, shortAddress, leaderData)) { return; } + // REED advertisement to lower partition to help merge faster + if (thread_heard_lower_partition(cur,leaderData)) { + thread_router_bootstrap_reed_merge_advertisement(cur); + } } - // process REED advertisement from higher partition - if (thread_reed_partitions_merge(cur, shortAddress, leaderData)) { - return; - } - // REED advertisement to lower partition to help merge faster - if (thread_heard_lower_partition(cur,leaderData)) { - thread_router_bootstrap_reed_merge_advertisement(cur); - } + /* ROUTER */ } else { - //Router if (!thread_router_leader_data_process(cur, mle_msg->packet_src_address, &leaderData, &routeTlv, entry_temp) ) { return; } From 41ca387fe23c59dc557ee1530338e42e3b8fb664 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Mon, 16 Apr 2018 12:54:15 +0300 Subject: [PATCH 38/52] removed the dependence of AE message relay on DUA prefix (#1655) --- source/6LoWPAN/Thread/thread_extension_bbr.c | 41 +++++++------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.c b/source/6LoWPAN/Thread/thread_extension_bbr.c index a2f402d07848..f6fafc33371d 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.c +++ b/source/6LoWPAN/Thread/thread_extension_bbr.c @@ -891,14 +891,17 @@ static int thread_extension_bbr_pbbr_start(thread_pbbr_t *this) //If started only refresh network data return 0; } + // Register to backbone CoAP service + this->br_bb_service_id = coap_service_initialize(this->backbone_interface_id, this->pbbr_port, COAP_SERVICE_OPTIONS_SELECT_SOCKET_IF, NULL, NULL); + if(this->br_bb_service_id < 0) { + tr_error("pBBR Commercial service start failed"); + thread_extension_bbr_pbbr_stop(this); + return -1; + } // Allow only filtered addresses to be forwarded multicast_fwd_full_for_scope(this->interface_id, 0x10); multicast_fwd_full_for_scope(this->backbone_interface_id, 0); - //Register baseline 1.2 features - coap_service_register_uri(this->coap_service_id, THREAD_URI_BBR_MCAST_LISTENER_REPORT, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_extension_bbr_mlr_cb); - this->pbbr_started = true; - // Generate pbbr multicast address memset(this->pbbr_multicast_address, 0, 16); this->pbbr_multicast_address[0] = 0xff; @@ -906,31 +909,21 @@ static int thread_extension_bbr_pbbr_start(thread_pbbr_t *this) this->pbbr_multicast_address[2] = 0x00; //Reserved this->pbbr_multicast_address[3] = 0x40; //Prefix length 64 bits this->pbbr_multicast_address[15] = 2; - if (0 != thread_extension_network_prefix_get(this->interface_id, NULL, &this->pbbr_multicast_address[4], NULL)) { - //No domain prefix in settings DUA handling not used - tr_info("pBBR service started (Home network)"); - return 0; - } + tr_info("pBBR service started (Commercial network)"); - // Start commercial mode features + // Register Primary BBR backbone multicast address multicast_add_address(this->pbbr_multicast_address, false); - // Register to backbone CoAP service - this->br_bb_service_id = coap_service_initialize(this->backbone_interface_id, this->pbbr_port, COAP_SERVICE_OPTIONS_SELECT_SOCKET_IF, NULL, NULL); - if(this->br_bb_service_id < 0) { - tr_error("pBBR Commercial service start failed"); - thread_extension_bbr_pbbr_stop(this); - return -1; - } - // Register Primary BBR backbone multicast address + this->pbbr_started = true; - // Register commercial features + // Register Backbone commercial features coap_service_register_uri(this->br_bb_service_id, THREAD_URI_BBR_BB_QRY_NTF, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_pbbr_bb_qry_cb); coap_service_register_uri(this->br_bb_service_id, THREAD_URI_BBR_BB_ANS_NTF, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_pbbr_bb_ans_cb); coap_service_register_uri(this->br_bb_service_id, THREAD_URI_TRI_TX_NTF, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_pbbr_relay_from_tri_cb); coap_service_register_uri(this->br_bb_service_id, THREAD_URI_BBR_BMLR_NTF, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_extension_bbr_bmlr_cb); // Register Mesh address registration URI + coap_service_register_uri(this->coap_service_id, THREAD_URI_BBR_MCAST_LISTENER_REPORT, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_extension_bbr_mlr_cb); coap_service_register_uri(this->coap_service_id, THREAD_URI_BBR_DOMAIN_ADDRESS_REGISTRATION, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_extension_bbr_dua_cb); // Register Mesh side relay URI coap_service_register_uri(this->coap_service_id, THREAD_URI_BBR_TRI_RX_NTF, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_pbbr_relay_to_tri_cb); @@ -942,7 +935,7 @@ static int thread_extension_bbr_pbbr_start(thread_pbbr_t *this) thread_extension_bootstrap_network_certificate_enable(cur, this->coap_nmkp_virtual_service_id); coap_service_register_uri(this->coap_nmkp_virtual_service_id, THREAD_URI_BBR_NMKP_REQ, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_pbbr_nmkp_req_recv_cb); coap_service_virtual_socket_set_cb(this->coap_nmkp_virtual_service_id, thread_pbbr_nmkp_virtual_socket_send_cb); - // Set the partition weight to be 72 + return 0; } @@ -986,6 +979,8 @@ int8_t thread_extension_bbr_init(int8_t interface_id, int8_t backbone_interface_ } ns_list_add_to_start(&pbbr_instance_list, this); + // Set the partition weight to be 72 + thread_management_partition_weighting_set(this->interface_id, 72); return 0; } @@ -1066,12 +1061,6 @@ void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds) thread_extension_bbr_pbbr_start(this); } else { - if(this->br_bb_service_id < 0 && - thread_extension_network_prefix_get(cur->id, NULL, NULL, NULL) == 0) { - // Settings changed to commercial - thread_extension_bbr_pbbr_stop(this); - thread_extension_bbr_pbbr_start(this); - } if (thread_extension_bbr_downgrade_to_secondary(cur)) { tr_info("pbbr downgraded"); thread_extension_bbr_pbbr_stop(this); From f8b227fac181b7a5044f8e3386d8f2a31d6bf8be Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Tue, 17 Apr 2018 13:53:17 +0300 Subject: [PATCH 39/52] Thread DHCP address allocation fix (#1657) If Thread network data contains multiple border routers then global address can be allocated for each prefix. Do not allow simultaneous DHCP solicits for single prefix. --- source/6LoWPAN/Thread/thread_bootstrap.c | 14 ++++---- source/6LoWPAN/Thread/thread_dhcpv6_client.c | 35 +++++++++++++++----- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index cfe6b3434e6e..eb04b72e2383 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -1807,7 +1807,7 @@ static void thread_dhcp_client_gua_error_cb(int8_t interface, uint8_t dhcp_addr[ } } -static bool thread_dhcpv6_address_valid(uint8_t *prefixPtr, if_address_list_t *list) +bool thread_dhcpv6_address_entry_available(uint8_t *prefixPtr, if_address_list_t *list) { bool addressReady = false; ns_list_foreach(if_address_entry_t, entry, list) { @@ -2501,8 +2501,8 @@ int thread_bootstrap_network_data_process(protocol_interface_info_entry_t *cur, memcpy(addr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, 8); memcpy(&addr[8], ADDR_SHORT_ADR_SUFFIC, 6); common_write_16_bit(genericService.routerID, &addr[14]); - thread_dhcp_client_global_address_delete(cur->id, addr, prefixTlv.Prefix); tr_debug("Delete DHCPv6 given address"); + thread_dhcp_client_global_address_delete(cur->id, addr, prefixTlv.Prefix); } } @@ -2729,7 +2729,7 @@ void thread_bootstrap_network_prefixes_process(protocol_interface_info_entry_t * bool validToLearnRoutes, validToLearOnMeshRoute; thread_network_server_data_entry_t *weHostService = NULL; uint16_t routerId; - tr_debug("Network Data:"); + tr_debug("Network Data process:"); routerId = cur->mac_parameters->mac_short_address; thread_network_data_cache_entry_t *networkData; networkData = &cur->thread_info->networkDataStorage; @@ -2792,14 +2792,14 @@ void thread_bootstrap_network_prefixes_process(protocol_interface_info_entry_t * } } - if (!thread_dhcpv6_address_valid(curPrefix->servicesPrefix, &cur->ip_addresses)) { + if (!thread_dhcpv6_address_entry_available(curPrefix->servicesPrefix, &cur->ip_addresses)) { thread_addr_write_mesh_local_16(addr, curBorderRouter->routerID, cur->thread_info); - + /* Do not allow multiple DHCP solicits from one prefix => delete previous */ + thread_dhcp_client_global_address_delete(cur->id, NULL, curPrefix->servicesPrefix); if (thread_dhcp_client_get_global_address(cur->id, addr, curPrefix->servicesPrefix, cur->mac, thread_dhcp_client_gua_error_cb) == 0) { tr_debug("GP Address Requested"); } } - } else { /* All end device types perform RLOC16 -> 0xfffe replacement if stable network data was requested. */ @@ -2812,7 +2812,7 @@ void thread_bootstrap_network_prefixes_process(protocol_interface_info_entry_t * } if (curBorderRouter->P_preferred) { - if (!thread_dhcpv6_address_valid(curPrefix->servicesPrefix, &cur->ip_addresses)) { + if (!thread_dhcpv6_address_entry_available(curPrefix->servicesPrefix, &cur->ip_addresses)) { icmpv6_slaac_address_add(cur, curPrefix->servicesPrefix, curPrefix->servicesPrefixLen, 0xffffffff, 0xffffffff, true, SLAAC_IID_DEFAULT); } } diff --git a/source/6LoWPAN/Thread/thread_dhcpv6_client.c b/source/6LoWPAN/Thread/thread_dhcpv6_client.c index 7005b52336c6..642857bdd708 100644 --- a/source/6LoWPAN/Thread/thread_dhcpv6_client.c +++ b/source/6LoWPAN/Thread/thread_dhcpv6_client.c @@ -135,6 +135,13 @@ int dhcp_solicit_resp_cb(uint16_t instance_id, void *ptr, uint8_t msg_name, uin tr_error("Sol Not include all Options"); goto error_exit; } + + if (libdhcpv6_nonTemporal_entry_get_by_iaid(dhcp_ia_non_temporal_params.iaId) != srv_data_ptr) { + /* Validate server data availability */ + tr_error("Valid instance not found"); + goto error_exit; + } + if (srv_data_ptr->IAID != dhcp_ia_non_temporal_params.iaId) { tr_error("Wrong IAID"); goto error_exit; @@ -181,7 +188,9 @@ int thread_dhcp_client_get_global_address(int8_t interface, uint8_t dhcp_addr[st tr_error("Invalid parameters"); return -1; } + srv_data_ptr = libdhcvp6_nontemporalAddress_server_data_allocate(interface, dhcp_client.libDhcp_instance, mac64, DHCPV6_DUID_HARDWARE_EUI64_TYPE, prefix, dhcp_addr); + payload_len = libdhcpv6_solication_message_length(DHCPV6_DUID_HARDWARE_EUI64_TYPE, true, 0); payload_ptr = ns_dyn_mem_temporary_alloc(payload_len); @@ -207,6 +216,7 @@ int thread_dhcp_client_get_global_address(int8_t interface, uint8_t dhcp_addr[st srv_data_ptr->transActionId = dhcp_service_send_req(dhcp_client.service_instance, 0, srv_data_ptr , dhcp_addr, payload_ptr, payload_len, dhcp_solicit_resp_cb); return srv_data_ptr->transActionId ? 0 : -1; } + void thread_dhcp_client_global_address_renew(int8_t interface) { // only prepared for changes in thread specifications @@ -219,15 +229,23 @@ void thread_dhcp_client_global_address_delete(int8_t interface, uint8_t dhcp_add protocol_interface_info_entry_t *cur; dhcpv6_client_server_data_t *srv_data_ptr; (void) dhcp_addr; + srv_data_ptr = libdhcpv6_nonTemporal_entry_get_by_prefix(interface, prefix); cur = protocol_stack_interface_info_get_by_id(interface); - if (cur == NULL || srv_data_ptr == NULL) { - tr_error("Not valid prefix"); - return; - } - dhcp_service_req_remove(srv_data_ptr->transActionId);// remove all pending retransmissions - addr_delete(cur, srv_data_ptr->iaNontemporalAddress.addressPrefix); - libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr); + + do { + if (cur == NULL || srv_data_ptr == NULL) { + return; + } + dhcp_service_req_remove(srv_data_ptr->transActionId);// remove all pending retransmissions + tr_debug("Deleting address: %s", trace_ipv6(srv_data_ptr->iaNontemporalAddress.addressPrefix)); + + addr_delete(cur, srv_data_ptr->iaNontemporalAddress.addressPrefix); + + libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr); + srv_data_ptr = libdhcpv6_nonTemporal_entry_get_by_prefix(interface, prefix); + } while (srv_data_ptr); + return; } @@ -306,7 +324,7 @@ void thread_dhcpv6_client_set_address(int8_t interface_id, dhcpv6_client_server_ if (address_entry == NULL) { tr_error("Address add failed"); - return ; + return; } if (renewTimer) { // translate seconds to 100ms ticks @@ -316,7 +334,6 @@ void thread_dhcpv6_client_set_address(int8_t interface_id, dhcpv6_client_server_ renewTimer = 0xfffffffe; } } - tr_debug("Added new address"); address_entry->state_timer = renewTimer; address_entry->cb = thread_dhcpv6_renew; } From c25df78625cc0f471584653ed537f7de79f758c9 Mon Sep 17 00:00:00 2001 From: Tero Heinonen Date: Thu, 19 Apr 2018 15:01:52 +0300 Subject: [PATCH 40/52] Fix for Router advertisement process in REED (#1658) Process router advertisements in REED mode, and merge partitions if needed. --- source/6LoWPAN/Thread/thread_bootstrap.c | 12 +++++---- .../Thread/thread_mle_message_handler.c | 26 ++++--------------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index eb04b72e2383..8f8ec3059423 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -325,11 +325,7 @@ int thread_bootstrap_partition_process(protocol_interface_info_entry_t *cur, uin tr_debug("Dropping advertisement from old partition without sequence number increase"); return -2; } - if (heard_partition_routers == 0 && active_routers == 1) { - //heard a REED and I am in a singleton partition so merge - tr_debug("Heard a REED and I am a singleton - merge"); - return 2; - } + /*Rule 0: If we are going to form Higher partition than heard we dont try to attach to lower ones */ if (thread_extension_enabled(cur) && @@ -343,6 +339,12 @@ int thread_bootstrap_partition_process(protocol_interface_info_entry_t *cur, uin } } + if ((heard_partition_routers == 0 && active_routers == 1) && thread_am_router(cur)) { + //heard a REED and I am a lonely router in a singleton partition, so merge + tr_debug("Heard a REED and I am a singleton - merge"); + return 2; + } + //Rule 1: A non-singleton Thread Network Partition always has higher priority than a singleton Thread Network Partition if (heard_partition_routers > 1 && active_routers == 1) { tr_debug("Heard a nonsingleton and i am a singleton"); diff --git a/source/6LoWPAN/Thread/thread_mle_message_handler.c b/source/6LoWPAN/Thread/thread_mle_message_handler.c index 1d13af747563..fee1e2235038 100644 --- a/source/6LoWPAN/Thread/thread_mle_message_handler.c +++ b/source/6LoWPAN/Thread/thread_mle_message_handler.c @@ -249,25 +249,6 @@ static bool thread_heard_lower_partition(protocol_interface_info_entry_t *cur, t return false; } -static bool thread_reed_partitions_merge(protocol_interface_info_entry_t *cur, uint16_t shortAddress, thread_leader_data_t heard_partition_leader_data) -{ - if (thread_is_router_addr(shortAddress)) { - return false; - } - // lower weighting heard - if (thread_info(cur)->thread_leader_data->weighting > heard_partition_leader_data.weighting) { - return false; - } - // lower/same partition id heard - if (thread_info(cur)->thread_leader_data->weighting == heard_partition_leader_data.weighting && - thread_info(cur)->thread_leader_data->partitionId >= heard_partition_leader_data.partitionId ) { - return false; - } - // can merge to a higher weighting/partition id - thread_bootstrap_connection_error(cur->id, CON_ERROR_PARTITION_MERGE, NULL); - return true; -} - 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) { //Read Leader Data and verify connectivity @@ -401,10 +382,13 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle } /* Advertisement from higher / lower partition */ } else { - // process REED advertisement from higher partition - if (thread_reed_partitions_merge(cur, shortAddress, leaderData)) { + // Check if better partition is heard + if (thread_bootstrap_partition_process(cur, thread_get_router_count_from_route_tlv(&routeTlv), &leaderData, &routeTlv) > 0) { + tr_debug("Start Merge"); + thread_bootstrap_connection_error(cur->id, CON_ERROR_PARTITION_MERGE, NULL); return; } + // REED advertisement to lower partition to help merge faster if (thread_heard_lower_partition(cur,leaderData)) { thread_router_bootstrap_reed_merge_advertisement(cur); From 58a60e7bff26ef19c9c88a543319d352447787bf Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Tue, 24 Apr 2018 12:53:52 +0300 Subject: [PATCH 41/52] address query logic implemented(#1667) --- source/6LoWPAN/Thread/thread_extension_bbr.c | 120 ++++++++++++------ source/6LoWPAN/Thread/thread_extension_bbr.h | 4 +- source/6LoWPAN/Thread/thread_nd.c | 6 +- .../6LoWPAN/Thread/thread_resolution_server.c | 5 +- .../6LoWPAN/Thread/thread_resolution_server.h | 2 +- 5 files changed, 92 insertions(+), 45 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.c b/source/6LoWPAN/Thread/thread_extension_bbr.c index f6fafc33371d..aac821a344bd 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.c +++ b/source/6LoWPAN/Thread/thread_extension_bbr.c @@ -229,7 +229,7 @@ static void thread_border_router_bb_ans_send(thread_pbbr_t *this, uint8_t *desti return; } -static void thread_border_router_bb_qry_send(thread_pbbr_t *this, uint8_t *target_eid_ptr, uint16_t *rloc_ptr) +static void thread_border_router_bb_qry_send(thread_pbbr_t *this, const uint8_t *target_eid_ptr, uint16_t *rloc_ptr) { uint8_t *ptr; uint8_t payload[22]; @@ -446,7 +446,7 @@ static int thread_pbbr_bb_qry_cb(int8_t service_id, uint8_t source_address[16], if (!link_configuration_ptr || !cur) { return -1; } - if (addr_is_assigned_to_interface(cur,source_address)) { + if (addr_interface_address_compare(cur, source_address) == 0) { // Received from own address no need to process return 0; } @@ -473,15 +473,57 @@ static int thread_pbbr_bb_qry_cb(int8_t service_id, uint8_t source_address[16], return 0; } + +static int thread_pbbr_dua_duplicate_address_detection(int8_t service_id, uint8_t *addr_data_ptr, uint8_t *ml_eid_ptr) +{ + thread_pbbr_t *this = thread_border_router_find_by_service(service_id); + + if (!this) { + return -1; + } + + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); + duplicate_dua_tr_t *tr_ptr = thread_border_router_dup_tr_find(this->interface_id,addr_data_ptr); + + if (!tr_ptr) { + return -1; + } + + ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, this->interface_id, NULL); + if (!route || route->prefix_len != 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_HOST) { + // Not found + tr_debug("route not found"); + return 0; + } + + // We have pending request and received answer + if (memcmp(ml_eid_ptr,tr_ptr->ml_eid, 8) != 0){ + // Different ml_eid but same address means duplicate address detected + thread_resolution_client_address_error(this->interface_id, tr_ptr->source_address, tr_ptr->target_eid, tr_ptr->ml_eid); + ipv6_neighbour_t *neighbour_entry; + neighbour_entry = ipv6_neighbour_lookup(&cur->ipv6_neighbour_cache, tr_ptr->target_eid); + if (neighbour_entry) { + tr_debug("Remove from neigh Cache: %s", tr_ipv6(tr_ptr->target_eid)); + ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour_entry); + } + ipv6_route_delete(route->prefix, route->prefix_len, this->interface_id, route->info.next_hop_addr, ROUTE_THREAD_PROXIED_HOST); + } + return 0; + + // TODO check last transaction time for migrated device if this answer is newer delete entry + // ipv6_route_delete(route->prefix, route->prefix_len, this->interface_id, route->info.next_hop_addr, ROUTE_THREAD_PROXIED_HOST); +} + static int thread_pbbr_bb_ans_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) { (void)service_id; (void)source_port; (void)request_ptr; - uint16_t addr_len, ml_eid_len, last_transaction_time_len, network_name_len; + uint16_t addr_len, ml_eid_len, last_transaction_time_len; uint8_t *addr_data_ptr; + uint16_t rloc16; + uint8_t destination_address[16] = {0}; uint8_t *ml_eid_ptr; - uint8_t *network_name_ptr; uint32_t last_transaction_time; tr_info("Thread BBR BB_ANS.ntf receive"); thread_pbbr_t *this = thread_border_router_find_by_service(service_id); @@ -495,7 +537,7 @@ static int thread_pbbr_bb_ans_cb(int8_t service_id, uint8_t source_address[16], if (!link_configuration_ptr || !cur) { return -1; } - if (addr_is_assigned_to_interface(cur,source_address)) { + if (addr_interface_address_compare(cur, source_address) == 0) { // Received from own address no need to process return 0; } @@ -503,46 +545,43 @@ static int thread_pbbr_bb_ans_cb(int8_t service_id, uint8_t source_address[16], addr_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_TARGET_EID, &addr_data_ptr); ml_eid_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_ML_EID, &ml_eid_ptr); last_transaction_time_len = thread_meshcop_tlv_data_get_uint32(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_LAST_TRANSACTION_TIME, &last_transaction_time); - network_name_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_LAST_TRANSACTION_TIME, &network_name_ptr); if ( addr_len < 16|| ml_eid_len < 8 || last_transaction_time_len < 4 ) { tr_err("Invalid message"); return 0; } - // Network name must match - if(stringlen((char *)link_configuration_ptr->name,16) != network_name_len || memcmp(link_configuration_ptr->name,network_name_ptr,network_name_len) != 0) { + if ((thread_pbbr_dua_duplicate_address_detection(service_id, addr_data_ptr, ml_eid_ptr) == 0)) { return 0; } - ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, this->interface_id, NULL); - if (!route || route->prefix_len != 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_HOST) { - // Not found + // If rloc16 is present then a/an is sent to the thread device with the rloc + if (thread_tmfcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_RLOC16, &rloc16) != 2) { return 0; } - duplicate_dua_tr_t *tr_ptr = thread_border_router_dup_tr_find(this->interface_id,addr_data_ptr); - if (tr_ptr) { - // We have pending request and received answer - if (memcmp(ml_eid_ptr,tr_ptr->ml_eid, 8) != 0){ - // Different ml_eid but same address means duplicate address detected - thread_resolution_client_address_error(this->interface_id, tr_ptr->source_address, tr_ptr->target_eid, tr_ptr->ml_eid); - ipv6_neighbour_t *neighbour_entry; - neighbour_entry = ipv6_neighbour_lookup(&cur->ipv6_neighbour_cache, tr_ptr->target_eid); - if (neighbour_entry) { - tr_debug("Remove from neigh Cache: %s", tr_ipv6(tr_ptr->target_eid)); - ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour_entry); - } - ipv6_route_delete(route->prefix, route->prefix_len, this->interface_id, route->info.next_hop_addr, ROUTE_THREAD_PROXIED_HOST); - } else { - // Roaming case lets inform other pbbr that we have newest - thread_border_router_bb_ans_send(this, source_address, tr_ptr->target_eid, tr_ptr->ml_eid, 0, link_configuration_ptr->name, NULL); - } - } else { - ipv6_route_delete(route->prefix, route->prefix_len, this->interface_id, route->info.next_hop_addr, ROUTE_THREAD_PROXIED_HOST); - } + // form the destination address to which the a/an is sent + thread_addr_write_mesh_local_16(destination_address, rloc16, cur->thread_info); - // If delayed DUA registration entry is present send duplicate error code to DUA.response + // Address query pending send address notification, include tlvs: target eid, rloc16 tlv of bbr, mleid, and last transaction time + uint8_t payload[16 + 2 + 8 + 4]; // Target eid + Rloc16 + MLEID + transaction time + uint8_t *ptr; + ptr = payload; + ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_TARGET_EID, 16, addr_data_ptr); + ptr = thread_tmfcop_tlv_data_write_uint16(ptr, TMFCOP_TLV_RLOC16, cur->thread_info->routerShortAddress); + ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_ML_EID, 8, ml_eid_ptr); + ptr = thread_tmfcop_tlv_data_write_uint32(ptr, TMFCOP_TLV_LAST_TRANSACTION_TIME, last_transaction_time); + + // XXX "Accepted" response? + + /* We don't require a response, so we don't specify a callback. Library + * should retry itself until it gets an ACK. + */ + coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_ADDRESS_SHORT, + destination_address, THREAD_MANAGEMENT_PORT, + COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, + THREAD_URI_ADDRESS_NOTIFICATION, COAP_CT_OCTET_STREAM, + payload, ptr - payload, NULL); return 0; } static int thread_extension_bbr_bmlr_req_send(int8_t service_id, const uint8_t br_addr[16], const uint8_t *address_ptr, uint8_t addr_len, uint32_t timeout) @@ -997,7 +1036,7 @@ void thread_extension_bbr_delete(int8_t interface_id) ns_dyn_mem_free(this); } -bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur, const uint8_t *target_addr) +bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur, const uint8_t *target_addr, uint16_t rloc) { uint8_t domain_prefix[8]; if (thread_version < THREAD_VERSION_1_2) { @@ -1010,12 +1049,17 @@ bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur, if (!this->pbbr_started) { return false; } - // if we have DUA addressing enabled - if ( thread_extension_network_prefix_get(cur->id, NULL, domain_prefix, NULL) == 0 && - bitsequal(domain_prefix,target_addr,64) ) { - return true; + // if we do not have DUA addressing enabled + if ( !thread_extension_network_prefix_get(cur->id, NULL, domain_prefix, NULL) == 0 || + !bitsequal(domain_prefix,target_addr,64) ) { + return false; + } - return false; + + // SEND BB_QRY + thread_border_router_bb_qry_send(this,target_addr,&rloc); + return true; + } diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.h b/source/6LoWPAN/Thread/thread_extension_bbr.h index 879e7a569c19..114d9fad9a4a 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.h +++ b/source/6LoWPAN/Thread/thread_extension_bbr.h @@ -41,7 +41,7 @@ extern "C" { #ifdef HAVE_THREAD_V2 int8_t thread_extension_bbr_init(int8_t interface_id, int8_t backbone_interface_id); void thread_extension_bbr_delete(int8_t interface_id); -bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur, const uint8_t *target_addr); +bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur, const uint8_t *target_addr, uint16_t rloc); void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds); int thread_extension_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t timeout_b, uint32_t delay); int thread_extension_bbr_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port); @@ -51,7 +51,7 @@ int thread_extension_bbr_address_set(int8_t interface_id, const uint8_t *addr_pt #define thread_extension_bbr_init(interface_id, backbone_interface_id) #define thread_extension_bbr_delete(interface_id) -#define thread_extension_bbr_nd_query_process(cur, target_addr) false +#define thread_extension_bbr_nd_query_process(cur, target_addr, rloc) false #define thread_extension_bbr_seconds_timer(interface_id, seconds) #define thread_extension_bbr_timeout_set(interface_id, timeout_a, timeout_b, delay) #define thread_extension_bbr_address_set(interface_id, addr_ptr, port) (-1) diff --git a/source/6LoWPAN/Thread/thread_nd.c b/source/6LoWPAN/Thread/thread_nd.c index 0ce0d26aa565..4c9a5af39184 100644 --- a/source/6LoWPAN/Thread/thread_nd.c +++ b/source/6LoWPAN/Thread/thread_nd.c @@ -209,7 +209,7 @@ static mle_neigh_table_entry_t *thread_nd_child_mleid_get(int8_t interface_id, u return NULL; } -static int thread_nd_address_query_lookup(int8_t interface_id, const uint8_t target_addr[static 16], uint16_t *addr_out, bool *proxy, uint32_t *last_transaction_time, uint8_t *mleid_ptr) +static int thread_nd_address_query_lookup(int8_t interface_id, const uint8_t target_addr[static 16], uint16_t *rloc, uint16_t *addr_out, bool *proxy, uint32_t *last_transaction_time, uint8_t *mleid_ptr) { protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); if (!cur) { @@ -260,8 +260,8 @@ static int thread_nd_address_query_lookup(int8_t interface_id, const uint8_t tar can_route_of_mesh = true; } - if (thread_extension_bbr_nd_query_process(cur,target_addr)) { - can_route_of_mesh = true; + if (thread_extension_bbr_nd_query_process(cur,target_addr, *rloc)){ + return -1; } if (can_route_of_mesh) { diff --git a/source/6LoWPAN/Thread/thread_resolution_server.c b/source/6LoWPAN/Thread/thread_resolution_server.c index 1440c48a5e65..292b7ca84366 100644 --- a/source/6LoWPAN/Thread/thread_resolution_server.c +++ b/source/6LoWPAN/Thread/thread_resolution_server.c @@ -91,6 +91,7 @@ static int thread_resolution_server_query_cb(int8_t service_id, uint8_t source_a uint8_t mlEID[8]; bool proxy; uint16_t rloc16; + uint16_t requestor_rloc; uint32_t last_transaction_time = 0; uint8_t *ptr; (void)source_port; @@ -118,9 +119,11 @@ static int thread_resolution_server_query_cb(int8_t service_id, uint8_t source_a return -1; } + requestor_rloc = common_read_16_bit(source_address + 14); + tr_debug("Thread address query %s", trace_ipv6(target_ip_ptr)); - int ret = this->query_cb_ptr(this->interface_id, target_ip_ptr, &rloc16, &proxy, &last_transaction_time, mlEID); + int ret = this->query_cb_ptr(this->interface_id, target_ip_ptr, &requestor_rloc, &rloc16, &proxy, &last_transaction_time, mlEID); if (ret < 0) { /* XXX "Forbidden" response? */ return -1; diff --git a/source/6LoWPAN/Thread/thread_resolution_server.h b/source/6LoWPAN/Thread/thread_resolution_server.h index 047538aa3f1b..a3795a1867c9 100644 --- a/source/6LoWPAN/Thread/thread_resolution_server.h +++ b/source/6LoWPAN/Thread/thread_resolution_server.h @@ -58,7 +58,7 @@ extern "C" { * * /return return 0 for success, negative if unable to respond. */ -typedef int thread_resolution_server_addr_query_cb(int8_t interface_id, const uint8_t target_addr[static 16], uint16_t *addr_out, bool *proxy, uint32_t *last_transaction_time, uint8_t *mleid_ptr); +typedef int thread_resolution_server_addr_query_cb(int8_t interface_id, const uint8_t target_addr[static 16], uint16_t *rloc, uint16_t *addr_out, bool *proxy, uint32_t *last_transaction_time, uint8_t *mleid_ptr); #ifdef HAVE_THREAD_NEIGHBOR_DISCOVERY From 934687b85dd5cfe0eda4e3e59d83e3e76bec2d35 Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Mon, 23 Apr 2018 13:37:14 +0300 Subject: [PATCH 42/52] Tighten core "for us" check for unicast addresses Basic "is this packet for us" check was special-cased for link-local addresses, but had no other scope handling. Tighten this up to apply the scope zones already configured in the interfaces and used for packet forwarding. We now only accept a packet on interface B for an address configured on interface A if A and B are in the same scope zone for that address. Main visible impact will be that Thread border routers will no longer accept mesh-local addresses on the Ethernet interface. Change-Id: Ib79526f1ada36fa409378b4824315221cc543321 --- source/Core/address.c | 15 +++++++++------ source/Core/ns_socket.c | 2 +- source/NWK_INTERFACE/Include/protocol.h | 2 +- source/NWK_INTERFACE/protocol_core.c | 8 +++++--- source/RPL/rpl_control.c | 2 +- source/RPL/rpl_downward.c | 4 ++-- source/libNET/src/socket_api.c | 2 +- test/nanostack/unittest/stub/protocol_core_stub.c | 2 +- 8 files changed, 21 insertions(+), 16 deletions(-) diff --git a/source/Core/address.c b/source/Core/address.c index 395a0e4be705..443aa270dc33 100644 --- a/source/Core/address.c +++ b/source/Core/address.c @@ -1354,14 +1354,17 @@ int8_t addr_interface_address_compare(protocol_interface_info_entry_t *cur, cons return 0; } - /* If link-local, that's it */ - if (addr_is_ipv6_link_local(addr)) { - return -1; + /* Then check other interfaces, enforcing scope zones */ + uint_fast8_t scope = addr_ipv6_scope(addr, cur); + ns_list_foreach(protocol_interface_info_entry_t, other, &protocol_interface_info_list) { + if (other != cur && + other->zone_index[scope] == cur->zone_index[scope] && + addr_is_assigned_to_interface(other, addr)) { + return 0; + } } - /* Now check other interfaces */ - /* TODO: should only do this if both current and other interface have forwarding enabled */ - return protcol_interface_address_compare(cur, addr); + return -1; } int8_t addr_interface_select_source(protocol_interface_info_entry_t *cur, uint8_t *src_ptr, const uint8_t *dest, uint32_t addr_preferences) diff --git a/source/Core/ns_socket.c b/source/Core/ns_socket.c index 08f5fd4173d9..01f7fe2360ec 100644 --- a/source/Core/ns_socket.c +++ b/source/Core/ns_socket.c @@ -1301,7 +1301,7 @@ int16_t socket_buffer_sendmsg(int8_t sid, buffer_t *buf, const struct ns_msghdr * address is valid in one of the available interfaces * */ if (buf->src_sa.addr_type == ADDR_IPV6 && - protcol_interface_address_compare(NULL, buf->src_sa.address) != 0) { + protocol_interface_address_compare(buf->src_sa.address) != 0) { tr_warn("Specified source address %s is not valid",trace_ipv6(buf->src_sa.address)); ret_val = -3; goto fail; diff --git a/source/NWK_INTERFACE/Include/protocol.h b/source/NWK_INTERFACE/Include/protocol.h index c2bb96fabd7d..1e7290c1184d 100644 --- a/source/NWK_INTERFACE/Include/protocol.h +++ b/source/NWK_INTERFACE/Include/protocol.h @@ -507,5 +507,5 @@ extern void protocol_core_dhcpv6_allocated_address_remove(protocol_interface_inf extern void nwk_bootsrap_state_update(arm_nwk_interface_status_type_e posted_event, protocol_interface_info_entry_t *cur); void bootsrap_next_state_kick(icmp_state_t new_state, protocol_interface_info_entry_t *cur); -int8_t protcol_interface_address_compare(protocol_interface_info_entry_t *cur, const uint8_t *addr); +int8_t protocol_interface_address_compare(const uint8_t *addr); #endif /* _NS_PROTOCOL_H */ diff --git a/source/NWK_INTERFACE/protocol_core.c b/source/NWK_INTERFACE/protocol_core.c index 4590ef324e45..2950b79964e3 100644 --- a/source/NWK_INTERFACE/protocol_core.c +++ b/source/NWK_INTERFACE/protocol_core.c @@ -1085,10 +1085,12 @@ void protocol_core_dhcpv6_allocated_address_remove(protocol_interface_info_entry } } -int8_t protcol_interface_address_compare(protocol_interface_info_entry_t *cur, const uint8_t *addr) +/* XXX note that this does not perform any scope checks, so will for example match + * link local addresses on any interface - you may want addr_interface_address_compare */ +int8_t protocol_interface_address_compare(const uint8_t *addr) { - ns_list_foreach(protocol_interface_info_entry_t, other, &protocol_interface_info_list) { - if (other != cur && addr_is_assigned_to_interface(other, addr)) { + ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { + if (addr_is_assigned_to_interface(cur, addr)) { return 0; } } diff --git a/source/RPL/rpl_control.c b/source/RPL/rpl_control.c index 229eade4bc63..703f81c261f7 100644 --- a/source/RPL/rpl_control.c +++ b/source/RPL/rpl_control.c @@ -855,7 +855,7 @@ static buffer_t *rpl_control_dio_handler(protocol_interface_info_entry_t *cur, r } /* Even if we're not currently rooting - what if it's our address? Ignore stale info on network */ - if (protcol_interface_address_compare(NULL, dodagid) == 0) { + if (addr_interface_address_compare(cur, dodagid) == 0) { tr_info("DIO our DODAGID %s", trace_ipv6(dodagid)); /* Should we transmit poison? */ goto invalid_parent; diff --git a/source/RPL/rpl_downward.c b/source/RPL/rpl_downward.c index 2f7d9c95d46c..d9c98dc63d8c 100644 --- a/source/RPL/rpl_downward.c +++ b/source/RPL/rpl_downward.c @@ -1059,7 +1059,7 @@ static bool rpl_downward_process_targets_for_transit(rpl_dodag_t *dodag, bool st /* In Non-Storing mode, add the transit to the target, and we'll re-evaluate system routes later */ ipv6_route_table_remove_info(-1, ROUTE_RPL_DAO_SR, target); if (transit_opt) { - if (protcol_interface_address_compare(NULL, parent) == 0) { + if (protocol_interface_address_compare(parent) == 0) { /* If we're transit, it's on-link */ ipv6_route_add_with_info(prefix, prefix_len, interface_id, NULL, ROUTE_RPL_DAO_SR, target, 0, target->lifetime, 0); } else { @@ -1122,7 +1122,7 @@ static void rpl_downward_link_transits_to_targets(rpl_instance_t *instance) } ns_list_foreach(rpl_dao_target_t, target, &instance->dao_targets) { ns_list_foreach(rpl_dao_root_transit_t, transit, &target->info.root.transits) { - if (protcol_interface_address_compare(NULL, transit->transit) == 0) { + if (protocol_interface_address_compare(transit->transit) == 0) { /* It points to us (the DODAG root) - mark this with NULL */ transit->parent = NULL; target->connected = true; diff --git a/source/libNET/src/socket_api.c b/source/libNET/src/socket_api.c index f0989a4525fd..84d5383ba091 100644 --- a/source/libNET/src/socket_api.c +++ b/source/libNET/src/socket_api.c @@ -656,7 +656,7 @@ int8_t socket_bind(int8_t socket, const ns_address_t *address) return -4; } - if (protcol_interface_address_compare(NULL, address->address) != 0) { + if (protocol_interface_address_compare(address->address) != 0) { return -3; } diff --git a/test/nanostack/unittest/stub/protocol_core_stub.c b/test/nanostack/unittest/stub/protocol_core_stub.c index af42ce01f4a4..ba2c1e9a9273 100644 --- a/test/nanostack/unittest/stub/protocol_core_stub.c +++ b/test/nanostack/unittest/stub/protocol_core_stub.c @@ -234,7 +234,7 @@ void protocol_core_dhcpv6_allocated_address_remove(protocol_interface_info_entry { } -int8_t protcol_interface_address_compare(protocol_interface_info_entry_t *cur, const uint8_t *addr) +int8_t protocol_interface_address_compare(const uint8_t *addr) { return protocol_core_stub.int8_value; } From 1584759dded2786515e64807ac62eeb130123e91 Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Mon, 23 Apr 2018 16:16:54 +0300 Subject: [PATCH 43/52] Extra Thread-specific address check handling Normal scope rules aren't sufficient for the Thread mesh-local address. Add special handling. --- source/Core/address.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/Core/address.c b/source/Core/address.c index 443aa270dc33..31b4434e75fb 100644 --- a/source/Core/address.c +++ b/source/Core/address.c @@ -1360,6 +1360,12 @@ int8_t addr_interface_address_compare(protocol_interface_info_entry_t *cur, cons if (other != cur && other->zone_index[scope] == cur->zone_index[scope] && addr_is_assigned_to_interface(other, addr)) { + // special handling for Thread - external global-scope ULA coming in, + // which would match, but we need to restrict if that ULA is mesh-local + // on the Thread side. + if (thread_info(other) && addr_ipv6_scope(addr, other) <= IPV6_SCOPE_REALM_LOCAL) { + continue; + } return 0; } } From 073f7e8fe7576b3303fab813188e568d4de22adb Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Wed, 25 Apr 2018 09:15:24 +0300 Subject: [PATCH 44/52] entry keep alive flag set to true if entry already exists. (#1675) --- source/6LoWPAN/Thread/thread_extension_bbr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.c b/source/6LoWPAN/Thread/thread_extension_bbr.c index aac821a344bd..9e9122702995 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.c +++ b/source/6LoWPAN/Thread/thread_extension_bbr.c @@ -776,13 +776,13 @@ static int thread_extension_bbr_dua_cb(int8_t service_id, uint8_t source_address tr_debug("DUA.req addr:%s ml_eid:%s", trace_array(addr_data_ptr, addr_len), trace_array(ml_eid_ptr, ml_eid_len)); - entry_keep_alive = true; + entry_keep_alive = false; // TODO add ml_eid to structure saved in info pointer to detect duplicates if (thread_bbr_nd_entry_find(this->interface_id, addr_data_ptr) == 0) { - entry_keep_alive = false; + entry_keep_alive = true; } - if (thread_bbr_nd_entry_add(this->interface_id, addr_data_ptr, 0xFFFFFFFF, NULL, ml_eid_ptr) == -1) { + if (thread_bbr_nd_entry_add(this->interface_id, addr_data_ptr, 0xFFFFFFFF, NULL, ml_eid_ptr) != 0) { bbr_status = THREAD_BBR_STATUS_RESOURCE_SHORTAGE; goto send_response; } From feb1784d60726c2fe73871ac711b774534f3bb3f Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Wed, 25 Apr 2018 17:12:02 +0300 Subject: [PATCH 45/52] Remove fragment/PMTU handling dropped by RFC 8200 The new IPv6 specification (RFC 8200 / STD 86) drops some IPv6 features, so we can simplify. We now drop ICMP "Packet Too Big" messages reporting a size less than the minimum 1280 MTU, and we won't create atomic fragments with fragment headers in response to them. Change-Id: I38451ca13842b9c5b89a2f95c4793a326dacae23 --- source/Common_Protocols/icmpv6.c | 5 +++ source/Common_Protocols/ipv6_fragmentation.c | 36 ++------------------ 2 files changed, 7 insertions(+), 34 deletions(-) diff --git a/source/Common_Protocols/icmpv6.c b/source/Common_Protocols/icmpv6.c index dec3f280be26..cf11bb8c893a 100644 --- a/source/Common_Protocols/icmpv6.c +++ b/source/Common_Protocols/icmpv6.c @@ -280,6 +280,11 @@ buffer_t *icmpv6_packet_too_big_handler(buffer_t *buf) const uint8_t *ptr = buffer_data_pointer(buf); uint32_t mtu = common_read_32_bit(ptr); + /* RFC 8201 - ignore MTU smaller than minimum */ + if (mtu < IPV6_MIN_LINK_MTU) { + return buffer_free(buf); + } + ptr = buffer_data_strip_header(buf, 4); /* Check source is us */ diff --git a/source/Common_Protocols/ipv6_fragmentation.c b/source/Common_Protocols/ipv6_fragmentation.c index bc265b1ba999..13169a0c191b 100644 --- a/source/Common_Protocols/ipv6_fragmentation.c +++ b/source/Common_Protocols/ipv6_fragmentation.c @@ -21,15 +21,12 @@ * References: * * RFC 815 IP Datagram Reassembly Algorithms - * RFC 2460 Internet Protocol. Version 6 (IPv6) Specification * RFC 3168 The Addition of Explicit Congestion Notification (ECN) to IP - * RFC 5722 Handling of Overlapping IPv6 Fragments * RFC 6040 Tunnelling of Explicit Congestion Notification - * RFC 6145 IP/ICMP Translation Algorithm [sections on Path MTU] * RFC 6660 Encoding Three Pre-Congestion Notification (PCN) States in the * IP Header Using a Single Diffserv Codepoint (DSCP) - * RFC 6946 Processing of IPv6 "Atomic" Fragments - * RFC 7112 Implications of Oversized IPv6 Header Chains + * RFC 8200 Internet Protocol, Version 6 (IPv6) Specification + * RFC 8201 Path MTU Discovery for IP version 6 */ #include "nsconfig.h" #include "ns_types.h" @@ -656,35 +653,6 @@ buffer_t *ipv6_frag_down(buffer_t *dgram_buf) *nh_ptr = IPV6_NH_FRAGMENT; - /* Special case for atomic fragments (caused by a small PMTU) */ - /* Note that we DO have the option of actually fragmenting and obeying - * a small PMTU, which would avoid this special case. - */ - if (buffer_data_length(dgram_buf) <= IPV6_MIN_LINK_MTU - 8) { - dgram_buf = buffer_headroom(dgram_buf, 8); - if (!dgram_buf) { - return NULL; - } - - /* Move unfragmentable section back 8 bytes; increase IP length field */ - ip_ptr = buffer_data_reserve_header(dgram_buf, 8); - memmove(ip_ptr, ip_ptr + 8, unfrag_len); - common_write_16_bit(common_read_16_bit(ip_ptr + 4) + 8, ip_ptr + 4); - - /* Write atomic fragment header into the gap */ - frag_hdr = ip_ptr + unfrag_len; - frag_hdr[0] = nh; - frag_hdr[1] = 0; - common_write_16_bit(0, frag_hdr + 2); - common_write_32_bit(++dest->fragment_id, frag_hdr + 4); - return dgram_buf; - } - - /* We won't fragment below minimum MTU. (Although we could...) */ - if (pmtu < IPV6_MIN_LINK_MTU) { - pmtu = IPV6_MIN_LINK_MTU; - } - /* Check for silly situation - can't fit any fragment data (8 for fragment * header, 8 for minimum fragment payload) */ if (unfrag_len + 8 + 8 > pmtu) { From 389fab0ce928b603552e97885dfd84181914c539 Mon Sep 17 00:00:00 2001 From: Tero Heinonen Date: Thu, 26 Apr 2018 12:52:16 +0300 Subject: [PATCH 46/52] MLE parent request timeout fixes (#1676) - More exact timeout values for parent request timeouts - Added delay for parent request send --- source/6LoWPAN/Thread/thread_config.h | 9 +++++++ source/6LoWPAN/Thread/thread_host_bootstrap.c | 15 +++++++---- source/Service_Libs/mle_service/mle_service.c | 27 ++++++++++++++++--- .../mle_service/mle_service_api.h | 17 +++++++++--- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_config.h b/source/6LoWPAN/Thread/thread_config.h index 55243dc4a83f..06eae38323f2 100644 --- a/source/6LoWPAN/Thread/thread_config.h +++ b/source/6LoWPAN/Thread/thread_config.h @@ -307,6 +307,15 @@ */ #define THREAD_PROACTIVE_AN_SEND_DELAY 2 +/* + * Parent response wait time (in 100ms) when "R" bit is set in scan mask TLV (rounded up from 0.75 seconds) + */ +#define THREAD_PARENT_REQ_SCANMASK_R_TIMEOUT 9 + +/* + * Parent response wait time (in 100ms) when both "R" and "E" bit is set in scan mask TLV (rounded up from 1.25 seconds) + */ +#define THREAD_PARENT_REQ_SCANMASK_RE_TIMEOUT 15 /** * Build time flag to enable THCI special traces for test harness purposes */ diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index fd384af728e2..82f27dcc9eec 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -227,13 +227,20 @@ static int thread_parent_request_build(protocol_interface_info_entry_t *cur) return -1; } + timeout.retrans_max = THREAD_PARENT_REQUEST_MAX_RETRY_CNT; + timeout.timeout_init = THREAD_PARENT_REQ_SCANMASK_R_TIMEOUT; + timeout.timeout_max = THREAD_PARENT_REQ_SCANMASK_RE_TIMEOUT; + timeout.delay = MLE_STANDARD_RESPONSE_DELAY; + if (cur->thread_info->thread_attached_state == THREAD_STATE_REATTACH || cur->thread_info->thread_attached_state == THREAD_STATE_REATTACH_RETRY || cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED || cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) { // When doing re-attach End devices are immediately accepted as parents scanMask |= 0x40; + timeout.timeout_init = THREAD_PARENT_REQ_SCANMASK_RE_TIMEOUT; } + thread_management_get_current_keysequence(cur->id, &keySequence); mle_service_msg_update_security_params(buf_id, 5, 2, keySequence); @@ -256,11 +263,9 @@ static int thread_parent_request_build(protocol_interface_info_entry_t *cur) if (mle_service_update_length_by_ptr(buf_id,ptr)!= 0) { tr_debug("Buffer overflow at message write"); } - timeout.retrans_max = THREAD_PARENT_REQUEST_MAX_RETRY_CNT; - timeout.timeout_init = 1; - timeout.timeout_max = 2; - timeout.delay = MLE_NO_DELAY; + cur->nwk_nd_re_scan_count = 1; + mle_service_set_packet_callback(buf_id, thread_parent_discover_timeout_cb); if (cur->thread_info->thread_attached_state == THREAD_STATE_NETWORK_DISCOVER) { mle_service_interface_receiver_handler_update(cur->id, thread_mle_parent_discover_receive_cb); @@ -268,7 +273,7 @@ static int thread_parent_request_build(protocol_interface_info_entry_t *cur) mle_service_interface_receiver_handler_update(cur->id, thread_general_mle_receive_cb); } - mle_service_set_msg_timeout_parameters(buf_id, &timeout); + mle_service_set_msg_timeout_parameters_fast(buf_id, &timeout); mle_service_send_message(buf_id); return 0; } diff --git a/source/Service_Libs/mle_service/mle_service.c b/source/Service_Libs/mle_service/mle_service.c index 88394d02aae7..45c5c081d3e8 100644 --- a/source/Service_Libs/mle_service/mle_service.c +++ b/source/Service_Libs/mle_service/mle_service.c @@ -1210,7 +1210,7 @@ int mle_service_message_tail_get(uint16_t msgId, uint16_t tail_length) return mle_service_buffer_tail_get(msgId,tail_length); } -int mle_service_set_msg_timeout_parameters(uint16_t msgId, mle_message_timeout_params_t *timeout_params) +static int mle_service_timeout_fill(uint16_t msgId, mle_message_timeout_params_t *timeout_params, bool timeout_in_seconds) { mle_service_msg_buf_t *buffer = mle_service_buffer_find(msgId); @@ -1218,14 +1218,33 @@ int mle_service_set_msg_timeout_parameters(uint16_t msgId, mle_message_timeout_p return -1; } - buffer->timeout_init = randLIB_randomise_base(timeout_params->timeout_init * 10, MLE_RAND_LOW, MLE_RAND_HIGH); - buffer->timeout = buffer->timeout_init; - buffer->timeout_max = timeout_params->timeout_max * 10; + buffer->timeout_max = timeout_params->timeout_max; buffer->retrans_max = timeout_params->retrans_max; buffer->delayed_response = timeout_params->delay; + buffer->timeout_init = timeout_params->timeout_init; + + if (timeout_in_seconds) { + buffer->timeout_max = buffer->timeout_max * 10; + buffer->timeout_init = buffer->timeout_init * 10; + } + + buffer->timeout_init = randLIB_randomise_base(buffer->timeout_init, MLE_RAND_LOW, MLE_RAND_HIGH); + + buffer->timeout = buffer->timeout_init; + return 0; } +int mle_service_set_msg_timeout_parameters(uint16_t msgId, mle_message_timeout_params_t *timeout_params) +{ + return mle_service_timeout_fill(msgId, timeout_params, true); +} + +int mle_service_set_msg_timeout_parameters_fast(uint16_t msgId, mle_message_timeout_params_t *timeout_params) +{ + return mle_service_timeout_fill(msgId, timeout_params, false); +} + int mle_service_set_msg_token_bucket_priority(uint16_t msgId) { mle_service_msg_buf_t *buffer = mle_service_buffer_find(msgId); diff --git a/source/Service_Libs/mle_service/mle_service_api.h b/source/Service_Libs/mle_service/mle_service_api.h index 00e61f217fd1..2efcf8e60131 100644 --- a/source/Service_Libs/mle_service/mle_service_api.h +++ b/source/Service_Libs/mle_service/mle_service_api.h @@ -126,8 +126,8 @@ typedef struct { * */ typedef struct { -uint16_t timeout_init; /*!< Define start timeout in seconds */ -uint16_t timeout_max; /*!< Define max timeout time in seconds */ +uint16_t timeout_init; /*!< Define start timeout */ +uint16_t timeout_max; /*!< Define max timeout time */ uint8_t retrans_max; /*!< Define max packet TX count */ uint8_t delay; /*!< 100ms Ticks for random delay */ } mle_message_timeout_params_t; @@ -583,7 +583,7 @@ int mle_service_set_msg_panid(uint16_t msgId, uint16_t panid); /** * Set messages timeout parameters. * -* Messages timeout parameters define messages TX count and init timeout and max timeout values is messages delayed. +* Struct timeout_params defines messages retransmission times in seconds, retransmission count and sending delay. * Delayed message will affect random time between 100-900ms * * \param msgId Message Id. @@ -591,6 +591,17 @@ int mle_service_set_msg_panid(uint16_t msgId, uint16_t panid); */ int mle_service_set_msg_timeout_parameters(uint16_t msgId, mle_message_timeout_params_t *timeout_params); +/** +* Set messages timeout parameters. +* +* Struct timeout_params defines messages retransmission times in 100ms, retransmission count and sending delay. +* Delayed message will affect random time between 100-900ms +* +* \param msgId Message Id. +* \param timeout_params messages transmission parameters +*/ +int mle_service_set_msg_timeout_parameters_fast(uint16_t msgId, mle_message_timeout_params_t *timeout_params); + int mle_service_set_msg_rf_channel(uint16_t msgId, uint8_t channel); int mle_service_set_msg_link_layer_security_mode(uint16_t msgId, bool use_key_id_mode_2); From f28cce8810b854b8952cafe355e19c908d9f1869 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Fri, 27 Apr 2018 15:47:44 +0300 Subject: [PATCH 47/52] pbbr route handling updated (#1681) --- source/6LoWPAN/Thread/thread_bbr_api.c | 2 +- source/6LoWPAN/Thread/thread_bootstrap.c | 3 ++ source/6LoWPAN/Thread/thread_extension.c | 16 +++---- source/6LoWPAN/Thread/thread_extension_bbr.c | 42 ++++++++++++++++--- source/6LoWPAN/Thread/thread_extension_bbr.h | 7 +++- source/ipv6_stack/ipv6_routing_table.h | 1 + .../unittest/stub/thread_extension_stub.c | 5 +++ 7 files changed, 57 insertions(+), 19 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bbr_api.c b/source/6LoWPAN/Thread/thread_bbr_api.c index acdaa2c45367..d3b7935fdf79 100644 --- a/source/6LoWPAN/Thread/thread_bbr_api.c +++ b/source/6LoWPAN/Thread/thread_bbr_api.c @@ -755,8 +755,8 @@ bool thread_bbr_routing_enabled(protocol_interface_info_entry_t *cur) void thread_bbr_network_data_update_notify(protocol_interface_info_entry_t *cur) { - (void) cur; thread_mdns_network_data_update_notify(); + thread_extension_bbr_route_update(cur); } #endif /* HAVE_THREAD_BORDER_ROUTER*/ diff --git a/source/6LoWPAN/Thread/thread_bootstrap.c b/source/6LoWPAN/Thread/thread_bootstrap.c index 8f8ec3059423..3f746d20d1a8 100644 --- a/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_bootstrap.c @@ -63,6 +63,7 @@ #include "6LoWPAN/Thread/thread_network_synch.h" #include "6LoWPAN/Thread/thread_joiner_application.h" #include "6LoWPAN/Thread/thread_extension.h" +#include "6LoWPAN/Thread/thread_extension_bbr.h" #include "6LoWPAN/Thread/thread_management_client.h" #include "6LoWPAN/Thread/thread_address_registration_client.h" #include "6LoWPAN/Thread/thread_joiner_application.h" @@ -681,6 +682,8 @@ int thread_configuration_thread_activate(protocol_interface_info_entry_t *cur, l thread_extension_activate(cur); + thread_extension_bbr_route_update(cur); + blacklist_clear(); blacklist_params_set( diff --git a/source/6LoWPAN/Thread/thread_extension.c b/source/6LoWPAN/Thread/thread_extension.c index d03d55244831..53c60e4f5bd1 100644 --- a/source/6LoWPAN/Thread/thread_extension.c +++ b/source/6LoWPAN/Thread/thread_extension.c @@ -192,17 +192,11 @@ void thread_extension_network_data_process(struct protocol_interface_info_entry } // Check if we are the BBR if we are make default route to backend if (0 == thread_extension_network_prefix_get(cur->id, NULL, domain_prefix, &domain_prefix_len)) { - if(addr_is_assigned_to_interface(cur, addr)) { - // pBBR does not have default route to mesh - tr_info("Hosting pBBR for DUA prefix"); - ipv6_route_delete(domain_prefix, domain_prefix_len, cur->id, NULL, ROUTE_THREAD); - } else { - // Routers and FEDs create on-mesh prefix for domain prefix - if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER || - cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE){ - if (ipv6_route_add(domain_prefix, domain_prefix_len, cur->id, NULL, ROUTE_THREAD, 0xffffffff, 0) == NULL) { - tr_error("fail to add domain prefix route"); - } + // Routers and FEDs create on-mesh prefix for domain prefix + if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER || + cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE){ + if (ipv6_route_add(domain_prefix, domain_prefix_len, cur->id, NULL, ROUTE_THREAD, 0xffffffff, 0) == NULL) { + tr_error("fail to add domain prefix route"); } } } diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.c b/source/6LoWPAN/Thread/thread_extension_bbr.c index 9e9122702995..2d96fe866da5 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.c +++ b/source/6LoWPAN/Thread/thread_extension_bbr.c @@ -59,8 +59,7 @@ #include "6LoWPAN/Thread/thread_extension_bbr.h" -#ifdef HAVE_THREAD_V2 -#ifdef HAVE_THREAD_BORDER_ROUTER +#if defined(HAVE_THREAD_V2) && defined(HAVE_THREAD_BORDER_ROUTER) #define TRACE_GROUP "pBBR" /* @@ -897,6 +896,8 @@ static int thread_extension_bbr_pbbr_stop(thread_pbbr_t *this) multicast_free_address(this->pbbr_multicast_address); multicast_fwd_full_for_scope(this->interface_id, IPV6_SCOPE_SITE_LOCAL); + ipv6_route_table_remove_info(this->backbone_interface_id, ROUTE_THREAD_BBR, NULL); + coap_service_unregister_uri(this->coap_service_id, THREAD_URI_BBR_TRI_RX_NTF); coap_service_unregister_uri(this->coap_service_id, THREAD_URI_BBR_NMK_RX_NTF); coap_service_unregister_uri(this->coap_service_id, THREAD_URI_BBR_DOMAIN_ADDRESS_REGISTRATION); @@ -952,7 +953,6 @@ static int thread_extension_bbr_pbbr_start(thread_pbbr_t *this) tr_info("pBBR service started (Commercial network)"); // Register Primary BBR backbone multicast address multicast_add_address(this->pbbr_multicast_address, false); - this->pbbr_started = true; // Register Backbone commercial features @@ -1062,6 +1062,38 @@ bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur, } +void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur) +{ + // if we have DUA prefix in settings + // if we are pbbr delete dua on-mesh route + // if we are pbbr add dua route to backbone + // else + // Remove all DUA routes using type + uint8_t addr[16]; + if (0 != thread_extension_primary_bbr_get(cur, addr, NULL, NULL, NULL)) { + // BBR not present + return; + } + if(!addr_is_assigned_to_interface(cur, addr)) { + return; + } + + thread_pbbr_t *this = thread_bbr_find_by_interface(cur->id); + if (!this) { + return; + } + // remove with info and add all valid doman prefixes again to back bone interface + ipv6_route_table_remove_info(this->backbone_interface_id, ROUTE_THREAD_BBR, NULL); + uint8_t domain_prefix[8]; + // Check if domain prefix is in settings and verify that configuration is made to backbone -> prefix on-link + if (0 == thread_extension_network_prefix_get(cur->id, NULL, domain_prefix, NULL)){ + // domain prefix in settings add dua route to backbone, delete dua on-mesh route + tr_debug("adding dua on link"); + ipv6_route_add_with_info(domain_prefix, 64, this->backbone_interface_id, NULL, ROUTE_THREAD_BBR, NULL, 0, 0xffffffff, 0); + tr_info("Hosting pBBR for DUA prefix"); + ipv6_route_delete(domain_prefix, 64, cur->id, NULL, ROUTE_THREAD); + } +} void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds) { @@ -1109,6 +1141,7 @@ void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds) tr_info("pbbr downgraded"); thread_extension_bbr_pbbr_stop(this); } + } // Check secondary state if we need to drop @@ -1175,5 +1208,4 @@ int thread_extension_bbr_address_set(int8_t interface_id, const uint8_t *addr_pt } -#endif //HAVE_THREAD_BORDER_ROUTER -#endif //HAVE_THREAD_V2 +#endif //HAVE_THREAD_BORDER_ROUTER && HAVE_THREAD_V2 diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.h b/source/6LoWPAN/Thread/thread_extension_bbr.h index 114d9fad9a4a..5e4ac8f8c157 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.h +++ b/source/6LoWPAN/Thread/thread_extension_bbr.h @@ -38,13 +38,15 @@ extern "C" { #endif -#ifdef HAVE_THREAD_V2 +#if defined(HAVE_THREAD_V2) && defined(HAVE_THREAD_BORDER_ROUTER) + int8_t thread_extension_bbr_init(int8_t interface_id, int8_t backbone_interface_id); void thread_extension_bbr_delete(int8_t interface_id); bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur, const uint8_t *target_addr, uint16_t rloc); void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds); int thread_extension_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t timeout_b, uint32_t delay); int thread_extension_bbr_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port); +void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur); #else @@ -55,10 +57,11 @@ int thread_extension_bbr_address_set(int8_t interface_id, const uint8_t *addr_pt #define thread_extension_bbr_seconds_timer(interface_id, seconds) #define thread_extension_bbr_timeout_set(interface_id, timeout_a, timeout_b, delay) #define thread_extension_bbr_address_set(interface_id, addr_ptr, port) (-1) +#define thread_extension_bbr_route_update(cur) #endif #ifdef __cplusplus } #endif -#endif /* THREAD_EXTENSION_BBR_H_ */ +#endif //HAVE_THREAD_BORDER_ROUTER && HAVE_THREAD_V2 diff --git a/source/ipv6_stack/ipv6_routing_table.h b/source/ipv6_stack/ipv6_routing_table.h index 86d08569e7aa..5d39a1cfa830 100644 --- a/source/ipv6_stack/ipv6_routing_table.h +++ b/source/ipv6_stack/ipv6_routing_table.h @@ -82,6 +82,7 @@ typedef enum ipv6_route_src { ROUTE_THREAD, ROUTE_THREAD_BORDER_ROUTER, ROUTE_THREAD_PROXIED_HOST, + ROUTE_THREAD_BBR, ROUTE_REDIRECT, /* Only occurs in destination cache */ ROUTE_MAX, } ipv6_route_src_t; diff --git a/test/nanostack/unittest/stub/thread_extension_stub.c b/test/nanostack/unittest/stub/thread_extension_stub.c index 3577d389ce33..01080ed72b35 100644 --- a/test/nanostack/unittest/stub/thread_extension_stub.c +++ b/test/nanostack/unittest/stub/thread_extension_stub.c @@ -58,6 +58,11 @@ void thread_extension_primary_bbr_update_done(struct protocol_interface_info_ent (void)cur; } +void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur) +{ + (void)cur; +} + void thread_extension_primary_bbr_process(struct protocol_interface_info_entry *cur) { (void)cur; From a573bc4964c103e7619851eec4667f010c319525 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Wed, 2 May 2018 12:46:52 +0300 Subject: [PATCH 48/52] Detection of duplicate address entries updated (#1686) --- source/6LoWPAN/Thread/thread_extension_bbr.c | 43 ++++++++++++++----- .../Thread/thread_joiner_application.c | 9 ++++ .../Thread/thread_joiner_application.h | 1 + 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.c b/source/6LoWPAN/Thread/thread_extension_bbr.c index 2d96fe866da5..ae0656dd05fc 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.c +++ b/source/6LoWPAN/Thread/thread_extension_bbr.c @@ -91,6 +91,7 @@ typedef struct { uint8_t ml_eid[8]; uint8_t target_eid[16]; uint16_t ttl; + uint8_t dua_dad_repeat; ns_list_link_t link; } duplicate_dua_tr_t; @@ -101,6 +102,8 @@ static NS_LIST_DEFINE(duplicate_dua_tr_list, duplicate_dua_tr_t, link); #define THREAD_BBR_DUA_REGISTRATION_TIMEOUT 3600 #define THREAD_BBR_DUA_REGISTRATION_DELAY 5000 // 5 seconds in ms #define THREAD_BBR_BACKBONE_PORT 5683 //<* Backbone border router +#define THREAD_BBR_DUA_DAD_QUERY_TIMEOUT 1 // wait period for Duplicate Address Detection +#define THREAD_BBR_DUA_DAD_REPEATS 2 // multicast repeated as part of DUA /* 0 – Successful registration @@ -164,7 +167,8 @@ static duplicate_dua_tr_t *thread_border_router_dup_tr_create(int8_t interface_i memcpy(this->target_eid, target_eid_ptr,16); memcpy(this->source_address, source_addr_ptr, 16); memcpy(this->ml_eid, ml_eid_ptr,8); - this->ttl = 2; + this->dua_dad_repeat = THREAD_BBR_DUA_DAD_REPEATS; + this->ttl = THREAD_BBR_DUA_DAD_QUERY_TIMEOUT; return this; } @@ -1062,6 +1066,31 @@ bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur, } +static void thread_extension_bbr_dad_process(protocol_interface_info_entry_t *cur, thread_pbbr_t *this, uint32_t seconds) +{ + ns_list_foreach_safe(duplicate_dua_tr_t, cur_dup_tr, &duplicate_dua_tr_list) { + if (cur_dup_tr->interface_id != cur->id) { + continue; + } + if (cur_dup_tr->ttl > seconds) { + cur_dup_tr->ttl -= seconds; + } else { + cur_dup_tr->dua_dad_repeat--; + // repeat dad for one more time + if (cur_dup_tr->dua_dad_repeat > 0) { + cur_dup_tr->ttl = THREAD_BBR_DUA_DAD_QUERY_TIMEOUT; + thread_border_router_bb_qry_send(this,cur_dup_tr->target_eid,NULL); + return; + } else { + // dad completed + // send PRO_BB.ntf and delete dad entry + thread_border_router_bb_ans_send(this, this->pbbr_multicast_address, cur_dup_tr->target_eid, cur_dup_tr->ml_eid, 0, thread_joiner_application_network_name_get(cur->id), NULL); + thread_border_router_dup_tr_delete(cur_dup_tr); + } + } + } +} + void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur) { // if we have DUA prefix in settings @@ -1095,6 +1124,7 @@ void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur) } } + void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds) { thread_pbbr_t *this = thread_bbr_find_by_interface(interface_id); @@ -1146,15 +1176,8 @@ void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds) // Check secondary state if we need to drop // Check pending dua registrations - ns_list_foreach_safe(duplicate_dua_tr_t, cur_dup_tr, &duplicate_dua_tr_list) { - if (cur_dup_tr->interface_id == interface_id && cur_dup_tr->ttl > seconds) { - cur_dup_tr->ttl -= seconds; - // TODO Repeat the ANS 2 times. - } else { - // Timeout Remmove the duplicate detection timer - thread_border_router_dup_tr_delete(cur_dup_tr); - } - } + thread_extension_bbr_dad_process(cur, this, seconds); + if (this->dua_timer_ticks) { if (this->dua_timer_ticks > seconds) { this->dua_timer_ticks -= seconds; diff --git a/source/6LoWPAN/Thread/thread_joiner_application.c b/source/6LoWPAN/Thread/thread_joiner_application.c index 231502f05810..91400d7e4018 100644 --- a/source/6LoWPAN/Thread/thread_joiner_application.c +++ b/source/6LoWPAN/Thread/thread_joiner_application.c @@ -917,6 +917,15 @@ link_configuration_s *thread_joiner_application_get_config(int8_t interface_id) return this->configuration_ptr; } +uint8_t *thread_joiner_application_network_name_get(int8_t interface_id) +{ + thread_joiner_t *this = thread_joiner_find(interface_id); + if (!this) { + return NULL; + } + return this->configuration_ptr->name; +} + static int thread_joiner_application_nvm_link_config_read(thread_joiner_t *this) { // read config from NVM, in case of failure current settings are unchanged. diff --git a/source/6LoWPAN/Thread/thread_joiner_application.h b/source/6LoWPAN/Thread/thread_joiner_application.h index 3939b5de5257..21258690ee2e 100644 --- a/source/6LoWPAN/Thread/thread_joiner_application.h +++ b/source/6LoWPAN/Thread/thread_joiner_application.h @@ -69,6 +69,7 @@ struct link_configuration *thread_joiner_application_get_config(int8_t interface uint64_t thread_joiner_application_active_timestamp_get(int8_t interface_id); uint8_t thread_joiner_application_security_policy_get(int8_t interface_id); void thread_joiner_application_active_timestamp_set(int8_t interface_id, uint64_t timestamp); +uint8_t *thread_joiner_application_network_name_get(int8_t interface_id); uint8_t *thread_joiner_application_active_config_tlv_list_get(uint8_t interface_id, uint16_t *length); uint8_t *thread_joiner_application_active_config_params_get(uint8_t interface_id, uint16_t *length); From e4a9657e0f426c7e84e084719a5b8907b0e2c857 Mon Sep 17 00:00:00 2001 From: Tero Heinonen Date: Thu, 3 May 2018 10:57:49 +0300 Subject: [PATCH 49/52] Compiler warning clean-up (#1690) Fixed compiler warnings. --- .../Generic/protocol_6lowpan_interface.c | 8 +- source/6LoWPAN/MAC/mac_helper.c | 2 + source/Common_Protocols/icmpv6.c | 153 +++++++++--------- source/Common_Protocols/tcp.c | 2 +- source/Core/include/ns_buffer.h | 12 +- .../mac_header_helper_functions.c | 6 + source/MPL/mpl.c | 3 +- .../Service_Libs/fhss/fhss_beacon_tasklet.c | 2 + source/Service_Libs/nd_proxy/nd_proxy.c | 5 +- source/Service_Libs/nd_proxy/nd_proxy.h | 6 +- source/ipv6_stack/ipv6_routing_table.c | 3 +- test/nanostack/unittest/stub/nd_proxy_stub.c | 2 +- 12 files changed, 110 insertions(+), 94 deletions(-) diff --git a/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_interface.c b/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_interface.c index 854f11b0017a..478d86ecafbe 100644 --- a/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_interface.c +++ b/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_interface.c @@ -87,7 +87,10 @@ static int8_t set_6lowpan_nwk_down(protocol_interface_info_entry_t *cur) #endif } } - uint16_t pan_id = cur->mac_parameters->pan_id; + if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) { + pana_reset_values(cur->mac_parameters->pan_id); + } + if (cur->interface_mode == INTERFACE_UP) { if (cur->mac_api) { mlme_reset_t reset; @@ -105,9 +108,6 @@ static int8_t set_6lowpan_nwk_down(protocol_interface_info_entry_t *cur) reassembly_interface_reset(cur->id); icmp_nd_routers_init(); - if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) { - pana_reset_values(pan_id); - } if (cur->pana_sec_info_temp) { ns_dyn_mem_free(cur->pana_sec_info_temp); diff --git a/source/6LoWPAN/MAC/mac_helper.c b/source/6LoWPAN/MAC/mac_helper.c index bf3e6c311514..faf954010d1b 100644 --- a/source/6LoWPAN/MAC/mac_helper.c +++ b/source/6LoWPAN/MAC/mac_helper.c @@ -768,8 +768,10 @@ static uint8_t mac_helper_header_security_aux_header_length(uint8_t keyIdmode) { switch (keyIdmode) { case MAC_KEY_ID_MODE_SRC8_IDX: header_length += 4; //64-bit key source first part + /* fall through */ case MAC_KEY_ID_MODE_SRC4_IDX: header_length += 4; //32-bit key source inline + /* fall through */ case MAC_KEY_ID_MODE_IDX: header_length += 1; break; diff --git a/source/Common_Protocols/icmpv6.c b/source/Common_Protocols/icmpv6.c index cf11bb8c893a..6c4240b65de8 100644 --- a/source/Common_Protocols/icmpv6.c +++ b/source/Common_Protocols/icmpv6.c @@ -48,7 +48,6 @@ #define TRACE_GROUP "icmp" static buffer_t *icmpv6_echo_request_handler(struct buffer *buf); -static buffer_t *icmpv6_na_handler(struct buffer *buf); /* Check to see if a message is recognisable ICMPv6, and if so, fill in code/type */ /* This used ONLY for the e.1 + e.2 tests in RFC 4443, to try to avoid ICMPv6 error loops */ @@ -486,7 +485,6 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf) * interface, which we should only do in the whiteboard case. */ if (addr_interface_address_compare(cur, target) != 0) { - int8_t mesh_id = -1; //tr_debug("Received NS for proxy %s", trace_ipv6(target)); proxy = true; @@ -495,7 +493,7 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf) goto drop; } - if (!nd_proxy_enabled_for_downstream(cur->id) || !nd_proxy_target_address_validation(cur->id, target, &mesh_id)) { + if (!nd_proxy_enabled_for_downstream(cur->id) || !nd_proxy_target_address_validation(cur->id, target)) { goto drop; } } @@ -922,6 +920,80 @@ static buffer_t *icmpv6_redirect_handler(buffer_t *buf, protocol_interface_info_ tr_warn("Redirect drop"); return buffer_free(buf); } + +static buffer_t *icmpv6_na_handler(buffer_t *buf) +{ + protocol_interface_info_entry_t *cur; + uint8_t *dptr = buffer_data_pointer(buf); + uint8_t flags; + const uint8_t *target; + const uint8_t *tllao; + if_address_entry_t *addr_entry; + ipv6_neighbour_t *neighbour_entry; + + //"Parse NA at IPv6\n"); + + if (buf->options.code != 0 || buf->options.hop_limit != 255) { + goto drop; + } + + if (!icmpv6_options_well_formed_in_buffer(buf, 20)) { + goto drop; + } + + // Skip the 4 reserved bytes + flags = *dptr; + dptr += 4; + + // Note the target IPv6 address + target = dptr; + + if (addr_is_ipv6_multicast(target)) { + goto drop; + } + + /* Solicited flag must be clear if sent to a multicast address */ + if (addr_is_ipv6_multicast(buf->dst_sa.address) && (flags & NA_S)) { + goto drop; + } + + cur = buf->interface; + + /* RFC 4862 5.4.4 DAD checks */ + addr_entry = addr_get_entry(cur, target); + if (addr_entry) { + if (addr_entry->tentative) { + tr_debug("Received NA for our tentative address"); + addr_duplicate_detected(cur, target); + } else { + tr_debug("NA received for our own address: %s", trace_ipv6(target)); + } + goto drop; + } + + if (cur->ipv6_neighbour_cache.recv_na_aro) { + const uint8_t *aro = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_ADDR_REGISTRATION, 2); + if (aro) { + icmpv6_na_aro_handler(cur, aro, buf->dst_sa.address); + } + } + + /* No need to create a neighbour cache entry if one doesn't already exist */ + neighbour_entry = ipv6_neighbour_lookup(&cur->ipv6_neighbour_cache, target); + if (!neighbour_entry) { + goto drop; + } + + tllao = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_TGT_LL_ADDR, 0); + if (!tllao || !cur->if_llao_parse(cur, tllao, &buf->dst_sa)) { + buf->dst_sa.addr_type = ADDR_NONE; + } + + ipv6_neighbour_update_from_na(&cur->ipv6_neighbour_cache, neighbour_entry, flags, buf->dst_sa.addr_type, buf->dst_sa.address); + +drop: + return buffer_free(buf); +} #endif // HAVE_IPV6_ND buffer_t *icmpv6_up(buffer_t *buf) @@ -994,7 +1066,7 @@ buffer_t *icmpv6_up(buffer_t *buf) case ICMPV6_TYPE_INFO_ECHO_REPLY: ipv6_neighbour_reachability_confirmation(buf->src_sa.address, buf->interface->id); - /* no break */ + /* fall through */ case ICMPV6_TYPE_ERROR_DESTINATION_UNREACH: #ifdef HAVE_RPL_ROOT @@ -1499,79 +1571,6 @@ buffer_t *icmpv6_build_na(protocol_interface_info_entry_t *cur, bool solicited, return (buf); } -static buffer_t *icmpv6_na_handler(buffer_t *buf) -{ - protocol_interface_info_entry_t *cur; - uint8_t *dptr = buffer_data_pointer(buf); - uint8_t flags; - const uint8_t *target; - const uint8_t *tllao; - if_address_entry_t *addr_entry; - ipv6_neighbour_t *neighbour_entry; - - //"Parse NA at IPv6\n"); - - if (buf->options.code != 0 || buf->options.hop_limit != 255) { - goto drop; - } - - if (!icmpv6_options_well_formed_in_buffer(buf, 20)) { - goto drop; - } - - // Skip the 4 reserved bytes - flags = *dptr; - dptr += 4; - - // Note the target IPv6 address - target = dptr; - - if (addr_is_ipv6_multicast(target)) { - goto drop; - } - - /* Solicited flag must be clear if sent to a multicast address */ - if (addr_is_ipv6_multicast(buf->dst_sa.address) && (flags & NA_S)) { - goto drop; - } - - cur = buf->interface; - - /* RFC 4862 5.4.4 DAD checks */ - addr_entry = addr_get_entry(cur, target); - if (addr_entry) { - if (addr_entry->tentative) { - tr_debug("Received NA for our tentative address"); - addr_duplicate_detected(cur, target); - } else { - tr_debug("NA received for our own address: %s", trace_ipv6(target)); - } - goto drop; - } - - if (cur->ipv6_neighbour_cache.recv_na_aro) { - const uint8_t *aro = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_ADDR_REGISTRATION, 2); - if (aro) { - icmpv6_na_aro_handler(cur, aro, buf->dst_sa.address); - } - } - - /* No need to create a neighbour cache entry if one doesn't already exist */ - neighbour_entry = ipv6_neighbour_lookup(&cur->ipv6_neighbour_cache, target); - if (!neighbour_entry) { - goto drop; - } - - tllao = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_TGT_LL_ADDR, 0); - if (!tllao || !cur->if_llao_parse(cur, tllao, &buf->dst_sa)) { - buf->dst_sa.addr_type = ADDR_NONE; - } - - ipv6_neighbour_update_from_na(&cur->ipv6_neighbour_cache, neighbour_entry, flags, buf->dst_sa.addr_type, buf->dst_sa.address); - -drop: - return buffer_free(buf); -} #endif // HAVE_IPV6_ND #ifdef HAVE_IPV6_ND diff --git a/source/Common_Protocols/tcp.c b/source/Common_Protocols/tcp.c index d492f563004a..5fb61554edef 100644 --- a/source/Common_Protocols/tcp.c +++ b/source/Common_Protocols/tcp.c @@ -559,7 +559,7 @@ tcp_error tcp_session_abort(tcp_session_t *tcp_session) case TCP_STATE_FIN_WAIT_2: case TCP_STATE_CLOSE_WAIT: tcp_session_send_reset_to_abort_connection(tcp_session); - /* no break */ + /* fall through */ case TCP_STATE_LISTEN: case TCP_STATE_SYN_SENT: tcp_session_delete_with_error(tcp_session, SOCKET_CONNECTION_RESET); diff --git a/source/Core/include/ns_buffer.h b/source/Core/include/ns_buffer.h index 5e4681bbeb91..60e5f22bff46 100644 --- a/source/Core/include/ns_buffer.h +++ b/source/Core/include/ns_buffer.h @@ -340,12 +340,20 @@ struct socket *buffer_socket_set(buffer_t *buf, struct socket *socket); /** Removes z amount of bytes from the begining of buffer * uint8_t *buffer_data_strip_header(buffer_t *x, uint16_t z) * */ -#define buffer_data_strip_header(x,z) ((x)->buf_ptr += (z), buffer_data_pointer_after_adjustment(x)) +static inline uint8_t *buffer_data_strip_header(buffer_t *x, uint16_t z) +{ + x->buf_ptr += z; + return buffer_data_pointer_after_adjustment(x); +} /** Adds z amount of bytes to the begining of buffer check if this is allowed using buffer_headroom method. * uint8_t *buffer_data_reserve_header(buffer_t *x, uint16_t z) * */ -#define buffer_data_reserve_header(x,z) ((x)->buf_ptr -= (z), buffer_data_pointer_after_adjustment(x)) +static inline uint8_t *buffer_data_reserve_header(buffer_t *x, uint16_t z) +{ + x->buf_ptr -= z; + return buffer_data_pointer_after_adjustment(x); +} /** append 1 byte to data*/ #define buffer_push_uint8(x, z) do {\ diff --git a/source/MAC/IEEE802_15_4/mac_header_helper_functions.c b/source/MAC/IEEE802_15_4/mac_header_helper_functions.c index 1a23d00b38bb..e5ed44e63e52 100644 --- a/source/MAC/IEEE802_15_4/mac_header_helper_functions.c +++ b/source/MAC/IEEE802_15_4/mac_header_helper_functions.c @@ -58,8 +58,10 @@ uint8_t mac_header_security_aux_header_length(uint8_t security_level, uint8_t ke switch (keyIdmode) { case MAC_KEY_ID_MODE_SRC8_IDX: header_length += 4; //64-bit key source first part + /* fall through */ case MAC_KEY_ID_MODE_SRC4_IDX: header_length += 4; //32-bit key source inline + /* fall through */ case MAC_KEY_ID_MODE_IDX: header_length += 1; break; @@ -128,8 +130,10 @@ void mac_header_security_parameter_set(mac_aux_security_header_t *header, const case MAC_KEY_ID_MODE_SRC8_IDX: keysource_len += 4; //64-bit key source first part + /* fall through */ case MAC_KEY_ID_MODE_SRC4_IDX: keysource_len += 4; //32-bit key source inline + /* fall through */ case MAC_KEY_ID_MODE_IDX: //Security header + 32-bit security counter + Key index header->KeyIndex = frame_setup->KeyIndex; @@ -198,10 +202,12 @@ void mac_header_security_components_read(mac_pre_parsed_frame_t *buffer, mlme_se break; case MAC_KEY_ID_MODE_SRC8_IDX: key_source_len += 4; + /* fall through */ case MAC_KEY_ID_MODE_SRC4_IDX: key_source_len += 4; memcpy(security_params->Keysource, ptr, key_source_len); ptr += key_source_len; + /* fall through */ case MAC_KEY_ID_MODE_IDX: security_params->KeyIndex = *ptr; break; diff --git a/source/MPL/mpl.c b/source/MPL/mpl.c index b72600da69f2..9ad06d49d3be 100644 --- a/source/MPL/mpl.c +++ b/source/MPL/mpl.c @@ -685,7 +685,8 @@ buffer_t *mpl_control_handler(buffer_t *buf, protocol_interface_info_entry_t *cu // by its colour not being flipped. // This is equivalent to having a "mentioned" flag, except we don't have // to have a separate "reset" loop. - bool new_colour = --domain->colour; // smart-alec binary flip + domain->colour = !domain->colour; + bool new_colour = domain->colour; while (ptr < end) { if (end - ptr < 2) { diff --git a/source/Service_Libs/fhss/fhss_beacon_tasklet.c b/source/Service_Libs/fhss/fhss_beacon_tasklet.c index 2ba416cf909e..7c54b6d2b0f7 100644 --- a/source/Service_Libs/fhss/fhss_beacon_tasklet.c +++ b/source/Service_Libs/fhss/fhss_beacon_tasklet.c @@ -68,7 +68,9 @@ static void fhss_beacon_tasklet_func(arm_event_s* event) if (!fhss_structure) { return; } +#ifdef FEA_TRACE_SUPPORT uint8_t parent_address[8]; +#endif fhss_clear_active_event(fhss_structure, event->event_type); // skip the init event as there will be a timer event after if (event->event_type == FHSS_TIMER_EVENT) { diff --git a/source/Service_Libs/nd_proxy/nd_proxy.c b/source/Service_Libs/nd_proxy/nd_proxy.c index 72a841343fd5..51b96b207946 100644 --- a/source/Service_Libs/nd_proxy/nd_proxy.c +++ b/source/Service_Libs/nd_proxy/nd_proxy.c @@ -434,11 +434,11 @@ bool nd_proxy_enabled_for_upstream(int8_t interface_id) return false; } -bool nd_proxy_target_address_validation(int8_t upstream_id, uint8_t *address, int8_t *downstream_id_ptr) +bool nd_proxy_target_address_validation(int8_t upstream_id, uint8_t *address) { nd_proxy_downstream_list_s *downstream; nd_proxy_connected_list_s *upstream = proxy_upstream_conection_get(upstream_id); - *downstream_id_ptr = -1; + if (!upstream) { return false; } @@ -447,7 +447,6 @@ bool nd_proxy_target_address_validation(int8_t upstream_id, uint8_t *address, in downstream = proxy_cache_downstream_interface_get(downstream_entry->id, &downstream_interface_list); if (downstream) { if (downstream->nd_proxy_validation(downstream_entry->id, address) == 0) { - *downstream_id_ptr = downstream_entry->id; return true; } } diff --git a/source/Service_Libs/nd_proxy/nd_proxy.h b/source/Service_Libs/nd_proxy/nd_proxy.h index 0059d6de9588..4ab48e23e5a2 100644 --- a/source/Service_Libs/nd_proxy/nd_proxy.h +++ b/source/Service_Libs/nd_proxy/nd_proxy.h @@ -125,7 +125,7 @@ bool nd_proxy_enabled_for_upstream(int8_t interface_id); *\return true Address validated behind downstream_id_ptr interface *\return false Unknown address for this proxy */ -bool nd_proxy_target_address_validation(int8_t upstream_id, uint8_t *address, int8_t *downstream_id_ptr); +bool nd_proxy_target_address_validation(int8_t upstream_id, uint8_t *address); /** * Downstream interface validate prefix route on Link status from connected Upstream interface * @@ -147,9 +147,9 @@ NS_DUMMY_DEFINITIONS_OK #define nd_proxy_upstream_interface_unregister(interface_id) -1 #define nd_proxy_enabled_for_downstream(interface_id) false #define nd_proxy_enabled_for_upstream(interface_id) false -#define nd_proxy_target_address_validation(upstream_id, address, downstream_id_ptr) false +#define nd_proxy_target_address_validation(upstream_id, address) false #define nd_proxy_upstream_route_onlink(downstream_id, address) false -#define nd_proxy_target_address_validation(upstream_id, address, downstream_id_ptr) false + #endif /* HAVE_ND_PROXY */ #endif /* ND_PROXY_H_ */ diff --git a/source/ipv6_stack/ipv6_routing_table.c b/source/ipv6_stack/ipv6_routing_table.c index 4c30a332099c..9e36a43a2a26 100644 --- a/source/ipv6_stack/ipv6_routing_table.c +++ b/source/ipv6_stack/ipv6_routing_table.c @@ -73,7 +73,6 @@ static void ipv6_destination_cache_forget_neighbour(const ipv6_neighbour_t *neig static void ipv6_destination_release(ipv6_destination_t *dest); static void ipv6_route_table_remove_router(int8_t interface_id, const uint8_t *addr, ipv6_route_src_t source); static uint16_t total_metric(const ipv6_route_t *route); -static void trace_debug_print(const char *fmt, ...); static uint8_t ipv6_route_table_count_source(int8_t interface_id, ipv6_route_src_t source); static void ipv6_route_table_remove_last_one_from_source(int8_t interface_id, ipv6_route_src_t source); static uint8_t ipv6_route_table_get_max_entries(int8_t interface_id, ipv6_route_src_t source); @@ -758,7 +757,7 @@ void ipv6_neighbour_cache_fast_timer(ipv6_neighbour_cache_t *cache, uint16_t tic ipv6_neighbour_set_state(cache, cur, IP_NEIGHBOUR_UNREACHABLE); } } - /* no break */ + /* fall through */ case IP_NEIGHBOUR_UNREACHABLE: if (cur->retrans_count < 0xFF) { cur->retrans_count++; diff --git a/test/nanostack/unittest/stub/nd_proxy_stub.c b/test/nanostack/unittest/stub/nd_proxy_stub.c index fa117fed2baf..89901f16369b 100644 --- a/test/nanostack/unittest/stub/nd_proxy_stub.c +++ b/test/nanostack/unittest/stub/nd_proxy_stub.c @@ -56,7 +56,7 @@ bool nd_proxy_enabled_for_upstream(int8_t interface_id) return false; } -bool nd_proxy_target_address_validation(int8_t upstream_id, uint8_t *address, int8_t *downstream_id_ptr) +bool nd_proxy_target_address_validation(int8_t upstream_id, uint8_t *address) { return false; } From 92044d6904faff3d0b5df1a762d88a6aed459f1b Mon Sep 17 00:00:00 2001 From: Tero Heinonen Date: Thu, 3 May 2018 14:02:52 +0300 Subject: [PATCH 50/52] Changed BBR router upgrade status (#1661) When BBR is started, it should require router ID with status "HAVE_CHILD_ID_REQUEST" (3) --- source/6LoWPAN/Thread/thread_bbr_api.c | 2 +- source/6LoWPAN/Thread/thread_config.h | 10 ++++++++++ source/6LoWPAN/Thread/thread_constants.h | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bbr_api.c b/source/6LoWPAN/Thread/thread_bbr_api.c index d3b7935fdf79..0e0fc04d1162 100644 --- a/source/6LoWPAN/Thread/thread_bbr_api.c +++ b/source/6LoWPAN/Thread/thread_bbr_api.c @@ -738,7 +738,7 @@ static bool thread_bbr_activated(thread_bbr_t *this, uint32_t seconds) return true; } // We will try to become router. This is done only in 120 seconds intervals if failed - thread_router_bootstrap_router_id_request(cur, 0); + thread_router_bootstrap_router_id_request(cur, THREAD_BBR_ROUTER_ID_REQUEST_STATUS); this->router_upgrade_delay_timer = 120; return false; } diff --git a/source/6LoWPAN/Thread/thread_config.h b/source/6LoWPAN/Thread/thread_config.h index 06eae38323f2..ca689a004f23 100644 --- a/source/6LoWPAN/Thread/thread_config.h +++ b/source/6LoWPAN/Thread/thread_config.h @@ -31,6 +31,10 @@ #ifndef THREAD_CONFIG_H_ #define THREAD_CONFIG_H_ +/** + * Thread stack configuration values. All constants that are specified in Thread specification can be found from thread_constants.h + */ + #include "thread_constants.h" /** @@ -316,6 +320,12 @@ * Parent response wait time (in 100ms) when both "R" and "E" bit is set in scan mask TLV (rounded up from 1.25 seconds) */ #define THREAD_PARENT_REQ_SCANMASK_RE_TIMEOUT 15 + +/* + * When BBR is started, router address is requested from leader with following status + */ +#define THREAD_BBR_ROUTER_ID_REQUEST_STATUS THREAD_COAP_STATUS_TLV_HAVE_CHILD_ID_REQUEST + /** * Build time flag to enable THCI special traces for test harness purposes */ diff --git a/source/6LoWPAN/Thread/thread_constants.h b/source/6LoWPAN/Thread/thread_constants.h index 602f0dcf9103..978606b360b2 100644 --- a/source/6LoWPAN/Thread/thread_constants.h +++ b/source/6LoWPAN/Thread/thread_constants.h @@ -31,7 +31,7 @@ #define THREAD_CONSTANTS_H_ /** - * Constants defined in Thread specifications + * Constants defined in Thread specifications. All configured values are defined in thread_config.h */ /** From 0860ae724483de64865a7ada1b4f14ddd8d2d5a4 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Mon, 7 May 2018 11:34:25 +0300 Subject: [PATCH 51/52] Keep parent mle_entry in child_update_req timeout (#1693) When end device fails to attach to new partition it will return back to old partition. End device is not allowed to delete its parent mle_entry when parent has moved to new partition and attach fails. --- source/6LoWPAN/Thread/thread_host_bootstrap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_host_bootstrap.c b/source/6LoWPAN/Thread/thread_host_bootstrap.c index 82f27dcc9eec..b1cf6441477d 100644 --- a/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -890,7 +890,7 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message break; } default: - tr_debug("Unsupported TLV %d", mle_msg->message_type); + tr_debug("Skip msg type %d", mle_msg->message_type); break; } @@ -998,7 +998,7 @@ static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, boo cur->thread_info->thread_attach_scanned_parent->child_id_request_id = 0; uint8_t *addr = mle_service_get_msg_destination_address_pointer(msgId); - tr_debug("Child ID Request timed out, address: %s", trace_ipv6(addr)); + tr_debug("Child ID Request timed out: %s", trace_ipv6(addr)); blacklist_update(addr, false); @@ -1023,7 +1023,8 @@ static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, boo ll64[8] ^= 2; entry_temp = mle_class_get_entry_by_ll64(cur->id, scanned_parent->linkMarginToParent, ll64, false, NULL); - if (entry_temp) { + if (entry_temp && !thread_check_is_this_my_parent(cur, entry_temp)) { + // remove scanned_parent entry only if it is not my parent mle_class_remove_entry(cur->id, entry_temp); } } From 7c7568d74500ccc8ec451e81f40067196d644e9d Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Mon, 7 May 2018 15:54:31 +0300 Subject: [PATCH 52/52] address error sent when matching entry found. (#1695) --- source/6LoWPAN/Thread/thread_extension_bbr.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.c b/source/6LoWPAN/Thread/thread_extension_bbr.c index ae0656dd05fc..14b5332fafc8 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.c +++ b/source/6LoWPAN/Thread/thread_extension_bbr.c @@ -468,7 +468,7 @@ static int thread_pbbr_bb_qry_cb(int8_t service_id, uint8_t source_address[16], rloc_ptr = &rloc; } - uint32_t last_transaction_time = this->mlr_timeout > route->lifetime? this->mlr_timeout - route->lifetime : 0; + uint32_t last_transaction_time = 30; uint8_t *ml_eid_ptr = &route->prefix[8];// TODO MLEID needs to be stored in own structure route->info.info and support for dealloc made // This address is valid in our MESH @@ -500,7 +500,7 @@ static int thread_pbbr_dua_duplicate_address_detection(int8_t service_id, uint8_ } // We have pending request and received answer - if (memcmp(ml_eid_ptr,tr_ptr->ml_eid, 8) != 0){ + if (memcmp(ml_eid_ptr,tr_ptr->ml_eid, 8) == 0){ // Different ml_eid but same address means duplicate address detected thread_resolution_client_address_error(this->interface_id, tr_ptr->source_address, tr_ptr->target_eid, tr_ptr->ml_eid); ipv6_neighbour_t *neighbour_entry; @@ -1068,6 +1068,9 @@ bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur, static void thread_extension_bbr_dad_process(protocol_interface_info_entry_t *cur, thread_pbbr_t *this, uint32_t seconds) { + if (!this) { + return; + } ns_list_foreach_safe(duplicate_dua_tr_t, cur_dup_tr, &duplicate_dua_tr_list) { if (cur_dup_tr->interface_id != cur->id) { continue; @@ -1080,7 +1083,6 @@ static void thread_extension_bbr_dad_process(protocol_interface_info_entry_t *cu if (cur_dup_tr->dua_dad_repeat > 0) { cur_dup_tr->ttl = THREAD_BBR_DUA_DAD_QUERY_TIMEOUT; thread_border_router_bb_qry_send(this,cur_dup_tr->target_eid,NULL); - return; } else { // dad completed // send PRO_BB.ntf and delete dad entry