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