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