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.
Fork of OmniWheels by
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 Fri Jul 22 2022 04:54:03 by
 1.7.2
 1.7.2 
    