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