Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
thread_management_if.c
00001 /* 00002 * Copyright (c) 2014-2019, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: BSD-3-Clause 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the copyright holder nor the 00014 * names of its contributors may be used to endorse or promote products 00015 * derived from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00021 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 * POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 #include "nsconfig.h" 00030 #include <string.h> 00031 #include "ns_types.h" 00032 #include "mlme.h" 00033 #include "NWK_INTERFACE/Include/protocol.h" 00034 #include "thread_management_if.h" 00035 #include <nsdynmemLIB.h> 00036 #include "eventOS_event.h" 00037 #include <ns_list.h> 00038 #include <net_thread_test.h> 00039 #include <net_ipv6_api.h> 00040 #include "ns_trace.h" 00041 #include "Core/include/ns_buffer.h" 00042 #include "common_functions.h" 00043 #include "6LoWPAN/Thread/thread_config.h" 00044 #include "6LoWPAN/Thread/thread_common.h" 00045 #include "6LoWPAN/Thread/thread_bootstrap.h" 00046 #include "6LoWPAN/Thread/thread_border_router_api_internal.h" 00047 #include "6LoWPAN/Thread/thread_routing.h" 00048 #include "6LoWPAN/Thread/thread_network_data_lib.h" 00049 #include "6LoWPAN/Thread/thread_network_data_storage.h" 00050 #include "6LoWPAN/Thread/thread_leader_service.h" 00051 #include "6LoWPAN/Thread/thread_nd.h" 00052 #include "thread_diagnostic.h" 00053 #include "DHCPv6_client/dhcpv6_client_api.h" 00054 #include "6LoWPAN/Thread/thread_discovery.h" 00055 #include "6LoWPAN/Thread/thread_network_synch.h" 00056 #include "6LoWPAN/Thread/thread_management_internal.h" 00057 #include "6LoWPAN/Thread/thread_management_server.h" 00058 #include "6LoWPAN/Thread/thread_joiner_application.h" 00059 #include "6LoWPAN/Thread/thread_management_client.h" 00060 #include "6LoWPAN/Thread/thread_nvm_store.h" 00061 #include "6LoWPAN/Thread/thread_ccm.h" 00062 #include "6LoWPAN/Thread/thread_tmfcop_lib.h" 00063 #include "6LoWPAN/Thread/thread_constants.h" 00064 #include "6LoWPAN/Thread/thread_bbr_api_internal.h" 00065 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00066 #include "Service_Libs/mle_service/mle_service_security.h" 00067 #include "RPL/rpl_control.h" // insanity - bootstraps shouldn't be doing each others' clean-up 00068 #include "MLE/mle.h" 00069 #include "MLE/mle_tlv.h" 00070 #include "thread_meshcop_lib.h" 00071 #include "thread_commissioning_if.h" 00072 #include "shalib.h" 00073 #include "Common_Protocols/icmpv6.h" 00074 #include "DHCPv6_Server/DHCPv6_server_service.h" 00075 #include "6LoWPAN/Thread/thread_dhcpv6_server.h" 00076 #include "Service_Libs/mle_service/mle_service_api.h" 00077 #include "Service_Libs/blacklist/blacklist.h" 00078 #include "6LoWPAN/MAC/mac_helper.h" 00079 #include "6LoWPAN/MAC/mac_pairwise_key.h" 00080 #include "6LoWPAN/MAC/mpx_api.h" 00081 #include "6LoWPAN/lowpan_adaptation_interface.h" 00082 #include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" 00083 #include "mac_common_defines.h" 00084 #include "mlme.h" 00085 #include "mac_api.h" 00086 00087 #ifdef HAVE_THREAD 00088 #define TRACE_GROUP "thrm" 00089 00090 static const uint8_t thread_discovery_key[16] = {0x78, 0x58, 0x16, 0x86, 0xfd, 0xb4, 0x58, 0x0f, 0xb0, 0x92, 0x54, 0x6a, 0xec, 0xbd, 0x15, 0x66}; 00091 static const uint8_t thread_discovery_extented_address[8] = {0x35, 0x06, 0xfe, 0xb8, 0x23, 0xd4, 0x87, 0x12}; 00092 00093 uint32_t thread_delay_timer_default = THREAD_DELAY_TIMER_DEFAULT_SECONDS; 00094 uint32_t thread_router_selection_jitter = THREAD_ROUTER_SELECTION_JITTER; 00095 uint16_t thread_joiner_port = THREAD_DEFAULT_JOINER_PORT; 00096 uint8_t thread_max_mcast_addr = THREAD_MCAST_ADDR_PER_MSG; 00097 00098 /* 00099 * Prototypes 00100 */ 00101 00102 static void thread_discover_key_descriptor_set(struct mac_api_s *api, const uint8_t *key, uint8_t id, uint32_t key32_bit_src, uint8_t attribute_index) 00103 { 00104 mlme_set_t set_req; 00105 mlme_key_id_lookup_descriptor_t lookup_description; 00106 mlme_key_descriptor_entry_t key_description; 00107 mlme_key_device_descriptor_t dev_descriptor; 00108 if (key) { 00109 memset(lookup_description.LookupData, 0, 9); 00110 common_write_32_bit(key32_bit_src, lookup_description.LookupData); 00111 lookup_description.LookupData[4] = id; 00112 lookup_description.LookupDataSize = 0; 00113 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00114 memcpy(key_description.Key, key, 16); 00115 key_description.KeyIdLookupList = &lookup_description; 00116 key_description.KeyIdLookupListEntries = 1; 00117 dev_descriptor.Blacklisted = false; 00118 dev_descriptor.DeviceDescriptorHandle = attribute_index; 00119 dev_descriptor.UniqueDevice = true; 00120 key_description.KeyDeviceList = &dev_descriptor; 00121 key_description.KeyDeviceListEntries = 1; 00122 00123 } else { 00124 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00125 } 00126 set_req.attr = macKeyTable; 00127 set_req.attr_index = 3; //Allwayd firth key 00128 set_req.value_pointer = &key_description; 00129 set_req.value_size = sizeof(mlme_key_descriptor_entry_t); 00130 00131 api->mlme_req(api, MLME_SET, &set_req); 00132 } 00133 00134 static void thread_discover_device_descriptor_set(struct mac_api_s *api, const uint8_t *device_extended_address, uint8_t attribute_index) 00135 { 00136 if (!api) { 00137 return; 00138 } 00139 00140 mlme_device_descriptor_t device_desc; 00141 mlme_set_t set_req; 00142 device_desc.FrameCounter = 0; 00143 device_desc.Exempt = false; 00144 device_desc.ShortAddress = 0xffff; 00145 memcpy(device_desc.ExtAddress, device_extended_address, 8); 00146 device_desc.PANId = 0xffff; 00147 00148 00149 set_req.attr = macDeviceTable; 00150 set_req.attr_index = attribute_index; 00151 set_req.value_pointer = (void *)&device_desc; 00152 set_req.value_size = sizeof(mlme_device_descriptor_t); 00153 tr_debug("Register Discovery device descriptor"); 00154 api->mlme_req(api, MLME_SET, &set_req); 00155 } 00156 00157 static void thread_discover_security_material_update(protocol_interface_info_entry_t *cur, const mlme_security_t *security_params) 00158 { 00159 if (!security_params || !cur) { 00160 return; 00161 } 00162 00163 if (security_params->SecurityLevel != SEC_ENC_MIC32 || security_params->KeyIdMode != MAC_KEY_ID_MODE_SRC4_IDX || security_params->KeyIndex != THREAD_DISCOVERY_SECURITY_KEY_INDEX) { 00164 return; 00165 } 00166 mac_description_storage_size_t buffer; 00167 if (common_read_32_bit(security_params->Keysource) != THREAD_DISCOVERY_SECURITY_KEY_SOURCE) { 00168 return; 00169 } 00170 00171 if (!cur->mac_api || !cur->mac_api->mac_storage_sizes_get || cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) { 00172 return; 00173 } 00174 thread_discover_device_descriptor_set(cur->mac_api, thread_discovery_extented_address, buffer.device_decription_table_size - 1); 00175 } 00176 00177 static void thread_security_trig_pending_key(protocol_interface_info_entry_t *cur) 00178 { 00179 if (cur->mac_parameters->mac_next_key_index) { 00180 00181 //Call MAC Key Update 00182 uint8_t key_id = cur->mac_parameters->mac_next_key_index; 00183 00184 mac_helper_security_key_swap_next_to_default(cur); 00185 00186 if (mle_service_security_key_trig(cur->id, key_id)) { 00187 thread_security_update_from_mac(cur); 00188 } 00189 } 00190 } 00191 00192 static void thread_mac_security_key_update_cb(protocol_interface_info_entry_t *cur, const mlme_security_t *security_params) 00193 { 00194 if (!cur->thread_info || !cur->mac_parameters) { 00195 return; 00196 } 00197 if (cur->mac_parameters->mac_next_key_index && (security_params->KeyIndex == cur->mac_parameters->mac_next_key_index)) { 00198 if (cur->thread_info->masterSecretMaterial.keySwitchGuardTimer == 0) { 00199 tr_debug("Trig Next Key"); 00200 thread_security_trig_pending_key(cur); 00201 } 00202 } else { 00203 thread_discover_security_material_update(cur, security_params); 00204 } 00205 } 00206 00207 int8_t thread_node_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode) 00208 { 00209 protocol_interface_info_entry_t *cur; 00210 uint8_t table_size = 4; 00211 00212 cur = protocol_stack_interface_info_get_by_id(interface_id); 00213 if (!cur) { 00214 return -1; 00215 } 00216 00217 //Read MAC device table sizes 00218 mac_description_storage_size_t buffer; 00219 if (!cur->mac_api || !cur->mac_api->mac_storage_sizes_get || cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) { 00220 return -1; 00221 } 00222 00223 cur->configure_flags &= ~INTERFACE_BOOTSTRAP_DEFINED; 00224 mac_pairwise_key_interface_unregister(cur->id); 00225 00226 if (buffer.key_description_table_size < 4) { 00227 tr_error("MAC key_description_table_size too short %d<4", buffer.key_description_table_size); 00228 return -1; 00229 } 00230 00231 switch (bootstrap_mode) { 00232 case NET_6LOWPAN_HOST: 00233 case NET_6LOWPAN_SLEEPY_HOST: 00234 protocol_6lowpan_host_init(cur, bootstrap_mode == NET_6LOWPAN_SLEEPY_HOST); 00235 break; 00236 00237 case NET_6LOWPAN_ROUTER: 00238 protocol_6lowpan_router_init(cur); 00239 table_size = buffer.key_description_table_size; 00240 break; 00241 00242 default: 00243 return -3; 00244 } 00245 00246 if (mac_pairwise_key_interface_register(cur->id, table_size, 4) < 0) { 00247 tr_error("MAC pairwise key in registration failed"); 00248 return -1; 00249 } 00250 00251 if (blacklist_init() != 0) { 00252 tr_debug("6LoWPAN MLE blacklist init failed."); 00253 return -1; 00254 } 00255 00256 blacklist_params_set( 00257 THREAD_BLACKLIST_ENTRY_LIFETIME, 00258 THREAD_BLACKLIST_TIMER_MAX_TIMEOUT, 00259 THREAD_BLACKLIST_TIMER_TIMEOUT, 00260 THREAD_BLACKLIST_ENTRY_MAX_NBR, 00261 THREAD_BLACKLIST_PURGE_NBR, 00262 THREAD_BLACKLIST_PURGE_TIMER_TIMEOUT); 00263 00264 if (thread_info_allocate_and_init(cur) < 0) { 00265 mac_pairwise_key_interface_unregister(cur->id); 00266 return -3; 00267 } 00268 00269 if (thread_discovery_init(cur->id, cur, thread_info(cur)->version, bootstrap_mode == NET_6LOWPAN_ROUTER) != 0) { 00270 tr_error("Discovery init fail"); 00271 mac_pairwise_key_interface_unregister(cur->id); 00272 return -3; 00273 } 00274 00275 cur->configure_flags |= INTERFACE_BOOTSTRAP_DEFINED; 00276 cur->lowpan_info |= INTERFACE_NWK_BOOTSRAP_MLE; 00277 rpl_control_remove_domain_from_interface(cur); 00278 //SET MAC key id mode 2 key and device 00279 thread_discover_key_descriptor_set(cur->mac_api, thread_discovery_key, THREAD_DISCOVERY_SECURITY_KEY_INDEX, THREAD_DISCOVERY_SECURITY_KEY_SOURCE, buffer.device_decription_table_size - 1); 00280 00281 thread_discover_device_descriptor_set(cur->mac_api, thread_discovery_extented_address, buffer.device_decription_table_size - 1); 00282 00283 cur->mac_security_key_usage_update_cb = thread_mac_security_key_update_cb; 00284 return 0; 00285 } 00286 00287 00288 void arm_thread_private_ula_prefix_set(protocol_interface_info_entry_t *cur, const uint8_t *ula_prefix) 00289 { 00290 //Define Local Thread 00291 memcpy(cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, ula_prefix, 8); 00292 cur->thread_info->threadPrivatePrefixInfo.ulaValid = true; 00293 } 00294 00295 /** 00296 * Calculate New Key Material by given security key material and sequency number 00297 * 00298 * \param key Thread Master key pointer 00299 * \param key_material_buf Buffer for calculated MAC & MLE key: first 128-bit for MLE and rest 128-bit for MAC 00300 * \param threadSequency Key material key index. 00301 * 00302 */ 00303 void thread_key_get(uint8_t *key, uint8_t *key_material_buf, uint32_t key_sequence_counter) 00304 { 00305 static uint8_t key_seed[6] = {'T', 'h', 'r', 'e', 'a', 'd'}; 00306 static uint8_t temp32_buf[4]; 00307 common_write_32_bit(key_sequence_counter, temp32_buf); 00308 SHALIB_init_HMAC(key, 16); 00309 SHALIB_push_data_HMAC(temp32_buf, 4); 00310 SHALIB_push_data_HMAC(key_seed, 6); 00311 SHALIB_finish_HMAC(key_material_buf, 8); 00312 } 00313 00314 /** 00315 * Thread key sequence & key synch 00316 * 00317 */ 00318 void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce) 00319 { 00320 protocol_interface_info_entry_t *cur; 00321 link_configuration_s *linkConfiguration; 00322 linkConfiguration = thread_joiner_application_get_config(interface_id); 00323 if (!linkConfiguration) { 00324 return; 00325 } 00326 cur = protocol_stack_interface_info_get_by_id(interface_id); 00327 if (!cur || !cur->thread_info) { 00328 return; 00329 } 00330 if (!cur->thread_info->masterSecretMaterial.valid_Info) { 00331 return; 00332 } 00333 //tr_debug("Sync key material by %"PRIu32, keySequnce); 00334 00335 if (keySequnce <= linkConfiguration->key_sequence) { 00336 // Smaller or equal request ignored 00337 //tr_debug("Sync key material no change"); 00338 return; 00339 } 00340 if ((cur->thread_info->masterSecretMaterial.keySwitchGuardTimer > 0)) { 00341 // Guard time prevent the change 00342 //tr_debug("Sync key material guard blocked"); 00343 return; 00344 } 00345 // Calculate new keys 00346 tr_debug("Sync key material by %"PRIu32, keySequnce); 00347 thread_management_key_sets_calc(cur, linkConfiguration, keySequnce); 00348 thread_key_guard_timer_calculate(cur, linkConfiguration, false); 00349 } 00350 00351 static void thread_history_key_material_push(thread_info_t *thread_info, uint8_t *mleKeyPtr, uint8_t keyId) 00352 { 00353 thread_info->masterSecretMaterial.historyKeyValid = true; 00354 thread_info->masterSecretMaterial.historyKeyId = keyId; 00355 memcpy(thread_info->masterSecretMaterial.historyKey, mleKeyPtr, 16); 00356 } 00357 00358 void thread_security_update_from_mac(protocol_interface_info_entry_t *cur) 00359 { 00360 uint8_t *mleKey; 00361 uint8_t historyKeyId; 00362 link_configuration_s *linkConfiguration; 00363 linkConfiguration = thread_joiner_application_get_config(cur->id); 00364 if (!linkConfiguration) { 00365 return; 00366 } 00367 00368 mleKey = mle_service_security_next_key_get(cur->id); 00369 if (!mleKey) { 00370 return; 00371 } 00372 historyKeyId = mle_service_security_next_key_id_get(cur->id); 00373 00374 /* Set old secondary to history */ 00375 thread_history_key_material_push(cur->thread_info, mleKey, historyKeyId); 00376 linkConfiguration->key_sequence++; 00377 mac_helper_link_frame_counter_set(cur->id, 0); 00378 thread_security_next_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence); 00379 thread_key_guard_timer_calculate(cur, linkConfiguration, false); 00380 } 00381 00382 void thread_security_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence) 00383 { 00384 uint8_t key_material[32]; 00385 uint8_t key_index; 00386 //primary key is generated from the current value of sequence counter 00387 uint32_t thrKeySequenceCounter = keySequence; 00388 /* Produced keys from Thread security material: MAC key | MLE key */ 00389 thread_key_get(masterKey, key_material, thrKeySequenceCounter); 00390 /* Update keys as primary keys */ 00391 key_index = THREAD_KEY_INDEX(thrKeySequenceCounter); 00392 tr_debug("Set current key Id: %u", key_index); 00393 mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); 00394 mle_service_security_set_security_key(cur->id, key_material, key_index, true); 00395 } 00396 00397 00398 void thread_security_prev_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence) 00399 { 00400 uint8_t key_material[32]; 00401 uint8_t key_index; 00402 uint32_t thrKeySequenceCounter; 00403 if (keySequence == 0) { 00404 // in initial value there is no prev available 00405 return; 00406 } 00407 thrKeySequenceCounter = keySequence - 1; 00408 /* Produced keys from Thread security material: MAC key | MLE key */ 00409 thread_key_get(masterKey, key_material, thrKeySequenceCounter); 00410 /* Update keys as primary keys */ 00411 key_index = THREAD_KEY_INDEX(thrKeySequenceCounter); 00412 tr_debug("Set previous key Id: %u", key_index); 00413 mac_helper_security_prev_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); 00414 mle_service_security_set_security_key(cur->id, key_material, key_index, false); 00415 //copy master secret material to history 00416 thread_history_key_material_push(cur->thread_info, key_material, key_index); 00417 } 00418 00419 void thread_security_next_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence) 00420 { 00421 uint8_t key_material[32]; 00422 uint8_t key_index; 00423 uint32_t thrKeySequenceCounter; 00424 /* Will wrap modulo 32 bits */ 00425 thrKeySequenceCounter = keySequence + 1; 00426 /* Produced keys from Thread security material: MAC key | MLE key */ 00427 thread_key_get(masterKey, key_material, thrKeySequenceCounter); 00428 /* Update keys as non-primary keys */ 00429 key_index = THREAD_KEY_INDEX(thrKeySequenceCounter); 00430 tr_debug("Set next key Id: %u", key_index); 00431 mac_helper_security_next_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); /* Auth counter not relevant for Thread */ 00432 mle_service_security_set_security_key(cur->id, key_material, key_index, false); 00433 } 00434 00435 int thread_management_key_sets_calc(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, uint32_t thrKeySequenceCounter) 00436 { 00437 int ret_val = -1; 00438 00439 if (thrKeySequenceCounter == linkConfiguration->key_sequence) { 00440 /* Same key - do not change */ 00441 ret_val = 0; 00442 } else if (thrKeySequenceCounter == (linkConfiguration->key_sequence + 1)) { 00443 /* Next key - trig pending key */ 00444 thread_security_trig_pending_key(cur); 00445 ret_val = 0; 00446 } else { 00447 /* Generate new key set */ 00448 //Clean All Keys 00449 mac_helper_security_key_clean(cur); 00450 00451 // Update key sequence 00452 linkConfiguration->key_sequence = thrKeySequenceCounter; 00453 // Zero all frame counters. MLE does it automatically 00454 mac_helper_link_frame_counter_set(cur->id, 0); 00455 // Store all frame counters as zero and update the sequence counter 00456 thread_nvm_store_fast_data_write_all(0, 0, thrKeySequenceCounter); 00457 00458 thread_security_prev_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence); 00459 thread_security_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence); 00460 thread_security_next_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence); 00461 ret_val = 0; 00462 } 00463 return ret_val; 00464 } 00465 00466 int thread_management_get_my_iid16(int8_t interface_id, uint8_t *iidPtr) 00467 { 00468 protocol_interface_info_entry_t *cur; 00469 cur = protocol_stack_interface_info_get_by_id(interface_id); 00470 if (!cur) { 00471 return -1; 00472 } 00473 00474 if (!cur->thread_info) { 00475 return -1; 00476 } 00477 00478 if (thread_attach_ready(cur) != 0) { 00479 return -1; 00480 } 00481 00482 if (!cur->thread_info->threadPrivatePrefixInfo.ulaValid) { 00483 return -1; 00484 } 00485 00486 memcpy(iidPtr, ADDR_SHORT_ADR_SUFFIC, 6); 00487 common_write_16_bit(mac_helper_mac16_address_get(cur), (iidPtr + 6)); 00488 00489 return 0; 00490 } 00491 00492 int thread_management_get_current_keysequence(int8_t interface_id, uint32_t *sequencePtr) 00493 { 00494 00495 link_configuration_s *linkConfiguration; 00496 linkConfiguration = thread_joiner_application_get_config(interface_id); 00497 if (!linkConfiguration) { 00498 return -1; 00499 } 00500 protocol_interface_info_entry_t *cur; 00501 cur = protocol_stack_interface_info_get_by_id(interface_id); 00502 if (!cur) { 00503 return -1; 00504 } 00505 00506 if (!cur->thread_info) { 00507 return -1; 00508 } 00509 00510 if (!cur->thread_info->masterSecretMaterial.valid_Info) { 00511 return -1; 00512 } 00513 00514 *sequencePtr = linkConfiguration->key_sequence; 00515 00516 return 0; 00517 } 00518 00519 int thread_management_increment_key_sequence_counter(int8_t interface_id) 00520 { 00521 protocol_interface_info_entry_t *cur; 00522 00523 cur = protocol_stack_interface_info_get_by_id(interface_id); 00524 if (cur && cur->thread_info) { 00525 /* Not sure if this check is needed - not sure exactly what the flag means! */ 00526 if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) == 0) { 00527 return -1; 00528 } 00529 00530 if ((cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED) == 0) { 00531 return -1; 00532 } 00533 00534 //Trig Pending Key 00535 thread_security_trig_pending_key(cur); 00536 return 0; 00537 } 00538 return -1; 00539 } 00540 00541 int thread_management_get_ml_prefix(int8_t interface_id, uint8_t *prefix_ptr) 00542 { 00543 // TODO get from static configuration 00544 protocol_interface_info_entry_t *cur; 00545 cur = protocol_stack_interface_info_get_by_id(interface_id); 00546 if (!cur || !prefix_ptr) { 00547 return -1; 00548 } 00549 00550 if (!cur->thread_info) { 00551 return -1; 00552 } 00553 00554 if (thread_attach_ready(cur) != 0) { 00555 return -1; 00556 } 00557 00558 if (!cur->thread_info->threadPrivatePrefixInfo.ulaValid) { 00559 return -1; 00560 } 00561 00562 memcpy(prefix_ptr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, 8); 00563 00564 return 0; 00565 } 00566 00567 /* Get my mesh local prefix /112 */ 00568 int thread_management_get_ml_prefix_112(int8_t interface_id, uint8_t *prefix_ptr) 00569 { 00570 protocol_interface_info_entry_t *cur; 00571 cur = protocol_stack_interface_info_get_by_id(interface_id); 00572 if (!cur || !prefix_ptr) { 00573 return -1; 00574 } 00575 00576 if (!cur->thread_info) { 00577 return -1; 00578 } 00579 00580 if (thread_attach_ready(cur) != 0) { 00581 return -1; 00582 } 00583 00584 if (!cur->thread_info->threadPrivatePrefixInfo.ulaValid) { 00585 return -1; 00586 } 00587 00588 memcpy(prefix_ptr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, 8); 00589 memcpy(prefix_ptr + 8, ADDR_SHORT_ADR_SUFFIC, 6); 00590 00591 return 0; 00592 } 00593 00594 #endif 00595 00596 /** 00597 * Public interface functions. 00598 */ 00599 00600 /** 00601 * Set DHCPV6 server for Thread GP data purpose 00602 * 00603 * \param interface_id Network Interface 00604 * \param prefix_ptr pointer DHCPv6 Server Given Prefix 00605 * 00606 * return 0, Set OK 00607 * return <0 Set Not OK 00608 */ 00609 int thread_dhcpv6_server_add(int8_t interface_id, uint8_t *prefix_ptr, uint32_t max_client_cnt, bool stableData) 00610 { 00611 #if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER) 00612 protocol_interface_info_entry_t *cur; 00613 thread_prefix_tlv_t prefixTlv; 00614 thread_border_router_tlv_entry_t service; 00615 uint8_t temp[16]; 00616 uint8_t *ptr = temp; 00617 00618 cur = protocol_stack_interface_info_get_by_id(interface_id); 00619 if (!cur) { 00620 return -1; 00621 } 00622 00623 if (!cur->thread_info) { 00624 return -1; 00625 } 00626 00627 if (thread_dhcp6_server_init(interface_id, prefix_ptr, cur->mac, THREAD_MIN_PREFIX_LIFETIME) != 0) { 00628 tr_warn("SerVER alloc fail"); 00629 return -1; 00630 } 00631 00632 prefixTlv.domainId = 0; 00633 prefixTlv.Prefix = prefix_ptr; 00634 prefixTlv.PrefixLen = 64; 00635 00636 memset(&service, 0, sizeof(thread_border_router_tlv_entry_t)); 00637 service.Prf = 1; 00638 service.P_dhcp = true; 00639 service.P_on_mesh = true; 00640 service.stableData = stableData; 00641 00642 // SET maximum number of accepted clients 00643 DHCPv6_server_service_set_max_clients_accepts_count(interface_id, prefix_ptr, max_client_cnt); 00644 00645 tr_debug("GUA server Generate OK"); 00646 memcpy(ptr, prefix_ptr, 8); 00647 memset(ptr + 8, 0, 8); 00648 //Network Data 00649 if (thread_local_server_list_add_on_mesh_server(&cur->thread_info->localServerDataBase, &prefixTlv, &service) != 0) { 00650 return -1; 00651 } 00652 00653 return 0; 00654 #else 00655 (void) interface_id; 00656 (void) prefix_ptr; 00657 (void) max_client_cnt; 00658 (void) stableData; 00659 return -1; 00660 #endif 00661 } 00662 00663 int thread_dhcpv6_server_set_lifetime(int8_t interface_id, uint8_t *prefix_ptr, uint32_t valid_lifetime) 00664 { 00665 #if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER) 00666 if (!prefix_ptr) { 00667 return -1; 00668 } 00669 00670 return DHCPv6_server_service_set_address_validlifetime(interface_id, prefix_ptr, valid_lifetime); 00671 #else 00672 (void) interface_id; 00673 (void) prefix_ptr; 00674 (void) valid_lifetime; 00675 return -1; 00676 #endif 00677 } 00678 00679 int thread_dhcpv6_server_set_max_client(int8_t interface_id, uint8_t *prefix_ptr, uint32_t max_client_count) 00680 { 00681 #if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER) 00682 if (!prefix_ptr) { 00683 return -1; 00684 } 00685 00686 return DHCPv6_server_service_set_max_clients_accepts_count(interface_id, prefix_ptr, max_client_count); 00687 #else 00688 (void) interface_id; 00689 (void) prefix_ptr; 00690 (void) max_client_count; 00691 return -1; 00692 #endif 00693 } 00694 00695 int thread_dhcpv6_server_set_anonymous_addressing(int8_t interface_id, uint8_t *prefix_ptr, bool anonymous) 00696 { 00697 #if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER) 00698 if (!prefix_ptr) { 00699 return -1; 00700 } 00701 00702 return DHCPv6_server_service_set_address_autonous_flag(interface_id, prefix_ptr, anonymous); 00703 #else 00704 (void) interface_id; 00705 (void) prefix_ptr; 00706 (void) anonymous; 00707 return -1; 00708 #endif 00709 00710 } 00711 00712 00713 int thread_dhcpv6_server_delete(int8_t interface_id, uint8_t *prefix_ptr) 00714 { 00715 #if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER) 00716 uint8_t temp[16]; 00717 protocol_interface_info_entry_t *cur; 00718 thread_prefix_tlv_t prefixTlv; 00719 tr_debug("GUA server Delete"); 00720 cur = protocol_stack_interface_info_get_by_id(interface_id); 00721 if (!cur) { 00722 return -1; 00723 } 00724 00725 if (!cur->thread_info) { 00726 return -1; 00727 } 00728 00729 memcpy(temp, prefix_ptr, 8); 00730 memset(temp + 8, 0, 8); 00731 00732 prefixTlv.domainId = 0; 00733 prefixTlv.Prefix = prefix_ptr; 00734 prefixTlv.PrefixLen = 64; 00735 //Delete dhcp service 00736 DHCPv6_server_service_delete(interface_id, prefix_ptr, false); 00737 ipv6_route_delete(temp, 64, cur->id, NULL, ROUTE_THREAD); 00738 thread_local_server_list_del_on_mesh_server(&cur->thread_info->localServerDataBase, &prefixTlv); 00739 00740 return 0; 00741 #else 00742 (void) interface_id; 00743 (void) prefix_ptr; 00744 return -1; 00745 #endif 00746 } 00747 00748 #ifdef HAVE_THREAD 00749 static mac_neighbor_table_entry_t *neighbor_data_poll_referesh(protocol_interface_info_entry_t *cur, const uint8_t *address, addrtype_t type) 00750 { 00751 mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address, type); 00752 if (!entry || !entry->connected_device ) { 00753 return NULL; 00754 } 00755 00756 entry->lifetime = entry->link_lifetime ; 00757 return entry; 00758 } 00759 void thread_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t *status) 00760 { 00761 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id); 00762 if (!cur) { 00763 return; 00764 } 00765 mac_neighbor_table_entry_t *entry; 00766 00767 switch (status->status) { 00768 00769 case MLME_SECURITY_FAIL: 00770 00771 break; 00772 00773 case MLME_COUNTER_ERROR: 00774 00775 break; 00776 00777 case MLME_DATA_POLL_NOTIFICATION: 00778 entry = neighbor_data_poll_referesh(cur, status->SrcAddr, (addrtype_t)status->SrcAddrMode); 00779 if (entry) { 00780 thread_neighbor_communication_update(cur, entry->index ); 00781 } 00782 break; 00783 default: 00784 break; 00785 } 00786 } 00787 #endif 00788 00789 int thread_management_node_init( 00790 int8_t interface_id, 00791 channel_list_s *channel_list, 00792 device_configuration_s *device_configuration, 00793 link_configuration_s *static_configuration) 00794 { 00795 #ifdef HAVE_THREAD 00796 protocol_interface_info_entry_t *cur; 00797 nwk_scan_params_t *scan_params; 00798 00799 if (!device_configuration) { 00800 return -1; 00801 } 00802 00803 cur = protocol_stack_interface_info_get_by_id(interface_id); 00804 00805 if (!cur) { 00806 tr_warn("Invalid interface id"); 00807 return -1; 00808 } 00809 00810 if (!cur->thread_info) { 00811 tr_warn("Not Thread specific interface"); 00812 return -1; 00813 } 00814 00815 if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) != 0) { 00816 return -1; 00817 } 00818 00819 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER || cur->border_router_setup) { 00820 return -1; 00821 } 00822 00823 if (thread_init(cur) < 0) { 00824 thread_nd_service_delete(cur->id); 00825 tr_warn("Thread Boostarp Init Fail"); 00826 return -1; 00827 } 00828 if (thread_management_server_init(cur->id) != 0) { 00829 tr_warn("Thread management server init fail"); 00830 return -1; 00831 } 00832 00833 if (thread_diagnostic_init(cur->id) != 0) { 00834 tr_warn("Thread diagnostic init fail"); 00835 return -1; 00836 } 00837 //Store setup to application Joiner Application 00838 if (thread_joiner_application_init(cur->id, device_configuration, static_configuration) != 0) { 00839 tr_error("mandatory device configuration missing"); 00840 return -2; 00841 } 00842 00843 // Joiner application copies and massages the device configuration - switch to massaged version 00844 device_configuration = thread_joiner_application_get_device_config(cur->id); 00845 if (!device_configuration) { 00846 return -1; 00847 } 00848 cur->if_lowpan_security_params->nwk_security_mode = NET_SEC_MODE_NO_LINK_SECURITY; 00849 cur->mac_parameters->mac_configured_sec_level = 0; 00850 00851 // If no-one has already set a secret key, use the EUI-64 - Thread 00852 // wants RFC 7217 IIDs. Also ensure they're on for the Thread interface. 00853 // (Note that this will likely enable opaque IIDs on Ethernet too). 00854 if (!addr_opaque_iid_key_is_set()) { 00855 // Could we include some private key here? 00856 arm_nwk_ipv6_opaque_iid_key(device_configuration->eui64, 8); 00857 arm_nwk_ipv6_opaque_iid_enable(cur->id, true); 00858 } 00859 // Copy the channel list 00860 memset(&cur->mac_parameters->mac_channel_list, 0, sizeof(channel_list_s)); 00861 if (channel_list) { 00862 // Application has given limited set of channels 00863 cur->mac_parameters->mac_channel_list = *channel_list; 00864 } else { 00865 cur->mac_parameters->mac_channel_list.channel_page = CHANNEL_PAGE_0; 00866 cur->mac_parameters->mac_channel_list.channel_mask[0] = 0x07FFF800; 00867 } 00868 00869 scan_params = &cur->mac_parameters->nwk_scan_params; 00870 memset(&scan_params->stack_chan_list, 0, sizeof(channel_list_s)); 00871 if (channel_list) { 00872 // Application has given limited set of channels 00873 scan_params->stack_chan_list = *channel_list; 00874 } else { 00875 scan_params->stack_chan_list.channel_page = CHANNEL_PAGE_0; 00876 scan_params->stack_chan_list.channel_mask[0] = 0x07FFF800; 00877 } 00878 scan_params->scan_duration = 5; 00879 00880 cur->thread_info->masterSecretMaterial.valid_Info = false; 00881 thread_key_guard_timer_calculate(cur, static_configuration, true); 00882 00883 cur->thread_info->maxChildCount = THREAD_MAX_CHILD_COUNT; 00884 cur->thread_info->rfc6775 = false; 00885 cur->thread_info->host_link_timeout = THREAD_END_DEVICE_DEFAULT_TIMEOUT; 00886 /* Thread will manage the address query timing, and report negatives. Set this high so as not to interfere. */ 00887 cur->ipv6_neighbour_cache.retrans_timer = 10000; 00888 00889 // Set default partition weighting 00890 cur->thread_info->partition_weighting = THREAD_DEFAULT_WEIGHTING; 00891 00892 /* IP forwarding is off by default */ 00893 cur->ip_forwarding = false; 00894 00895 lowpan_adaptation_indirect_queue_params_set(cur, 00896 THREAD_INDIRECT_BIG_PACKET_THRESHOLD, 00897 THREAD_INDIRECT_BIG_PACKETS_TOTAL, 00898 THREAD_INDIRECT_SMALL_PACKETS_PER_CHILD); 00899 00900 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST) { 00901 cur->thread_info->requestFullNetworkData = false; 00902 } else { 00903 cur->thread_info->requestFullNetworkData = true; 00904 } 00905 00906 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION; 00907 cur->configure_flags |= INTERFACE_SECURITY_DEFINED; 00908 cur->comm_status_ind_cb = thread_comm_status_indication_cb; 00909 return 0; 00910 #else 00911 (void) interface_id; 00912 (void) channel_list; 00913 (void) device_configuration; 00914 (void) static_configuration; 00915 return -1; 00916 #endif 00917 } 00918 00919 int thread_management_device_type_set(int8_t interface_id, thread_device_type_e device_type) 00920 { 00921 #ifdef HAVE_THREAD 00922 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00923 00924 if (!cur || !cur->thread_info) { 00925 tr_warn("Not Thread specific interface"); 00926 return -1; 00927 } 00928 if (device_type == THREAD_DEVICE_REED) { 00929 // Change mode to router 00930 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER; 00931 } else if (device_type == THREAD_DEVICE_FED) { 00932 //FED devices makes links and makes address resolutions 00933 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_HOST; 00934 cur->thread_info->end_device_link_synch = true; 00935 } else if (device_type == THREAD_DEVICE_MED) { 00936 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_HOST; 00937 cur->thread_info->end_device_link_synch = false; 00938 } else if (device_type == THREAD_DEVICE_SED) { 00939 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST; 00940 cur->thread_info->end_device_link_synch = false; 00941 } 00942 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00943 // bootstrap active need to restart 00944 thread_bootstrap_reset_restart(interface_id); 00945 } 00946 00947 return 0; 00948 #else 00949 (void) interface_id; 00950 (void) device_type; 00951 return -1; 00952 #endif 00953 } 00954 00955 int thread_management_max_child_count( 00956 int8_t interface_id, 00957 uint8_t maxChildCount) 00958 { 00959 #ifdef HAVE_THREAD 00960 protocol_interface_info_entry_t *cur; 00961 00962 cur = protocol_stack_interface_info_get_by_id(interface_id); 00963 if (!cur) { 00964 tr_warn("Invalid interface id"); 00965 return -1; 00966 } 00967 00968 if (!cur->thread_info) { 00969 tr_warn("Not Thread specific interface"); 00970 return -1; 00971 } 00972 00973 mac_description_storage_size_t buffer; 00974 if (!cur->mac_api || !cur->mac_api->mac_storage_sizes_get || cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) { 00975 return -1; 00976 } 00977 00978 if (maxChildCount > buffer.device_decription_table_size) { 00979 tr_error("Accept values are between 0-%d for max Child count", buffer.device_decription_table_size); 00980 return -1; 00981 } 00982 cur->thread_info->maxChildCount = maxChildCount; 00983 return 0; 00984 #else 00985 (void) interface_id; 00986 (void) maxChildCount; 00987 return -1; 00988 #endif 00989 } 00990 00991 link_configuration_s *thread_management_configuration_get(int8_t interface_id) 00992 { 00993 #ifdef HAVE_THREAD 00994 return thread_joiner_application_get_config(interface_id); 00995 #else 00996 (void) interface_id; 00997 return NULL; 00998 #endif 00999 } 01000 01001 device_configuration_s *thread_management_device_configuration_get(int8_t interface_id) 01002 { 01003 #ifdef HAVE_THREAD 01004 return thread_joiner_application_get_device_config(interface_id); 01005 #else 01006 (void) interface_id; 01007 return NULL; 01008 #endif 01009 } 01010 01011 int thread_management_link_configuration_store(int8_t interface_id, link_configuration_s *link_config) 01012 { 01013 #ifdef HAVE_THREAD 01014 int ret = thread_joiner_application_link_configuration_store(interface_id, link_config); 01015 01016 if (interface_id == -1) { 01017 return ret; 01018 } 01019 01020 if (ret >= 0) { 01021 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01022 if (!link_config || !cur || !cur->thread_info) { 01023 return -2; 01024 } 01025 if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) != 0) { 01026 // take new settings into use after restart 01027 thread_bootstrap_reset_restart(interface_id); 01028 } 01029 } 01030 01031 return ret; 01032 #else 01033 (void) interface_id; 01034 (void) link_config; 01035 return -1; 01036 #endif 01037 } 01038 01039 int thread_management_link_configuration_add(int8_t interface_id, uint8_t *additional_ptr, uint8_t additional_len) 01040 { 01041 #ifdef HAVE_THREAD 01042 if (interface_id < 0) { 01043 return -1; 01044 } 01045 01046 int ret = thread_joiner_application_update_configuration(interface_id, additional_ptr, additional_len, true); 01047 if (ret != 0) { 01048 return ret; 01049 } 01050 01051 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01052 if (!cur || !cur->thread_info) { 01053 return -2; 01054 } 01055 if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) != 0) { 01056 // take new settings into use after restart 01057 thread_bootstrap_reset_restart(interface_id); 01058 } 01059 01060 return ret; 01061 #else 01062 (void) interface_id; 01063 (void) additional_ptr; 01064 (void) additional_len; 01065 return -1; 01066 #endif 01067 } 01068 01069 int thread_management_link_configuration_delete(int8_t interface_id) 01070 { 01071 #ifdef HAVE_THREAD 01072 int ret = thread_joiner_application_link_configuration_delete(interface_id); 01073 01074 if (interface_id == -1) { 01075 return ret; 01076 } 01077 01078 if (ret >= 0) { 01079 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01080 if (!cur || !cur->thread_info) { 01081 return -2; 01082 } 01083 if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) != 0) { 01084 thread_bootstrap_reset_restart(interface_id); 01085 } 01086 } 01087 return ret; 01088 #else 01089 (void) interface_id; 01090 return -1; 01091 #endif 01092 } 01093 01094 int thread_management_get_leader_address(int8_t interface_id, uint8_t *address_buffer) 01095 { 01096 #ifdef HAVE_THREAD 01097 01098 protocol_interface_info_entry_t *cur; 01099 01100 cur = protocol_stack_interface_info_get_by_id(interface_id); 01101 if (cur) { 01102 if ((cur->thread_info) && (thread_attach_ready(cur) == 0) && 01103 (cur->thread_info->threadPrivatePrefixInfo.ulaValid)) { 01104 thread_addr_write_mesh_local_16(address_buffer, thread_router_addr_from_id(cur->thread_info->thread_leader_data->leaderRouterId), cur->thread_info); 01105 return 0; 01106 } 01107 } 01108 return -1; 01109 #else 01110 (void) interface_id; 01111 (void) address_buffer; 01112 return -1; 01113 #endif 01114 } 01115 01116 int thread_management_get_leader_aloc(int8_t interface_id, uint8_t *address_buffer) 01117 { 01118 #ifdef HAVE_THREAD 01119 01120 protocol_interface_info_entry_t *cur; 01121 01122 cur = protocol_stack_interface_info_get_by_id(interface_id); 01123 if (cur) { 01124 if ((cur->thread_info) && (thread_attach_ready(cur) == 0) && 01125 (cur->thread_info->threadPrivatePrefixInfo.ulaValid)) { 01126 thread_addr_write_mesh_local_16(address_buffer, 0xfc00, cur->thread_info); 01127 return 0; 01128 } 01129 } 01130 return -1; 01131 #else 01132 (void) interface_id; 01133 (void) address_buffer; 01134 return -1; 01135 #endif 01136 } 01137 int thread_management_get_ml64_address(int8_t interface_id, uint8_t *address_ptr) 01138 { 01139 #ifdef HAVE_THREAD 01140 protocol_interface_info_entry_t *cur; 01141 cur = protocol_stack_interface_info_get_by_id(interface_id); 01142 if (!cur) { 01143 return -1; 01144 } 01145 01146 if (!address_ptr) { 01147 return -1; 01148 } 01149 01150 if (0 != thread_management_get_ml_prefix(interface_id, address_ptr)) { 01151 return -2; 01152 } 01153 01154 memcpy(&address_ptr[8], cur->iid_slaac, 8); 01155 return 0; 01156 #else 01157 (void) interface_id; 01158 (void) address_ptr; 01159 return -1; 01160 #endif 01161 } 01162 01163 int thread_management_get_ml16_address(int8_t interface_id, uint8_t *address_ptr) 01164 { 01165 #ifdef HAVE_THREAD 01166 if (!address_ptr) { 01167 return -1; 01168 } 01169 01170 if (0 != thread_management_get_ml_prefix(interface_id, address_ptr)) { 01171 return -2; 01172 } 01173 01174 if (0 != thread_management_get_my_iid16(interface_id, address_ptr + 8)) { 01175 return -2; 01176 } 01177 01178 return 0; 01179 #else 01180 (void) interface_id; 01181 (void) address_ptr; 01182 return -1; 01183 #endif 01184 } 01185 01186 int thread_management_get_parent_address(int8_t interface_id, uint8_t *address_ptr) 01187 { 01188 #ifdef HAVE_THREAD 01189 protocol_interface_info_entry_t *cur; 01190 cur = protocol_stack_interface_info_get_by_id(interface_id); 01191 01192 if (!cur || !cur->thread_info || !address_ptr) { 01193 return -1; 01194 } 01195 memset(address_ptr, 0, 16); 01196 if (cur->thread_info->thread_endnode_parent) { 01197 memcpy(address_ptr, ADDR_LINK_LOCAL_PREFIX, 8); 01198 address_ptr += 8; 01199 memcpy(address_ptr, cur->thread_info->thread_endnode_parent->mac64, 8); 01200 *address_ptr ^= 2; 01201 } 01202 01203 return 0; 01204 #else 01205 (void) interface_id; 01206 (void) address_ptr; 01207 return -1; 01208 #endif 01209 } 01210 01211 int thread_management_get_commissioner_address(int8_t interface_id, uint8_t *address_ptr, uint16_t *port_ptr) 01212 { 01213 #ifdef HAVE_THREAD 01214 protocol_interface_info_entry_t *cur; 01215 cur = protocol_stack_interface_info_get_by_id(interface_id); 01216 01217 if (!cur || !cur->thread_info || !address_ptr) { 01218 return -1; 01219 } 01220 01221 if (!cur->thread_info->registered_commissioner.commissioner_valid) { 01222 return -2; 01223 } 01224 memcpy(address_ptr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, 8); 01225 memcpy(address_ptr + 8, ADDR_SHORT_ADR_SUFFIC, 6); 01226 common_write_16_bit(0xfc30 + (cur->thread_info->registered_commissioner.session_id % 8), address_ptr + 14); 01227 01228 if (port_ptr) { 01229 *port_ptr = THREAD_MANAGEMENT_PORT;// Default commissioner port 01230 } 01231 01232 return 0; 01233 #else 01234 (void) interface_id; 01235 (void) address_ptr; 01236 (void) port_ptr; 01237 return -1; 01238 #endif 01239 } 01240 int8_t thread_management_set_link_timeout(int8_t interface_id, uint32_t link_timeout) 01241 { 01242 #ifdef HAVE_THREAD 01243 protocol_interface_info_entry_t *cur; 01244 01245 cur = protocol_stack_interface_info_get_by_id(interface_id); 01246 if (!cur) { 01247 tr_warn("Invalid interface id"); 01248 return -1; 01249 } 01250 thread_info_t *thread = cur->thread_info; 01251 if (!thread) { 01252 tr_warn("Thread not active"); 01253 return -2; 01254 } 01255 tr_info("set new link timeout %"PRIu32" , old value %"PRIu32"", link_timeout, thread->host_link_timeout); 01256 thread->host_link_timeout = link_timeout; 01257 thread_bootstrap_child_update_trig(cur); 01258 return 0; 01259 #else 01260 (void) interface_id; 01261 (void) link_timeout; 01262 return -1; 01263 #endif 01264 } 01265 01266 int8_t thread_management_get_link_timeout(int8_t interface_id, uint32_t *link_timeout) 01267 { 01268 #ifdef HAVE_THREAD 01269 const protocol_interface_info_entry_t *cur; 01270 01271 if (!link_timeout) { 01272 tr_warn("Invalid input ptr"); 01273 return -3; 01274 } 01275 cur = protocol_stack_interface_info_get_by_id(interface_id); 01276 if (!cur) { 01277 tr_warn("Invalid interface id"); 01278 return -1; 01279 } 01280 const thread_info_t *thread = cur->thread_info; 01281 if (!thread) { 01282 tr_warn("Thread not active"); 01283 return -2; 01284 } 01285 *link_timeout = thread->host_link_timeout; 01286 return 0; 01287 #else 01288 (void) interface_id; 01289 (void) link_timeout; 01290 return -1; 01291 #endif 01292 } 01293 01294 int8_t thread_management_set_request_full_nwk_data(int8_t interface_id, bool full_nwk_data) 01295 { 01296 #ifdef HAVE_THREAD 01297 protocol_interface_info_entry_t *cur; 01298 cur = protocol_stack_interface_info_get_by_id(interface_id); 01299 if (!cur) { 01300 tr_warn("Invalid interface id"); 01301 return -1; 01302 } 01303 if (!cur->thread_info) { 01304 tr_warn("Thread not active"); 01305 return -2; 01306 } 01307 if (cur->thread_info->requestFullNetworkData != full_nwk_data) { 01308 cur->thread_info->requestFullNetworkData = full_nwk_data; 01309 thread_bootstrap_child_update_trig(cur); 01310 } 01311 return 0; 01312 #else 01313 (void) interface_id; 01314 (void) full_nwk_data; 01315 return -1; 01316 #endif 01317 } 01318 01319 int8_t thread_management_get_request_full_nwk_data(int8_t interface_id, bool *full_nwk_data) 01320 { 01321 #ifdef HAVE_THREAD 01322 const protocol_interface_info_entry_t *cur; 01323 01324 if (!full_nwk_data) { 01325 tr_warn("Invalid input ptr"); 01326 return -3; 01327 } 01328 cur = protocol_stack_interface_info_get_by_id(interface_id); 01329 if (!cur) { 01330 tr_warn("Invalid interface id"); 01331 return -1; 01332 } 01333 if (!cur->thread_info) { 01334 tr_warn("Thread not active"); 01335 return -2; 01336 } 01337 *full_nwk_data = cur->thread_info->requestFullNetworkData; 01338 return 0; 01339 #else 01340 (void) interface_id; 01341 (void) full_nwk_data; 01342 return -1; 01343 #endif 01344 } 01345 01346 int thread_management_device_certificate_set(int8_t interface_id, const unsigned char *device_certificate_ptr, uint16_t device_certificate_len, const unsigned char *priv_key_ptr, uint16_t priv_key_len) 01347 { 01348 (void) device_certificate_ptr; 01349 (void) device_certificate_len; 01350 (void) priv_key_ptr; 01351 (void) priv_key_len; 01352 01353 #ifdef HAVE_THREAD 01354 protocol_interface_info_entry_t *cur; 01355 01356 cur = protocol_stack_interface_info_get_by_id(interface_id); 01357 if (!cur) { 01358 tr_warn("invalid interface id"); 01359 return -1; 01360 } 01361 01362 return thread_ccm_device_certificate_set(cur, device_certificate_ptr, device_certificate_len, priv_key_ptr, priv_key_len); 01363 01364 #else 01365 (void) interface_id; 01366 return -1; 01367 #endif 01368 } 01369 int thread_management_network_certificate_set(int8_t interface_id, const unsigned char *network_certificate_ptr, uint16_t network_certificate_len, const unsigned char *priv_key_ptr, uint16_t priv_key_len) 01370 { 01371 (void) network_certificate_ptr; 01372 (void) network_certificate_len; 01373 (void) priv_key_ptr; 01374 (void) priv_key_len; 01375 01376 #ifdef HAVE_THREAD 01377 protocol_interface_info_entry_t *cur; 01378 int ret_val; 01379 01380 cur = protocol_stack_interface_info_get_by_id(interface_id); 01381 if (!cur) { 01382 tr_debug("invalid interface id"); 01383 return -1; 01384 } 01385 01386 ret_val = thread_ccm_network_certificate_set(cur, network_certificate_ptr, network_certificate_len); 01387 if (0 > ret_val) { 01388 return -1; 01389 } 01390 01391 return thread_ccm_network_private_key_set(cur, priv_key_ptr, priv_key_len); 01392 #else 01393 (void) interface_id; 01394 return -1; 01395 #endif 01396 } 01397 01398 int thread_management_partition_weighting_set(int8_t interface_id, uint8_t partition_weighting) 01399 { 01400 #ifdef HAVE_THREAD 01401 protocol_interface_info_entry_t *cur; 01402 01403 cur = protocol_stack_interface_info_get_by_id(interface_id); 01404 if (!cur || !cur->thread_info) { 01405 tr_debug("Invalid interface id"); 01406 return -1; 01407 } 01408 01409 if (cur->thread_info->partition_weighting == partition_weighting) { 01410 return 0; 01411 } 01412 01413 bool trig_network_scan = false; 01414 if (cur->thread_info->thread_leader_data) { 01415 if (cur->thread_info->thread_leader_data->weighting < partition_weighting) { 01416 trig_network_scan = true; 01417 } 01418 } 01419 01420 cur->thread_info->partition_weighting = partition_weighting; 01421 01422 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 01423 if (trig_network_scan && thread_common_ccm_enabled(cur)) { 01424 thread_nvm_store_link_info_clear(); 01425 // bootstrap active and weighting has changed 01426 thread_bootstrap_reset_restart(interface_id); 01427 } 01428 } 01429 01430 return 0; 01431 #else 01432 (void) interface_id; 01433 (void) partition_weighting; 01434 return -1; 01435 #endif 01436 }
Generated on Tue Jul 12 2022 13:54:59 by
