Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
thread_test_api.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 00031 #include <string.h> 00032 #include <ns_list.h> 00033 #include <nsdynmemLIB.h> 00034 #include <net_thread_test.h> 00035 #include "randLIB.h" 00036 00037 #include "ns_trace.h" 00038 #include "common_functions.h" 00039 #include "NWK_INTERFACE/Include/protocol.h" 00040 #include "NWK_INTERFACE/Include/protocol_abstract.h" 00041 #include "6LoWPAN/Thread/thread_config.h" 00042 #include "6LoWPAN/Thread/thread_common.h" 00043 #include "6LoWPAN/Thread/thread_routing.h" 00044 #include "6LoWPAN/Thread/thread_joiner_application.h" 00045 #include "6LoWPAN/Thread/thread_leader_service.h" 00046 #include "6LoWPAN/Thread/thread_management_internal.h" 00047 #include "6LoWPAN/Thread/thread_bootstrap.h" 00048 #include "6LoWPAN/Thread/thread_router_bootstrap.h" 00049 #include "6LoWPAN/Thread/thread_discovery.h" 00050 #include "6LoWPAN/Thread/thread_nvm_store.h" 00051 #include "6LoWPAN/Thread/thread_extension_bootstrap.h" 00052 #include "MLE/mle.h" 00053 #include "thread_meshcop_lib.h" 00054 #include "thread_diagcop_lib.h" 00055 #include "coap_service_api.h" 00056 #include "Service_Libs/mle_service/mle_service_api.h" 00057 #include "6LoWPAN/MAC/mac_helper.h" 00058 00059 #define TRACE_GROUP "tapi" 00060 00061 00062 int_fast8_t arm_nwk_6lowpan_thread_test_add_neighbour( 00063 int8_t interface_id, 00064 uint16_t neighbour_short_addr, 00065 uint_fast8_t link_margin_db, 00066 uint8_t id_sequence, 00067 const uint8_t *id_mask, 00068 const uint8_t *route_data) 00069 { 00070 #ifdef HAVE_THREAD 00071 protocol_interface_info_entry_t *cur; 00072 cur = protocol_stack_interface_info_get_by_id(interface_id); 00073 if (!cur) { 00074 tr_warn("Invalid interface id"); 00075 return -1; 00076 } 00077 00078 return thread_routing_add_link(cur, neighbour_short_addr, link_margin_db, id_sequence, id_mask, route_data, true); 00079 #else 00080 (void)interface_id; 00081 (void)neighbour_short_addr; 00082 (void)link_margin_db; 00083 (void)id_sequence; 00084 (void)id_mask; 00085 (void)route_data; 00086 return -1; 00087 #endif 00088 } 00089 00090 int_fast8_t arm_nwk_6lowpan_thread_test_remove_neighbour( 00091 int8_t interface_id, 00092 uint16_t neighbour_short_addr) 00093 { 00094 #ifdef HAVE_THREAD 00095 protocol_interface_info_entry_t *cur; 00096 cur = protocol_stack_interface_info_get_by_id(interface_id); 00097 if (!cur) { 00098 tr_warn("Invalid interface id"); 00099 return -1; 00100 } 00101 00102 return thread_routing_remove_link(cur, neighbour_short_addr); 00103 #else 00104 (void)interface_id; 00105 (void)neighbour_short_addr; 00106 return -1; 00107 #endif 00108 00109 } 00110 00111 void arm_nwk_6lowpan_thread_test_print_routing_database(int8_t interface_id) 00112 { 00113 #if defined(FEA_TRACE_SUPPORT) && defined(HAVE_THREAD) 00114 const protocol_interface_info_entry_t *cur; 00115 00116 cur = protocol_stack_interface_info_get_by_id(interface_id); 00117 if (!cur) { 00118 tr_warn("Invalid interface id"); 00119 return; 00120 } 00121 00122 const thread_info_t *thread = cur->thread_info; 00123 if (!thread) { 00124 tr_warn("Thread not active"); 00125 return; 00126 } 00127 00128 //tr_debug("Thread routing database"); 00129 if (thread_i_am_router(cur)) { 00130 tr_info("I am Thread Router (ID: %d)", thread_router_id_from_addr(mac_helper_mac16_address_get(cur))); 00131 } else { 00132 tr_info("I am not a Thread Router"); 00133 } 00134 //tr_debug("Router ID Set + Current Route:"); 00135 if (thread_i_am_router(cur)) { 00136 for (int r = 0; r < N_THREAD_ROUTERS; r++) { 00137 if (thread->routing.fast_route_table[r] != FAST_ROUTE_INVALID_ID) { 00138 if (thread->routing.fast_route_table[r] == FAST_ROUTE_NO_ROUTE) { 00139 tr_debug("Current Route - fast no route: %d -> ?", r); 00140 } else { 00141 tr_debug("Current Route - fast route: %d -> %d", r, thread->routing.fast_route_table[r]); 00142 } 00143 } 00144 } 00145 } 00146 00147 ns_list_foreach(const thread_router_link_t, n, &thread->routing.link_set) { 00148 tr_debug("Link Set - Id:%d Margin:%d.%x InQ:%d OutQ:%d As good:%d Age:%ds", 00149 n->router_id, 00150 n->link_margin >> THREAD_LINK_MARGIN_SCALING, 00151 n->link_margin & ((1 << THREAD_LINK_MARGIN_SCALING) - 1), 00152 n->incoming_quality, 00153 n->outgoing_quality, 00154 n->as_good, 00155 n->age / 10); 00156 } 00157 00158 if (thread_i_am_router(cur)) { 00159 ns_list_foreach(const thread_route_t, route, &thread->routing.route_set) { 00160 tr_debug("Route Set - Dest:%d Next hop:%d Cost:%d", 00161 route->destination, 00162 route->next_hop, 00163 route->route_cost); 00164 } 00165 } 00166 #else 00167 (void)interface_id; 00168 #endif 00169 } 00170 00171 int8_t thread_routing_set_network_id_timeout(int8_t interface_id, uint16_t network_id_timeout) 00172 { 00173 #ifdef HAVE_THREAD 00174 const protocol_interface_info_entry_t *cur; 00175 00176 if( network_id_timeout < 5 ) { 00177 tr_warn("Too small timeout value, min: 5"); 00178 return -3; 00179 } 00180 00181 cur = protocol_stack_interface_info_get_by_id(interface_id); 00182 if (!cur) { 00183 tr_warn("Invalid interface id"); 00184 return -1; 00185 } 00186 if (!cur->thread_info) { 00187 tr_warn("Thread not active"); 00188 return -2; 00189 } 00190 cur->thread_info->routing.networkIdTimeout = network_id_timeout; 00191 return 0; 00192 #else 00193 (void)interface_id; 00194 (void)network_id_timeout; 00195 return -1; 00196 #endif 00197 } 00198 00199 int8_t thread_routing_get_network_id_timeout(int8_t interface_id, uint16_t *network_id_timeout) 00200 { 00201 #ifdef HAVE_THREAD 00202 const protocol_interface_info_entry_t *cur; 00203 00204 if(!network_id_timeout) { 00205 tr_warn("Invalid input ptr"); 00206 return -3; 00207 } 00208 cur = protocol_stack_interface_info_get_by_id(interface_id); 00209 if (!cur) { 00210 tr_warn("Invalid interface id"); 00211 return -1; 00212 } 00213 if (!cur->thread_info) { 00214 tr_warn("Thread not active"); 00215 return -2; 00216 } 00217 *network_id_timeout = cur->thread_info->routing.networkIdTimeout; 00218 return 0; 00219 #else 00220 (void)interface_id; 00221 (void)network_id_timeout; 00222 return -1; 00223 #endif 00224 } 00225 00226 int thread_test_set_context_id_reuse_timeout( 00227 int8_t interface_id, 00228 uint32_t timeout) 00229 { 00230 #ifdef HAVE_THREAD 00231 protocol_interface_info_entry_t *cur; 00232 00233 if (timeout < 60 || timeout > THREAD_CONTEXT_ID_REUSE_TIMEOUT) { 00234 return -1; 00235 } 00236 00237 cur = protocol_stack_interface_info_get_by_id(interface_id); 00238 if (!cur) { 00239 tr_warn("Invalid interface id"); 00240 return -1; 00241 } 00242 00243 if (!cur->thread_info) { 00244 tr_warn("Not Thread specific interface"); 00245 return -1; 00246 } 00247 00248 cur->thread_info->networkDataStorage.contex_id_reuse_timeout = timeout; 00249 return 0; 00250 #else 00251 (void)interface_id; 00252 (void)timeout; 00253 return -1; 00254 #endif 00255 } 00256 00257 int thread_test_remove_router_by_id(int8_t interface_id, uint8_t routerId) 00258 { 00259 #ifdef HAVE_THREAD 00260 protocol_interface_info_entry_t *cur; 00261 cur = protocol_stack_interface_info_get_by_id(interface_id); 00262 00263 if (!cur) { 00264 return -1; 00265 } 00266 00267 if (!cur->thread_info) { 00268 return -1; 00269 } 00270 00271 if (!cur->thread_info->leader_private_data) { 00272 return -1; 00273 } 00274 00275 if (thread_attach_ready(cur) != 0) { 00276 return -1; 00277 } 00278 00279 if (routerId >= 64) { 00280 return -1; 00281 } 00282 00283 if (!thread_leader_service_route_mask_bit_clear(cur->thread_info->leader_private_data, routerId)) { 00284 return -1; 00285 } 00286 00287 tr_debug("Release Routerid %x", routerId); 00288 thread_leader_service_update_id_set(cur); 00289 00290 return 0; 00291 #else 00292 (void)interface_id; 00293 (void)routerId; 00294 return -1; 00295 #endif 00296 } 00297 00298 int thread_test_router_downgrade(int8_t interface_id) 00299 { 00300 #ifdef HAVE_THREAD 00301 protocol_interface_info_entry_t *cur; 00302 cur = protocol_stack_interface_info_get_by_id(interface_id); 00303 00304 if (!cur) { 00305 return -1; 00306 } 00307 00308 if (!cur->thread_info) { 00309 return -1; 00310 } 00311 00312 if (thread_attach_ready(cur) != 0) { 00313 return -1; 00314 } 00315 00316 tr_debug("Trigger REED router downgrade process"); 00317 thread_bootstrap_attached_downgrade_router(cur); 00318 00319 return 0; 00320 #else 00321 (void)interface_id; 00322 return -1; 00323 #endif 00324 } 00325 00326 int thread_test_print_network_data(int8_t interface_id) 00327 { 00328 #ifdef HAVE_THREAD 00329 protocol_interface_info_entry_t *cur; 00330 cur = protocol_stack_interface_info_get_by_id(interface_id); 00331 if (!cur) { 00332 return -1; 00333 } 00334 00335 if (!cur->thread_info) { 00336 return -1; 00337 } 00338 00339 00340 if (thread_attach_ready(cur) != 0) { 00341 return -1; 00342 } 00343 00344 thread_nd_network_data_print(&cur->thread_info->networkDataStorage, mac_helper_mac16_address_get(cur)); 00345 00346 return 0; 00347 #else 00348 (void)interface_id; 00349 return -1; 00350 #endif 00351 } 00352 00353 00354 int8_t thread_reed_set_advertisement_interval(int8_t interface_id, uint16_t advertisement_interval, uint16_t jitter_interval) 00355 { 00356 #ifdef HAVE_THREAD 00357 const protocol_interface_info_entry_t *cur; 00358 00359 if(!advertisement_interval) { 00360 tr_warn("Invalid input ptr"); 00361 return -3; 00362 } 00363 cur = protocol_stack_interface_info_get_by_id(interface_id); 00364 if (!cur) { 00365 tr_warn("Invalid interface id"); 00366 return -1; 00367 } 00368 if (!cur->thread_info) { 00369 tr_warn("Thread not active"); 00370 return -2; 00371 } 00372 if (!jitter_interval){ 00373 jitter_interval = 0; 00374 } 00375 cur->thread_info->routerSelectParameters.reedAdvertisementInterval = (uint16_t) advertisement_interval; 00376 cur->thread_info->routerSelectParameters.reedAdvertisementJitterInterval = (uint16_t) jitter_interval; 00377 tr_debug("new advertisement interval set to %d seconds and jitter %d seconds",(uint16_t) advertisement_interval, (uint16_t) jitter_interval); 00378 return 0; 00379 #else 00380 (void)interface_id; 00381 (void)advertisement_interval; 00382 (void)jitter_interval; 00383 return -1; 00384 #endif 00385 } 00386 00387 int thread_test_key_sequence_counter_update(int8_t interface_id, uint32_t thrKeySequenceCounter) 00388 { 00389 #ifdef HAVE_THREAD 00390 int ret_val = -1; 00391 protocol_interface_info_entry_t *cur; 00392 link_configuration_s *linkConfiguration; 00393 linkConfiguration = thread_joiner_application_get_config(interface_id); 00394 if (!linkConfiguration) { 00395 return -1; 00396 } 00397 00398 cur = protocol_stack_interface_info_get_by_id(interface_id); 00399 if (cur && cur->thread_info) { 00400 /* Not sure if this check is needed - not sure exactly what the flag means! */ 00401 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00402 if (cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED) { 00403 if (thrKeySequenceCounter > linkConfiguration->key_sequence) { 00404 ret_val = thread_management_key_sets_calc(cur, linkConfiguration, thrKeySequenceCounter); 00405 } 00406 } 00407 } 00408 } 00409 return ret_val; 00410 #else 00411 (void)interface_id; 00412 (void)thrKeySequenceCounter; 00413 return -1; 00414 #endif 00415 } 00416 00417 int thread_test_stack_cache_reset(int8_t interface_id) 00418 { 00419 #ifdef HAVE_THREAD 00420 protocol_interface_info_entry_t *cur; 00421 00422 cur = protocol_stack_interface_info_get_by_id(interface_id); 00423 if (!cur) { 00424 tr_warn("Invalid interface id"); 00425 return -1; 00426 } 00427 00428 // Reset link information 00429 (void) thread_nvm_store_link_info_clear(); 00430 00431 return 0; 00432 #else 00433 (void)interface_id; 00434 return -1; 00435 #endif 00436 } 00437 00438 int thread_test_key_rotation_update(int8_t interface_id, uint32_t thrKeyRotation) 00439 { 00440 #ifdef HAVE_THREAD 00441 int ret_val = -1; 00442 protocol_interface_info_entry_t *cur; 00443 link_configuration_s *linkConfiguration; 00444 linkConfiguration = thread_joiner_application_get_config(interface_id); 00445 if (!linkConfiguration) { 00446 return -1; 00447 } 00448 00449 cur = protocol_stack_interface_info_get_by_id(interface_id); 00450 if (cur && cur->thread_info) { 00451 /* Not sure if this check is needed - not sure exactly what the flag means! */ 00452 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00453 if (cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED) { 00454 linkConfiguration->key_rotation = thrKeyRotation; 00455 thread_calculate_key_guard_timer(cur, linkConfiguration, false); 00456 ret_val = 0; 00457 } 00458 } 00459 } 00460 return ret_val; 00461 #else 00462 (void)interface_id; 00463 (void)thrKeyRotation; 00464 return -1; 00465 #endif 00466 } 00467 00468 int thread_test_router_select_threshold_values_set( 00469 int8_t interface_id, 00470 uint8_t upgradeThreshold, 00471 uint8_t downgradeThreshold) 00472 { 00473 #ifdef HAVE_THREAD 00474 protocol_interface_info_entry_t *cur; 00475 if (downgradeThreshold == 0) { 00476 tr_warn("Invalid Threshold value"); 00477 return -1; 00478 } 00479 00480 if (upgradeThreshold >= downgradeThreshold) { 00481 tr_warn("Invalid Threshold value %u >= %u", upgradeThreshold, downgradeThreshold); 00482 return -1; 00483 } 00484 00485 cur = protocol_stack_interface_info_get_by_id(interface_id); 00486 if (!cur) { 00487 tr_warn("Invalid interface id"); 00488 return -1; 00489 } 00490 00491 if (!cur->thread_info) { 00492 tr_warn("Not Thread specific interface"); 00493 return -1; 00494 } 00495 00496 cur->thread_info->routerSelectParameters.routerUpgradeThresHold = upgradeThreshold; 00497 cur->thread_info->routerSelectParameters.routerDowngradeThresHold = downgradeThreshold; 00498 00499 return 0; 00500 #else 00501 (void)interface_id; 00502 (void)upgradeThreshold; 00503 (void)downgradeThreshold; 00504 return -1; 00505 #endif 00506 } 00507 int thread_test_max_accepted_router_id_limit_set( 00508 int8_t interface_id, 00509 uint8_t maxRouterLimit) 00510 { 00511 #ifdef HAVE_THREAD 00512 protocol_interface_info_entry_t *cur; 00513 if ((maxRouterLimit < 1) || (maxRouterLimit > 32)) { 00514 tr_error("Accept values are between 1-32 for max Router Id assign limit"); 00515 return -1; 00516 } 00517 00518 cur = protocol_stack_interface_info_get_by_id(interface_id); 00519 if (!cur) { 00520 tr_warn("Invalid interface id"); 00521 return -1; 00522 } 00523 00524 if (!cur->thread_info) { 00525 tr_warn("Not Thread specific interface"); 00526 return -1; 00527 } 00528 cur->thread_info->testMaxActiveRouterIdLimit = maxRouterLimit; 00529 tr_debug("New max Router Id assign limit is %u", maxRouterLimit); 00530 return 0; 00531 #else 00532 (void)interface_id; 00533 (void)maxRouterLimit; 00534 return -1; 00535 #endif 00536 } 00537 00538 00539 /** 00540 * Set Thread Security Master Key and Key Index 00541 * 00542 * \param interface_id Network Interface 00543 * \param enableSecurity Boolean for enable security or disable 00544 * \param threadMasterKey Thread Master Key material which will be used for generating new key 00545 * \param threadMasterKeyIndex Thread key material key index which will be increment periodically 00546 * \param keyRollPeriod Define Key index & key update process 00547 * 00548 * return 0, ADD OK 00549 * return <0 Add Not OK 00550 */ 00551 int thread_test_security_material_set(int8_t interface_id, bool enableSecurity, uint8_t *thrMasterKey, uint32_t thrKeySequenceCounter, uint32_t thrKeyRotation) 00552 { 00553 #ifdef HAVE_THREAD 00554 int ret_val = -1; 00555 uint8_t key_material[32]; 00556 uint8_t key_index; 00557 protocol_interface_info_entry_t *cur; 00558 link_configuration_s *linkConfiguration; 00559 linkConfiguration = thread_joiner_application_get_config(interface_id); 00560 if (!linkConfiguration) { 00561 return -1; 00562 } 00563 00564 cur = protocol_stack_interface_info_get_by_id(interface_id); 00565 if (!cur) { 00566 return -1; 00567 } 00568 00569 if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) == 0) { 00570 return -4; 00571 } 00572 00573 if (cur->thread_info) { 00574 00575 if (cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED) { 00576 mac_helper_link_frame_counter_set(cur->id, 0); 00577 if (enableSecurity) { 00578 if (thrMasterKey) { 00579 ret_val = 0; 00580 linkConfiguration->key_rotation = thrKeyRotation; 00581 linkConfiguration->key_sequence = thrKeySequenceCounter; 00582 cur->if_lowpan_security_params->nwk_security_mode = NET_SEC_MODE_PSK_LINK_SECURITY; 00583 cur->mac_parameters->mac_configured_sec_level = 5; 00584 cur->thread_info->masterSecretMaterial.historyKeyValid = false; 00585 cur->thread_info->masterSecretMaterial.valid_Info = true; 00586 memcpy(linkConfiguration->master_key, thrMasterKey, 16); 00587 cur->thread_info->masterSecretMaterial.keyRotation = thrKeyRotation; 00588 //Define KEY's 00589 thread_key_get(thrMasterKey, key_material, thrKeySequenceCounter); 00590 key_index = THREAD_KEY_INDEX(thrKeySequenceCounter); 00591 //Set Keys 00592 mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); 00593 mle_service_security_set_security_key(cur->id, key_material, key_index, true); 00594 //Gen also Next Key 00595 thread_security_next_key_generate(cur, linkConfiguration->master_key, thrKeySequenceCounter); 00596 thread_calculate_key_guard_timer(cur, linkConfiguration, false); 00597 } 00598 } else { 00599 ret_val = 0; 00600 cur->if_lowpan_security_params->nwk_security_mode = NET_SEC_MODE_NO_LINK_SECURITY; 00601 cur->mac_parameters->mac_configured_sec_level = 0; 00602 cur->thread_info->masterSecretMaterial.valid_Info = false; 00603 } 00604 if (ret_val == 0) { 00605 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION; 00606 cur->configure_flags |= INTERFACE_SECURITY_DEFINED; 00607 } 00608 } 00609 } 00610 return ret_val; 00611 #else 00612 (void)interface_id; 00613 (void)enableSecurity; 00614 (void)thrMasterKey; 00615 (void)thrKeySequenceCounter; 00616 (void)thrKeyRotation; 00617 return -1; 00618 #endif 00619 } 00620 00621 int thread_test_version_set(int8_t interface_id, uint8_t version) 00622 { 00623 #ifdef HAVE_THREAD 00624 protocol_interface_info_entry_t *cur; 00625 thread_version = version; 00626 cur = protocol_stack_interface_info_get_by_id(interface_id); 00627 if (!cur) { 00628 return -1; 00629 } 00630 cur->thread_info->version = version; 00631 return 0; 00632 00633 #else 00634 (void)interface_id; 00635 return -1; 00636 #endif 00637 } 00638 int thread_test_router_selection_jitter_set(int8_t interface_id, uint32_t jitter) 00639 { 00640 #ifdef HAVE_THREAD 00641 protocol_interface_info_entry_t *cur; 00642 if (jitter < 1) { 00643 return -1; 00644 } 00645 thread_router_selection_jitter = jitter; 00646 cur = protocol_stack_interface_info_get_by_id(interface_id); 00647 if (cur && cur->thread_info && cur->thread_info->reedJitterTimer > jitter) { 00648 cur->thread_info->reedJitterTimer = thread_router_bootstrap_random_upgrade_jitter(); 00649 } 00650 return 0; 00651 00652 #else 00653 (void)interface_id; 00654 (void)jitter; 00655 return -1; 00656 #endif 00657 } 00658 00659 int thread_test_min_delay_timer_set(int8_t interface_id, uint32_t delay_timer_value) 00660 { 00661 #ifdef HAVE_THREAD 00662 (void)interface_id; 00663 if (delay_timer_value < 1) { 00664 return -1; 00665 } 00666 thread_delay_timer_default = delay_timer_value; 00667 return 0; 00668 00669 #else 00670 (void)interface_id; 00671 (void)delay_timer_value; 00672 return -1; 00673 #endif 00674 } 00675 00676 int thread_test_increment_key_sequence_counter(int8_t interface_id) 00677 { 00678 #ifdef HAVE_THREAD 00679 return thread_management_increment_key_sequence_counter(interface_id); 00680 #else 00681 (void)interface_id; 00682 return -1; 00683 #endif 00684 } 00685 #ifdef HAVE_THREAD 00686 static int thread_test_panid_conflict_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00687 { 00688 (void)source_address; 00689 (void)source_port; 00690 uint16_t panid; 00691 uint8_t *ptr; 00692 uint16_t len MAYBE_UNUSED; 00693 tr_debug("Thread test panid conflict request"); 00694 if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_PANID, &panid)) { 00695 tr_info("PANID TLV %02x",panid); 00696 } 00697 if ( (len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_CHANNEL_MASK, &ptr)) > 0) { 00698 tr_info("Channel mask TLV %s",trace_array(ptr,len)); 00699 } 00700 coap_service_response_send(service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, NULL, 0); 00701 return 0; 00702 } 00703 #endif 00704 00705 #ifdef HAVE_THREAD 00706 static int thread_test_energy_scan_result_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00707 { 00708 (void)source_address; 00709 (void)source_port; 00710 uint8_t *ptr; 00711 uint16_t len MAYBE_UNUSED; 00712 00713 tr_debug("Thread test energy scan result"); 00714 if ( (len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_CHANNEL_MASK, &ptr)) > 0) { 00715 tr_info("Channel mask TLV %s",trace_array(ptr,len)); 00716 } 00717 if ( (len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_ENERGY_LIST, &ptr)) > 0) { 00718 tr_info("Energy list TLV %s",trace_array(ptr,len)); 00719 } 00720 coap_service_response_send(service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, NULL, 0); 00721 return 0; 00722 } 00723 #ifdef HAVE_THREAD 00724 static uint8_t coap_service = 0; 00725 static response_cb *generic_response_cb_ptr = NULL; 00726 static coap_response_cb *coap_response_cb_ptr = NULL; 00727 00728 static int thread_test_response_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00729 { 00730 (void)source_address; 00731 (void)source_port; 00732 00733 tr_debug("Thread test response received"); 00734 if (!response_ptr) { 00735 return -1; 00736 } 00737 /* Call callback function when receiving response, but do not call when receiving message code "empty" (Just ACK - not piggybacked response) */ 00738 if (generic_response_cb_ptr && (response_ptr->msg_code != COAP_MSG_CODE_EMPTY)) 00739 generic_response_cb_ptr(service_id, response_ptr->payload_ptr, response_ptr->payload_len); 00740 00741 if(response_ptr->uri_path_ptr && (!memcmp(response_ptr->uri_path_ptr, THREAD_URI_DIAGNOSTIC_ANSWER, strlen(THREAD_URI_DIAGNOSTIC_ANSWER)))){ 00742 coap_service_response_send(service_id, COAP_REQUEST_OPTIONS_NONE, response_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, NULL, 0); 00743 } 00744 return 0; 00745 } 00746 00747 static int thread_coap_response_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00748 { 00749 #ifndef HAVE_DEBUG 00750 (void) source_address; 00751 (void) source_port; 00752 #endif 00753 00754 tr_debug("Thread coap response received %s :%d",trace_ipv6(source_address),source_port); 00755 if (!response_ptr) { 00756 if (coap_response_cb_ptr) { 00757 coap_response_cb_ptr(service_id, 0xff, 0xff, NULL, 0); 00758 } 00759 return 0; 00760 } 00761 /* Call callback function when receiving response, but do not call when receiving message code "empty" (Just ACK - not piggybacked response) */ 00762 if (coap_response_cb_ptr && (response_ptr->msg_code != COAP_MSG_CODE_EMPTY)) { 00763 coap_response_cb_ptr(service_id, (uint8_t)(response_ptr->msg_code), (uint8_t)(response_ptr->msg_type), response_ptr->payload_ptr, response_ptr->payload_len); 00764 } 00765 00766 return 0; 00767 } 00768 00769 static int thread_coap_multicast_response_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00770 { 00771 #ifndef HAVE_DEBUG 00772 (void) source_address; 00773 (void) source_port; 00774 #endif 00775 00776 tr_debug("Thread coap multicast response received %s :%d",trace_ipv6(source_address),source_port); 00777 /* Call callback function when receiving response, but do not call when receiving message code "empty" (Just ACK - not piggybacked response) */ 00778 00779 if (coap_response_cb_ptr) { 00780 coap_response_cb_ptr(service_id, (uint8_t)(response_ptr->msg_code), (uint8_t)(response_ptr->msg_type), response_ptr->payload_ptr, response_ptr->payload_len); 00781 } 00782 coap_service_response_send(service_id, COAP_REQUEST_OPTIONS_NONE, response_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, NULL, 0); 00783 return 0; 00784 } 00785 #endif 00786 00787 static int thread_test_service_init(int8_t interface_id) 00788 { 00789 if (coap_service == 0) { 00790 coap_service = coap_service_initialize(interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL); 00791 coap_service_register_uri(coap_service, THREAD_URI_PANID_CONFLICT, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_test_panid_conflict_cb); 00792 coap_service_register_uri(coap_service, THREAD_URI_ED_REPORT, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_test_energy_scan_result_cb); 00793 coap_service_register_uri(coap_service, THREAD_URI_DIAGNOSTIC_ANSWER, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_coap_multicast_response_cb); 00794 } 00795 return 0; 00796 } 00797 00798 static uint8_t *channel_mask_write(uint8_t *ptr, uint8_t channel_page, uint8_t *mask_ptr) 00799 { 00800 uint8_t mask_len = 0; 00801 uint8_t mask_tlv[6];// 00802 if (channel_page == 0){ 00803 mask_len = 6; 00804 mask_tlv[0] = channel_page; 00805 mask_tlv[1] = 4; 00806 memcpy(&mask_tlv[2],mask_ptr,4); 00807 } 00808 ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_CHANNEL_MASK, mask_len, mask_tlv); 00809 return ptr; 00810 } 00811 #endif 00812 int thread_test_panid_query_send(int8_t interface_id, uint8_t *address_ptr, uint16_t session_id, uint16_t panid, uint8_t channel_page, uint8_t *mask_ptr) 00813 { 00814 #ifdef HAVE_THREAD 00815 sn_coap_msg_type_e msg_type; 00816 uint8_t payload[16];// 2+6 + 2+2 + 2+2 00817 uint8_t *ptr; 00818 thread_test_service_init(interface_id); 00819 if (address_ptr[0] == 0xff){ 00820 msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE; 00821 } else { 00822 msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00823 } 00824 ptr = payload; 00825 ptr = channel_mask_write(ptr, channel_page, mask_ptr); 00826 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_PANID, panid); 00827 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_COMMISSIONER_SESSION_ID, session_id); 00828 coap_service_request_send(coap_service, COAP_REQUEST_OPTIONS_NONE, address_ptr, THREAD_MANAGEMENT_PORT, 00829 msg_type, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_PANID_QUERY, COAP_CT_OCTET_STREAM, payload, ptr - payload, thread_test_response_cb); 00830 00831 return 0; 00832 #else 00833 (void)interface_id; 00834 (void)address_ptr; 00835 (void)session_id; 00836 (void)panid; 00837 (void)channel_page; 00838 (void)mask_ptr; 00839 return -1; 00840 #endif 00841 } 00842 int thread_test_energy_scan_send(int8_t interface_id, uint8_t *address_ptr, uint16_t session_id, uint8_t channel_page, uint8_t *mask_ptr, uint16_t period, uint8_t count, uint16_t duration) 00843 { 00844 #ifdef HAVE_THREAD 00845 sn_coap_msg_type_e msg_type; 00846 uint8_t payload[2+2 + 2+1 + 2+1 + 2+6 + 2+2]; 00847 uint8_t *ptr; 00848 thread_test_service_init(interface_id); 00849 if (address_ptr[0] == 0xff){ 00850 msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE; 00851 } else { 00852 msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00853 } 00854 ptr = payload; 00855 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_PERIOD, period); 00856 ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_COUNT, count); 00857 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_DURATION, duration); 00858 00859 ptr = channel_mask_write(ptr, channel_page, mask_ptr); 00860 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_COMMISSIONER_SESSION_ID, session_id); 00861 coap_service_request_send(coap_service, COAP_REQUEST_OPTIONS_NONE, address_ptr, THREAD_MANAGEMENT_PORT, 00862 msg_type, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_ED_SCAN, COAP_CT_OCTET_STREAM, payload, ptr - payload, thread_test_response_cb); 00863 00864 return 0; 00865 #else 00866 (void)interface_id; 00867 (void)address_ptr; 00868 (void)session_id; 00869 (void)channel_page; 00870 (void)mask_ptr; 00871 (void)period; 00872 (void)count; 00873 (void)duration; 00874 return -1; 00875 #endif 00876 } 00877 00878 int thread_test_diagnostic_command_send(int8_t interface_id, uint8_t *address_ptr,const char *uri_ptr, uint8_t request_length, uint8_t *request_ptr, response_cb *resp_cb) 00879 { 00880 #ifdef HAVE_THREAD 00881 uint8_t payload[17+2] = {0}; 00882 uint8_t *ptr = NULL; 00883 generic_response_cb_ptr = resp_cb; 00884 sn_coap_msg_type_e msg_type; 00885 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_REQUEST_GET; 00886 00887 thread_test_service_init(interface_id); 00888 00889 if(request_length > 17 || !address_ptr) { 00890 return -1; 00891 } 00892 00893 if (address_ptr[0] == 0xff){ 00894 msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE; 00895 } else { 00896 msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00897 } 00898 00899 if(!strcmp(uri_ptr, "d/dr")){ 00900 msg_code = COAP_MSG_CODE_REQUEST_POST; 00901 } 00902 00903 ptr = payload; 00904 if (request_length > 0 && request_ptr) { 00905 ptr = thread_diagcop_tlv_data_write(ptr, DIAGCOP_TLV_TYPE_LIST, request_length, request_ptr); 00906 } 00907 coap_service_request_send(coap_service, COAP_REQUEST_OPTIONS_NONE, address_ptr, THREAD_MANAGEMENT_PORT, 00908 msg_type, msg_code, uri_ptr, COAP_CT_OCTET_STREAM, payload, ptr - payload, thread_test_response_cb); 00909 00910 return 0; 00911 #else 00912 (void)interface_id; 00913 (void)address_ptr; 00914 (void)uri_ptr; 00915 (void)request_length; 00916 (void)request_ptr; 00917 (void)resp_cb; 00918 return -1; 00919 #endif 00920 } 00921 int thread_test_coap_request_send(int8_t interface_id, uint8_t *address_ptr, uint16_t port, uint8_t msg_type, uint8_t msg_code, uint16_t content_format, const char *uri_ptr, uint8_t *request_ptr, uint8_t request_length, coap_response_cb *resp_cb) 00922 { 00923 #ifdef HAVE_THREAD 00924 coap_response_cb_ptr = resp_cb; 00925 00926 thread_test_service_init(interface_id); 00927 00928 coap_service_request_send(coap_service, COAP_REQUEST_OPTIONS_NONE, address_ptr, port, 00929 (sn_coap_msg_type_e)msg_type, (sn_coap_msg_code_e)msg_code, uri_ptr, (sn_coap_content_format_e) content_format, request_ptr, request_length, thread_coap_response_cb); 00930 00931 return 0; 00932 #else 00933 (void)interface_id; 00934 (void)address_ptr; 00935 (void)port; 00936 (void)msg_type; 00937 (void)msg_code; 00938 (void)content_format; 00939 (void)uri_ptr; 00940 (void)request_length; 00941 (void)request_ptr; 00942 (void)resp_cb; 00943 return -1; 00944 #endif 00945 } 00946 00947 00948 int thread_test_announce_ntf_send(int8_t interface_id, uint8_t *address_ptr, uint32_t channel, uint16_t panid, uint64_t timestamp) 00949 { 00950 #ifdef HAVE_THREAD 00951 00952 (void)address_ptr; 00953 protocol_interface_info_entry_t *cur; 00954 cur = protocol_stack_interface_info_get_by_id(interface_id); 00955 if (!cur || !cur->thread_info ) { 00956 return -1; 00957 } 00958 return thread_bootstrap_announce_send(cur, (uint8_t)(channel >> 16), (uint16_t) channel, panid, timestamp, (uint16_t) channel); 00959 #else 00960 (void)interface_id; 00961 (void)address_ptr; 00962 (void)channel; 00963 (void)panid; 00964 (void)timestamp; 00965 return -1; 00966 #endif 00967 } 00968 00969 int thread_test_announce_begin_send(int8_t interface_id, uint8_t *address_ptr, uint16_t session_id, uint8_t channel_page, uint8_t *mask_ptr, uint16_t period, uint8_t count) 00970 { 00971 #ifdef HAVE_THREAD 00972 uint8_t payload[ 2+2 + 2+2 + 2+1 + 2+6]; 00973 uint8_t *ptr; 00974 sn_coap_msg_type_e msg_type; 00975 thread_test_service_init(interface_id); 00976 00977 if (address_ptr[0] == 0xff){ 00978 msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE; 00979 } else { 00980 msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00981 } 00982 00983 ptr = payload; 00984 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_COMMISSIONER_SESSION_ID, session_id); 00985 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_PERIOD, period); 00986 ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_COUNT, count); 00987 ptr = channel_mask_write(ptr, channel_page, mask_ptr); 00988 coap_service_request_send(coap_service, COAP_REQUEST_OPTIONS_NONE, address_ptr, THREAD_MANAGEMENT_PORT, 00989 msg_type, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_MANAGEMENT_ANNOUNCE_BEGIN, COAP_CT_OCTET_STREAM, payload, ptr - payload, thread_test_response_cb); 00990 00991 return 0; 00992 #else 00993 (void)interface_id; 00994 (void)address_ptr; 00995 (void)session_id; 00996 (void)channel_page; 00997 (void)mask_ptr; 00998 (void)period; 00999 (void)count; 01000 return -1; 01001 #endif 01002 } 01003 01004 int thread_test_partition_info_get(int8_t interface_id, uint32_t *partition_id, uint8_t *weighting, uint8_t *data_version, uint8_t *stable_data_version, uint8_t *leader_id) 01005 { 01006 #ifdef HAVE_THREAD 01007 protocol_interface_info_entry_t *cur; 01008 cur = protocol_stack_interface_info_get_by_id(interface_id); 01009 if (!cur || !cur->thread_info || !cur->thread_info->thread_leader_data) { 01010 return -1; 01011 } 01012 01013 if (thread_attach_ready(cur) != 0) { 01014 return -1; 01015 } 01016 01017 if (partition_id) { 01018 *partition_id = cur->thread_info->thread_leader_data->partitionId; 01019 } 01020 if (weighting) { 01021 *weighting = cur->thread_info->thread_leader_data->weighting; 01022 } 01023 if (data_version) { 01024 *data_version = cur->thread_info->thread_leader_data->dataVersion; 01025 } 01026 if (stable_data_version) { 01027 *stable_data_version = cur->thread_info->thread_leader_data->stableDataVersion; 01028 } 01029 if (leader_id) { 01030 *leader_id = cur->thread_info->thread_leader_data->leaderRouterId; 01031 } 01032 return 0; 01033 #else 01034 (void)interface_id; 01035 (void)partition_id; 01036 (void)weighting; 01037 (void)data_version; 01038 (void)stable_data_version; 01039 (void)leader_id; 01040 return -1; 01041 #endif 01042 } 01043 int thread_test_partition_info_set(int8_t interface_id, uint32_t partition_id) 01044 { 01045 #ifdef HAVE_THREAD 01046 protocol_interface_info_entry_t *cur; 01047 cur = protocol_stack_interface_info_get_by_id(interface_id); 01048 if (!cur || !cur->thread_info ) { 01049 return -1; 01050 } 01051 cur->thread_info->testRandomPartitionId = partition_id; 01052 return 0; 01053 01054 #else 01055 (void)interface_id; 01056 (void)partition_id; 01057 return -1; 01058 #endif 01059 } 01060 int8_t thread_test_thread_information_get(int8_t interface_id, uint16_t *short_addr, uint8_t *router_count, bool *network_stable) 01061 { 01062 #ifdef HAVE_THREAD 01063 protocol_interface_info_entry_t *cur; 01064 cur = protocol_stack_interface_info_get_by_id(interface_id); 01065 if (!cur || !cur->thread_info) { 01066 return -1; 01067 } 01068 if (short_addr) { 01069 *short_addr = mac_helper_mac16_address_get(cur); 01070 } 01071 if (router_count) { 01072 *router_count = thread_routing_count_active_routers(&cur->thread_info->routing); 01073 } 01074 if (network_stable) { 01075 if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE || 01076 cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_END_DEVICE || 01077 cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE) { 01078 *network_stable = true; 01079 } else { 01080 *network_stable = !(thread_router_bootstrap_reed_upgrade(cur) || 01081 thread_router_bootstrap_router_downgrade(cur)); 01082 } 01083 01084 } 01085 return 0; 01086 #else 01087 (void)interface_id; 01088 (void)short_addr; 01089 (void)router_count; 01090 (void)network_stable; 01091 return -1; 01092 #endif 01093 } 01094 01095 01096 int8_t thread_test_child_count_get(int8_t interface_id) 01097 { 01098 #ifdef HAVE_THREAD 01099 protocol_interface_info_entry_t *cur; 01100 cur = protocol_stack_interface_info_get_by_id(interface_id); 01101 if (!cur || !cur->thread_info || !(cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER)) { 01102 return -1; 01103 } 01104 return thread_router_bootstrap_child_count_get(cur); 01105 #else 01106 (void)interface_id; 01107 return -1; 01108 #endif 01109 } 01110 01111 int8_t thread_test_child_info_get(int8_t interface_id, uint8_t index, uint16_t *short_addr, bool *sleepy, uint8_t *mac64,uint8_t *margin) 01112 { 01113 #ifdef HAVE_THREAD 01114 protocol_interface_info_entry_t *cur; 01115 uint8_t n= 0; 01116 cur = protocol_stack_interface_info_get_by_id(interface_id); 01117 if (!cur || !cur->thread_info || cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER) { 01118 return -1; 01119 } 01120 uint16_t mac16 = mac_helper_mac16_address_get(cur); 01121 mle_neigh_table_list_t *mle_table = mle_class_active_list_get(interface_id); 01122 if (!mle_table) { 01123 return -1; 01124 } 01125 01126 ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { 01127 if (cur_entry->threadNeighbor && thread_router_addr_from_addr(cur_entry->short_adr) == thread_router_addr_from_addr(mac16)) { 01128 if (n == index) { 01129 *short_addr = cur_entry->short_adr; 01130 memcpy(mac64,cur_entry->mac64, 8); 01131 *sleepy = (cur_entry->mode & MLE_RX_ON_IDLE) != MLE_RX_ON_IDLE; 01132 *margin = cur_entry->link_margin; 01133 return 0; 01134 } 01135 n++; 01136 } 01137 } 01138 return -1; 01139 #else 01140 (void)interface_id; 01141 (void)index; 01142 (void)short_addr; 01143 (void)sleepy; 01144 (void)mac64; 01145 (void)margin; 01146 return -1; 01147 #endif 01148 } 01149 int8_t thread_test_neighbour_info_get(int8_t interface_id, uint8_t index, uint16_t *short_addr, uint8_t *mac64, uint8_t *margin) 01150 { 01151 #ifdef HAVE_THREAD 01152 protocol_interface_info_entry_t *cur; 01153 uint8_t n= 0; 01154 cur = protocol_stack_interface_info_get_by_id(interface_id); 01155 if (!cur || !cur->thread_info) { 01156 return -1; 01157 } 01158 uint16_t mac16 = mac_helper_mac16_address_get(cur); 01159 mle_neigh_table_list_t *mle_table = mle_class_active_list_get(interface_id); 01160 if (!mle_table) { 01161 return -1; 01162 } 01163 01164 ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { 01165 if (cur_entry->threadNeighbor && thread_router_addr_from_addr(cur_entry->short_adr) != thread_router_addr_from_addr(mac16)) { 01166 if (n == index) { 01167 *short_addr = cur_entry->short_adr; 01168 memcpy(mac64,cur_entry->mac64, 8); 01169 *margin = cur_entry->link_margin; 01170 return 0; 01171 } 01172 n++; 01173 } 01174 } 01175 return -1; 01176 #else 01177 (void)interface_id; 01178 (void)index; 01179 (void)short_addr; 01180 (void)mac64; 01181 (void)margin; 01182 return -1; 01183 #endif 01184 } 01185 01186 int8_t thread_test_initial_slaac_iid_set(int8_t interface_id, uint8_t *iid) 01187 { 01188 #ifdef HAVE_THREAD 01189 (void)interface_id;// I somehow feel this might be needed later 01190 return addr_opaque_initial_iid_set(iid); 01191 #else 01192 (void)interface_id; 01193 (void)iid; 01194 return -1; 01195 #endif 01196 } 01197 01198 01199 int8_t thread_test_router_id_request_send(int8_t interface_id, uint8_t status) 01200 { 01201 #ifdef HAVE_THREAD 01202 protocol_interface_info_entry_t *cur; 01203 01204 cur = protocol_stack_interface_info_get_by_id(interface_id); 01205 if (!cur || !cur->thread_info) { 01206 return -1; 01207 } 01208 01209 if (thread_attach_ready(cur) != 0) { 01210 return -1; 01211 } 01212 01213 tr_debug("Trigger REED router upgrade process with status %d", status); 01214 01215 thread_router_bootstrap_router_id_request(cur, status); 01216 01217 return 0; 01218 #else 01219 (void)interface_id; 01220 (void)status; 01221 return -1; 01222 #endif 01223 01224 } 01225 01226 int8_t thread_test_router_address_set(int8_t interface_id, uint16_t router_address) 01227 { 01228 #ifdef HAVE_THREAD 01229 protocol_interface_info_entry_t *cur; 01230 cur = protocol_stack_interface_info_get_by_id(interface_id); 01231 if (!cur || !cur->thread_info) { 01232 return -1; 01233 } 01234 if ((router_address & THREAD_ROUTER_MASK) == THREAD_ROUTER_MASK) { 01235 tr_warn("address requested is reserved for anycast locator"); 01236 return -2; 01237 } 01238 if (cur->thread_info->routerShortAddress != 0xfffe) { 01239 tr_debug("router short address already present"); 01240 return -3; 01241 } 01242 cur->thread_info->routerShortAddress = router_address; 01243 return 0; 01244 #else 01245 (void)interface_id; 01246 (void)router_address; 01247 return -1; 01248 #endif 01249 } 01250 01251 int8_t thread_test_joiner_router_joiner_port_set(uint16_t port) 01252 { 01253 #ifdef HAVE_THREAD 01254 /* If parameter is '0', then use default port */ 01255 if (0 == port) { 01256 port = THREAD_DEFAULT_JOINER_PORT; 01257 } 01258 01259 thread_joiner_port = port; 01260 return 0; 01261 #else 01262 (void)port; 01263 return -1; 01264 #endif 01265 01266 } 01267 01268 int thread_test_mle_message_send(int8_t interface_id, uint8_t *dst_address, uint8_t msg_id, bool write_src_addr, bool write_leader_data, bool write_network_data, bool write_timestamp, bool write_operational_set, bool write_challenge, uint8_t *msg_ptr, uint8_t msg_len) 01269 { 01270 #ifdef HAVE_THREAD 01271 protocol_interface_info_entry_t *cur; 01272 uint16_t len = 32; 01273 uint32_t keySequence; 01274 uint8_t *ptr; 01275 cur = protocol_stack_interface_info_get_by_id(interface_id); 01276 if (!cur || !cur->thread_info) { 01277 return -1; 01278 } 01279 01280 len += msg_len; 01281 if (write_operational_set) { 01282 len += thread_active_operational_dataset_size(cur); 01283 len += thread_pending_operational_dataset_size(cur); 01284 } 01285 if (write_network_data) { 01286 len += thread_network_data_tlv_size(cur, true); 01287 } 01288 01289 uint16_t bufId = mle_service_msg_allocate(cur->id, len, write_challenge, msg_id); 01290 01291 if (bufId == 0) { 01292 return -1; 01293 } 01294 01295 tr_debug("thread test send MLE message"); 01296 01297 thread_management_get_current_keysequence(cur->id, &keySequence); 01298 mle_service_msg_update_security_params(bufId, 5, 2, keySequence); 01299 01300 ptr = mle_service_get_data_pointer(bufId); 01301 01302 //Set SRC 01303 if (write_src_addr) { 01304 ptr = mle_general_write_source_address(ptr, cur); 01305 } 01306 //SET leader data 01307 if (write_leader_data) { 01308 ptr = thread_leader_data_tlv_write(ptr, cur); 01309 } 01310 if (write_timestamp) { 01311 ptr = thread_active_timestamp_write(cur,ptr); 01312 ptr = thread_pending_operational_dataset_write(cur, ptr); 01313 } 01314 01315 if (write_operational_set) { 01316 ptr = thread_active_operational_dataset_write(cur, ptr); 01317 ptr = thread_pending_operational_dataset_write(cur, ptr); 01318 } 01319 if (write_network_data) { 01320 ptr = thread_network_data_tlv_write(cur, ptr, true); 01321 } 01322 // Add any user decided TLVs 01323 if (msg_ptr && msg_len) { 01324 memcpy(ptr,msg_ptr,msg_len); 01325 ptr += msg_len; 01326 } 01327 01328 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 01329 tr_debug("Buffer overflow at message write"); 01330 } 01331 mle_service_set_msg_destination_address(bufId, dst_address); 01332 mle_service_send_message(bufId); 01333 return 0; 01334 #else 01335 (void)interface_id; 01336 (void)dst_address; 01337 (void)msg_id; 01338 (void)write_src_addr; 01339 (void)write_leader_data; 01340 (void)write_operational_set; 01341 (void)write_challenge; 01342 (void)msg_ptr; 01343 (void)msg_len; 01344 return -1; 01345 #endif 01346 } 01347 01348 01349 int thread_test_extension_name_set(int8_t interface_id, char extension_name[16]) 01350 { 01351 (void) interface_id; 01352 (void) extension_name; 01353 #ifdef HAVE_THREAD 01354 protocol_interface_info_entry_t *cur; 01355 01356 cur = protocol_stack_interface_info_get_by_id(interface_id); 01357 if (!cur || !cur->thread_info) { 01358 return -1; 01359 } 01360 01361 return thread_extension_bootstrap_thread_name_set(cur, extension_name); 01362 #else 01363 return -1; 01364 #endif 01365 }
Generated on Tue Jul 12 2022 12:46:02 by
