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