Skip to content

Commit

Permalink
Merge pull request ARMmbed#1560 from ARMmbed/mergeMtoK2
Browse files Browse the repository at this point in the history
Merge mto k2
  • Loading branch information
Jarkko Paso committed Feb 7, 2018
2 parents 8b43c6e + b78a370 commit 3fb6390
Show file tree
Hide file tree
Showing 15 changed files with 193 additions and 137 deletions.
67 changes: 1 addition & 66 deletions source/6LoWPAN/Thread/thread_bootstrap.c
Expand Up @@ -115,21 +115,6 @@ static void thread_bootsrap_network_join_start(struct protocol_interface_info_en
static int8_t thread_child_keep_alive(int8_t interface_id, const uint8_t *mac64);


int thread_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child)
{
thread_dynamic_storage_child_info_clear(cur->id, child);

// If Child's RLOC16 appears in the Network Data send the RLOC16 to the Leader
if (thread_network_data_services_registered(&cur->thread_info->networkDataStorage, child->short_adr)) {
tr_debug("Remove references to Child's RLOC16 from the Network Data");
thread_management_client_network_data_unregister(cur->id, child->short_adr);
}

// Clear all (sleepy) child registrations to multicast groups
thread_child_mcast_entries_remove(cur, child->mac64);

return 0;
}

static bool thread_interface_is_active(int8_t interface_id) {
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
Expand All @@ -146,57 +131,7 @@ static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t
if (!cur_interface) {
return;
}
if (thread_info(cur_interface)->thread_device_mode == THREAD_DEVICE_MODE_END_DEVICE || thread_info(cur_interface)->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) {
thread_parent_info_t *thread_endnode_parent = thread_info(cur_interface)->thread_endnode_parent;
//Compare Parent
if (thread_endnode_parent) {
if (thread_endnode_parent->shortAddress == cur->short_adr) {
tr_warn("End device lost Parent!\n");
thread_bootstrap_connection_error(cur_interface->id, CON_PARENT_CONNECT_DOWN, NULL);
}
}
}
else {
if (thread_info(cur_interface)->thread_attached_state == THREAD_STATE_CONNECTED)
{
thread_parent_info_t *thread_endnode_parent = thread_info(cur_interface)->thread_endnode_parent;
if (thread_endnode_parent->shortAddress == cur->short_adr) {
tr_warn("REED has lost Parent!\n");
thread_routing_remove_link(cur_interface, cur->short_adr);
if(cur_interface->nwk_bootstrap_state != ER_CHILD_ID_REQ) {
thread_bootstrap_connection_error(cur_interface->id, CON_PARENT_CONNECT_DOWN, NULL);
}
}
else{
tr_debug("Delete REED Neighbor");
if (thread_is_router_addr(cur->short_adr)) {
tr_debug("Router Free");
thread_routing_remove_link(cur_interface, cur->short_adr);
}
}
}
else if (thread_info(cur_interface)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER)
{
tr_debug("Delete Router Neighbor %x", cur->short_adr);
if (thread_is_router_addr(cur->short_adr)) {
tr_debug("Router free");
thread_routing_remove_link(cur_interface, cur->short_adr);
} else if (thread_addr_is_child(mac_helper_mac16_address_get(cur_interface), cur->short_adr)) {
tr_debug("Child free");
/* 16-bit neighbour cache entries are mesh addresses, so remain potentially valid even if an
* MLE link fails. This is the only exception - if it was the link from us as a router to a
* child. That means that device must be off the mesh (at that 16-bit address, at least).
* This will actually clear either a GC cache entry for a FTD or a registered entry
* for a MTD.
*/
protocol_6lowpan_release_short_link_address_from_neighcache(cur_interface, cur->short_adr);
thread_bootstrap_reset_child_info(cur_interface, cur);
}
}
}

protocol_6lowpan_release_long_link_address_from_neighcache(cur_interface, cur->mac64);
mac_helper_devicetable_remove(cur_interface->mac_api, cur->attribute_index);
thread_reset_neighbour_info(cur_interface, cur);
}


Expand Down
64 changes: 29 additions & 35 deletions source/6LoWPAN/Thread/thread_common.c
Expand Up @@ -1837,36 +1837,27 @@ static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failure
return;
}

if (thread_i_am_router(cur)) {
if (thread_addr_is_child(mac_helper_mac16_address_get(cur), neighbor->short_adr)) {
if (accumulated_failures < THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
return;
}

tr_debug("Free the Child node, mac16=%d", neighbor->short_adr);
thread_bootstrap_reset_child_info(cur, neighbor);

protocol_6lowpan_release_short_link_address_from_neighcache(cur, neighbor->short_adr);
protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbor->mac64);
mac_helper_devicetable_remove(cur->mac_api, neighbor->attribute_index);
} else if (thread_is_router_addr(neighbor->short_adr)) {
if (accumulated_failures < THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_ROUTER_TRANSMISSIONS) {
return;
}

tr_debug("Set link quality to neighbor router to zero...");
thread_routing_force_link_margin(cur, neighbor->short_adr, 0);
}
} else { // We are a Child
if (thread_check_is_this_my_parent(cur, neighbor)) {
if (accumulated_failures < THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
return;
}

tr_debug("Consider the parent gone...");
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
}
}
if (accumulated_failures >= THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
thread_reset_neighbour_info(cur, neighbor);
}
}

/* Called when MLE link to neighbour lost, or ETX callback says link is bad */
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour)
{
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) {
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
}
}

thread_routing_remove_link(cur, neighbour->short_adr);
thread_router_bootstrap_reset_child_info(cur, neighbour);
protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbour->mac64);
mac_helper_devicetable_remove(cur->mac_api, neighbour->attribute_index);
}

uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv)
Expand Down Expand Up @@ -1929,14 +1920,17 @@ void thread_mcast_group_change(struct protocol_interface_info_entry *interface,
}
}

void thread_old_partition_data_purge(thread_info_t *thread_info)
void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur)
{
/* Partition has been changed. Wipe out data related to old partition */
thread_management_client_pending_coap_request_kill(thread_info->interface_id);
thread_management_client_pending_coap_request_kill(cur->id);

/* Reset previous routing information */
thread_routing_reset(&cur->thread_info->routing);

/* Flush address cache */
ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache);

/* Reset/init previous routing information */
thread_routing_reset(&thread_info->routing);
thread_routing_init(&thread_info->routing);
}

#endif
Expand Down
9 changes: 5 additions & 4 deletions source/6LoWPAN/Thread/thread_common.h
Expand Up @@ -70,9 +70,9 @@ extern uint16_t thread_joiner_port;

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

void thread_set_active_router(protocol_interface_info_entry_t *cur, if_address_entry_t *address_entry, uint8_t *routerId);
uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv);
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour);

void thread_child_id_request_entry_clean(protocol_interface_info_entry_t *cur);
thread_pending_child_id_req_t *thread_child_id_request_entry_get(protocol_interface_info_entry_t *cur, uint8_t *euid64);
Expand Down Expand Up @@ -411,7 +412,7 @@ uint8_t thread_pending_timestamp_tlv_size(protocol_interface_info_entry_t *cur);
void thread_calculate_key_guard_timer(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init);
void thread_set_link_local_address(protocol_interface_info_entry_t *cur);
void thread_mcast_group_change(struct protocol_interface_info_entry *interface, struct if_group_entry *group, bool group_added);
void thread_old_partition_data_purge(thread_info_t *thread_info);
void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur);

#else // HAVE_THREAD

Expand Down
7 changes: 6 additions & 1 deletion source/6LoWPAN/Thread/thread_host_bootstrap.c
Expand Up @@ -230,7 +230,9 @@ static int thread_parent_request_build(protocol_interface_info_entry_t *cur)
}

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_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;
}
Expand Down Expand Up @@ -835,6 +837,9 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message
thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED;

thread_bootstrap_update_ml16_address(cur, childId);
if (!thread_is_router_addr(thread_info(cur)->routerShortAddress)) {
thread_info(cur)->routerShortAddress = 0xfffe;
}

mle_service_msg_free(scan_result->child_id_request_id);

Expand Down
2 changes: 1 addition & 1 deletion source/6LoWPAN/Thread/thread_leader_service.c
Expand Up @@ -1317,7 +1317,7 @@ static void thread_leader_service_interface_setup_activate(protocol_interface_in
thread_leader_service_private_routemask_init(private);
//SET Router ID
thread_leader_allocate_router_id_by_allocated_id(private, routerId, cur->mac);
thread_old_partition_data_purge(cur->thread_info);
thread_old_partition_data_purge(cur);
cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS;
thread_bootstrap_update_ml16_address(cur, cur->thread_info->routerShortAddress);
thread_generate_ml64_address(cur);
Expand Down
1 change: 0 additions & 1 deletion source/6LoWPAN/Thread/thread_lowpower_api.c
Expand Up @@ -444,7 +444,6 @@ void thread_lowpower_process_response(uint8_t *src_address,int8_t instance_id, u
(void) instance_id;
mle_tlv_info_t linkMetricsReport;
if (memcmp(src_address, data_response_ptr->destination_address, 16) != 0) {
tr_debug("Data response not for me");
return;
}

Expand Down
2 changes: 1 addition & 1 deletion source/6LoWPAN/Thread/thread_management_server.c
Expand Up @@ -857,6 +857,7 @@ static int thread_management_server_panid_query_cb(int8_t service_id, uint8_t so
this->scan_ptr->timer = eventOS_timeout_ms(thread_panid_scan_timeout_cb, 500, this);// Delay for the confirm response message
if (!this->scan_ptr->timer) {
ns_dyn_mem_free(this->scan_ptr);
this->scan_ptr = NULL;
response_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
goto error_exit;
}
Expand All @@ -875,7 +876,6 @@ static int thread_management_server_panid_query_cb(int8_t service_id, uint8_t so
}
return -1;
error_exit:
this->scan_ptr = NULL;
if (request_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE ){
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, NULL, 0);
return 0;
Expand Down
36 changes: 32 additions & 4 deletions source/6LoWPAN/Thread/thread_mle_message_handler.c
Expand Up @@ -45,6 +45,7 @@
#include "6LoWPAN/Thread/thread_leader_service.h"
#include "6LoWPAN/Thread/thread_tmfcop_lib.h"
#include "6LoWPAN/Thread/thread_host_bootstrap.h"
#include "6LoWPAN/Thread/thread_extension.h"
#include "6LoWPAN/Thread/thread_router_bootstrap.h"
#include "6LoWPAN/Thread/thread_network_synch.h"
#include "6LoWPAN/MAC/mac_helper.h"
Expand Down Expand Up @@ -238,6 +239,29 @@ static bool thread_router_leader_data_process(protocol_interface_info_entry_t *c
return true;
}

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){
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
Expand Down Expand Up @@ -327,7 +351,7 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) ||
(thread_info(cur)->thread_leader_data->weighting != leaderData.weighting)) {
//parent changed partition/weight - reset own routing information
thread_old_partition_data_purge(cur->thread_info);
thread_old_partition_data_purge(cur);
}
//check if network data needs to be requested
if (!thread_bootstrap_request_network_data(cur, &leaderData, shortAddress)) {
Expand All @@ -347,7 +371,7 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
// 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)) {
(thread_info(cur)->thread_leader_data->weighting == leaderData.weighting)) {
// Create link to new neighbor no other processing allowed
thread_link_request_start(cur, mle_msg->packet_src_address);
return;
Expand All @@ -357,6 +381,10 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
return;
}
}
// process REED advertisement from higher partition
if (thread_reed_partitions_merge(cur, shortAddress, leaderData)) {
return;
}
} else {
//Router
if (!thread_router_leader_data_process(cur, mle_msg->packet_src_address, &leaderData, &routeTlv, entry_temp) ) {
Expand Down Expand Up @@ -549,7 +577,7 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) {
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData.leaderRouterId;
thread_info(cur)->thread_leader_data->partitionId = leaderData.partitionId;
thread_old_partition_data_purge(cur->thread_info);
thread_old_partition_data_purge(cur);
accept_new_data = true;
}

Expand Down Expand Up @@ -688,7 +716,7 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) {
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData.leaderRouterId;
thread_info(cur)->thread_leader_data->partitionId = leaderData.partitionId;
thread_old_partition_data_purge(cur->thread_info);
thread_old_partition_data_purge(cur);
}
//Check Network Data TLV
if (mle_tlv_read_tlv(MLE_TYPE_NETWORK_DATA, mle_msg->data_ptr, mle_msg->data_length, &networkDataTlv)) {
Expand Down

0 comments on commit 3fb6390

Please sign in to comment.