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_diagnostic.c
00001 /* 00002 * Copyright (c) 2016-2018, 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 #ifdef HAVE_THREAD 00031 #include <string.h> 00032 #include <ns_types.h> 00033 #include <ns_list.h> 00034 #include <ns_trace.h> 00035 #include "nsdynmemLIB.h" 00036 #include "net_interface.h" 00037 #include "thread_management_if.h" 00038 #include "thread_common.h" 00039 #include "thread_joiner_application.h" 00040 #include "thread_leader_service.h" 00041 #include "thread_router_bootstrap.h" 00042 #include "6LoWPAN/Thread/thread_neighbor_class.h" 00043 #include "MLE/mle.h" 00044 #include "6LoWPAN/Thread/thread_router_bootstrap.h" 00045 #include "thread_config.h" 00046 #include "thread_network_data_storage.h" 00047 #include "NWK_INTERFACE/Include/protocol.h" 00048 #include "thread_diagcop_lib.h" 00049 #include "common_functions.h" 00050 #include "6LoWPAN/MAC/mac_helper.h" 00051 #include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" 00052 #include "mac_api.h" 00053 00054 00055 #define TRACE_GROUP "TdiaC" 00056 00057 00058 #include "coap_service_api.h" 00059 00060 00061 typedef struct thread_diagnostic_command { 00062 int8_t interface_id; 00063 int8_t coap_service_id; 00064 ns_list_link_t link; 00065 } thread_diagnostic_command_t; 00066 00067 static NS_LIST_DEFINE(instance_list, thread_diagnostic_command_t, link); 00068 00069 static thread_diagnostic_command_t *thread_diagnostic_command_find(int8_t interface_id) 00070 { 00071 thread_diagnostic_command_t *this = NULL; 00072 ns_list_foreach(thread_diagnostic_command_t, cur_ptr, &instance_list) { 00073 if (cur_ptr->interface_id == interface_id) { 00074 this = cur_ptr; 00075 break; 00076 } 00077 } 00078 return this; 00079 } 00080 00081 static thread_diagnostic_command_t *thread_diagnostic_find_by_service(int8_t service_id) 00082 { 00083 thread_diagnostic_command_t *this = NULL; 00084 ns_list_foreach(thread_diagnostic_command_t, cur_ptr, &instance_list) { 00085 if (cur_ptr->coap_service_id == service_id) { 00086 this = cur_ptr; 00087 break; 00088 } 00089 } 00090 return this; 00091 } 00092 00093 static uint8_t *thread_diagnostic_child_table_tlv_build(uint8_t *data_ptr, protocol_interface_info_entry_t *cur) 00094 { 00095 uint8_t child_count = 0; 00096 uint8_t calculated_timeout; 00097 00098 mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; 00099 00100 child_count = thread_router_bootstrap_child_count_get(cur); 00101 00102 *data_ptr++ = DIAGCOP_TLV_CHILD_TABLE; // Type 00103 *data_ptr++ = (3 * child_count); // Length 00104 00105 ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) { 00106 if (thread_router_addr_from_addr(cur_entry->mac16) == mac_helper_mac16_address_get(cur)){ 00107 /* |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3| */ 00108 /* |Timeout |Rsv| Child ID | Mode | */ 00109 calculated_timeout = thread_log2_aprx(cur_entry->link_lifetime - 1) + 4; 00110 uint8_t mode = 0; 00111 mode |= mle_mode_write_from_mac_entry(cur_entry); 00112 mode |= thread_neighbor_class_mode_write_from_entry(&cur->thread_info->neighbor_class, cur_entry->index); 00113 tr_debug("Write child table TLV entry: %d - %d - %d", calculated_timeout, cur_entry->mac16, mode); 00114 *data_ptr = 0x00; //reserved bytes to zero 00115 *data_ptr = calculated_timeout << 3; 00116 00117 if(cur_entry->mac16 & 0x0100){ 00118 *data_ptr = *data_ptr | 0x01; 00119 } 00120 data_ptr++; 00121 *data_ptr++ = (uint8_t)(cur_entry->mac16 & 0x00ff); 00122 *data_ptr++ = mode; 00123 } 00124 } 00125 00126 return data_ptr; 00127 } 00128 00129 uint8_t thread_diag_mode_get_by_interface_ptr(protocol_interface_info_entry_t *cur) 00130 { 00131 uint8_t mle_mode = 0; 00132 if (!thread_info(cur)) { 00133 return 0; 00134 } 00135 if (!(cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE)) { 00136 mle_mode |= MLE_RX_ON_IDLE; 00137 } 00138 00139 if (thread_info(cur)->requestFullNetworkData) { 00140 mle_mode |= (MLE_THREAD_REQ_FULL_DATA_SET); 00141 } 00142 00143 /* We always send secured data requests */ 00144 mle_mode |= MLE_THREAD_SECURED_DATA_REQUEST; 00145 00146 switch (thread_info(cur)->thread_device_mode) { 00147 case THREAD_DEVICE_MODE_ROUTER: 00148 case THREAD_DEVICE_MODE_FULL_END_DEVICE: 00149 mle_mode |= MLE_FFD_DEV; 00150 break; 00151 00152 default: 00153 break; 00154 } 00155 00156 00157 return mle_mode; 00158 } 00159 00160 static int thread_diagnostic_configuration_calc(protocol_interface_info_entry_t *cur, uint8_t *tlv_list, uint16_t list_len) 00161 { 00162 int payload_len = 0; 00163 uint16_t address_count = 0; 00164 00165 if(!tlv_list || list_len < 1) { 00166 return 0; 00167 } 00168 00169 while(list_len --){ 00170 switch (*tlv_list){ 00171 case DIAGCOP_TLV_EXTENDED_MAC_ADDRESS: 00172 payload_len += 2 + 8; 00173 break; 00174 00175 case DIAGCOP_TLV_ADDRESS16: 00176 payload_len += 2 + 2; 00177 break; 00178 00179 case DIAGCOP_TLV_MODE: 00180 payload_len += 2 + 1; 00181 break; 00182 00183 case DIAGCOP_TLV_TIMEOUT: 00184 if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE || 00185 cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_END_DEVICE ) { 00186 payload_len += 2 + 4; 00187 } 00188 break; 00189 00190 case DIAGCOP_TLV_CONNECTIVITY: 00191 payload_len += 2 + 10; 00192 break; 00193 00194 case DIAGCOP_TLV_ROUTE64: 00195 payload_len += thread_route_option_size(cur); 00196 break; 00197 00198 case DIAGCOP_TLV_LEADER_DATA: 00199 payload_len += 2 + 8; // TLV header + uint16 pan id 00200 break; 00201 00202 case DIAGCOP_TLV_NETWORK_DATA: 00203 payload_len += 2; // TLV header 00204 payload_len += thread_network_data_tlv_size(cur,1); 00205 break; 00206 00207 case DIAGCOP_TLV_IPV6_ADDRESS_LIST: 00208 arm_net_interface_address_list_size(cur->id, &address_count); 00209 payload_len += 2 + (address_count * 16); 00210 break; 00211 00212 case DIAGCOP_TLV_MAC_COUNTERS: 00213 payload_len += 2+36; 00214 break; 00215 case DIAGCOP_TLV_BATTERY_LEVEL: 00216 payload_len += 2 + 1; 00217 break; 00218 00219 case DIAGCOP_TLV_SUPPLY_VOLTAGE: 00220 payload_len += 2 + 2; 00221 break; 00222 00223 case DIAGCOP_TLV_CHILD_TABLE: 00224 /* Value length = Type + Length + 3 * child count */ 00225 payload_len += 2 + (3 * thread_router_bootstrap_child_count_get(cur)); 00226 break; 00227 00228 case DIAGCOP_TLV_CHANNEL_PAGES: 00229 payload_len += 2+1; 00230 break; 00231 00232 default: 00233 // todo: Other TLV's not supported atm 00234 break; 00235 } 00236 00237 tlv_list++; 00238 } 00239 return payload_len; 00240 } 00241 00242 static uint8_t *thread_diagnostic_get_build(protocol_interface_info_entry_t *cur, uint8_t *response_ptr, uint8_t *tlv_list, uint16_t list_len) 00243 { 00244 00245 if(!tlv_list || list_len < 1) { 00246 // Request all 00247 return response_ptr; 00248 } 00249 if (!thread_info(cur)) { 00250 return response_ptr; 00251 } 00252 // the following are some tlvs that need to be implemented correctly, this is only dummy data for the moment 00253 uint8_t dummy_data[36] = {0}; 00254 uint8_t *ptr; 00255 int written_address_count = 0; 00256 uint16_t ipv6_address_count = 0; 00257 uint8_t extended_address[8] = {0}; 00258 00259 arm_net_interface_address_list_size(cur->id, &ipv6_address_count); 00260 00261 // 16 bytes for each ipv6 address 00262 uint8_t ipv6_address_list[ipv6_address_count * 16]; 00263 00264 tr_debug("tlv list length %d", list_len); 00265 while(list_len --){ 00266 switch (*tlv_list){ 00267 00268 case DIAGCOP_TLV_EXTENDED_MAC_ADDRESS: 00269 if (cur->mac_api) { 00270 //Read dynamicaly generated current extented address from MAC. 00271 cur->mac_api->mac64_get(cur->mac_api,MAC_EXTENDED_DYNAMIC, extended_address); 00272 } 00273 response_ptr = thread_diagcop_tlv_data_write(response_ptr, DIAGCOP_TLV_EXTENDED_MAC_ADDRESS, 8, extended_address); 00274 break; 00275 00276 case DIAGCOP_TLV_ADDRESS16: 00277 response_ptr = thread_diagcop_tlv_data_write_uint16(response_ptr, DIAGCOP_TLV_ADDRESS16, mac_helper_mac16_address_get(cur)); 00278 break; 00279 00280 case DIAGCOP_TLV_MODE: 00281 response_ptr = thread_diagcop_tlv_data_write_uint8(response_ptr, DIAGCOP_TLV_MODE, thread_diag_mode_get_by_interface_ptr(cur)); 00282 break; 00283 00284 case DIAGCOP_TLV_TIMEOUT: 00285 //must be sleeping poll rate 00286 if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE || 00287 cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_END_DEVICE ) { 00288 response_ptr = thread_diagcop_tlv_data_write_uint32(response_ptr, DIAGCOP_TLV_TIMEOUT, cur->thread_info->host_link_timeout); 00289 } 00290 break; 00291 00292 case DIAGCOP_TLV_CONNECTIVITY: 00293 ptr = response_ptr; 00294 response_ptr = thread_connectivity_tlv_write(response_ptr, cur, 0x0f); 00295 if (ptr != response_ptr) { 00296 ptr[0]=DIAGCOP_TLV_CONNECTIVITY; 00297 } 00298 break; 00299 00300 case DIAGCOP_TLV_ROUTE64: 00301 ptr = response_ptr; 00302 response_ptr = thread_route_option_write(cur,response_ptr); 00303 if (ptr != response_ptr) { 00304 ptr[0]=DIAGCOP_TLV_ROUTE64; 00305 } 00306 break; 00307 00308 case DIAGCOP_TLV_LEADER_DATA: 00309 ptr = response_ptr; 00310 response_ptr = thread_leader_data_tlv_write(response_ptr,cur); 00311 if (ptr != response_ptr) { 00312 ptr[0]=DIAGCOP_TLV_LEADER_DATA; 00313 } 00314 break; 00315 00316 case DIAGCOP_TLV_NETWORK_DATA: 00317 ptr = response_ptr; 00318 response_ptr = thread_network_data_tlv_write(cur, response_ptr, true); 00319 if (ptr != response_ptr) { 00320 ptr[0]=DIAGCOP_TLV_NETWORK_DATA; 00321 } 00322 break; 00323 00324 case DIAGCOP_TLV_IPV6_ADDRESS_LIST: 00325 arm_net_address_list_get(cur->id, ipv6_address_count * 16,ipv6_address_list,&written_address_count); 00326 response_ptr = thread_diagcop_tlv_data_write(response_ptr, DIAGCOP_TLV_IPV6_ADDRESS_LIST, ipv6_address_count*16, ipv6_address_list); 00327 break; 00328 00329 case DIAGCOP_TLV_MAC_COUNTERS: 00330 /* The following elements from [RFC 2863] are included in this order: 00331 * ifInUnknownProtos (4), ifInErrors (4), ifOutErrors (4), ifInUcastPkts (4), 00332 * ifInBroadcastPkts (4), ifInDiscards (4), ifOutUcastPkts (4), ifOutBroadcastPkts (4), ifOutDiscards (4) */ 00333 response_ptr = thread_diagcop_tlv_data_write(response_ptr, DIAGCOP_TLV_MAC_COUNTERS, 36, dummy_data); 00334 break; 00335 00336 case DIAGCOP_TLV_BATTERY_LEVEL: 00337 response_ptr = thread_diagcop_tlv_data_write_uint8(response_ptr, DIAGCOP_TLV_BATTERY_LEVEL, 0); 00338 break; 00339 00340 case DIAGCOP_TLV_SUPPLY_VOLTAGE: 00341 response_ptr = thread_diagcop_tlv_data_write_uint16(response_ptr, DIAGCOP_TLV_SUPPLY_VOLTAGE, 0); 00342 break; 00343 00344 case DIAGCOP_TLV_CHILD_TABLE: 00345 if (thread_router_bootstrap_child_count_get(cur)) { 00346 response_ptr = thread_diagnostic_child_table_tlv_build(response_ptr, cur); 00347 } 00348 break; 00349 00350 case DIAGCOP_TLV_CHANNEL_PAGES: 00351 // Only supporting channel page 0 00352 response_ptr = thread_diagcop_tlv_data_write_uint8(response_ptr, DIAGCOP_TLV_CHANNEL_PAGES, 0); 00353 break; 00354 00355 default: 00356 00357 break; 00358 } 00359 00360 tlv_list++; 00361 } 00362 return response_ptr; 00363 } 00364 /** 00365 * Thread diagnostics request d/dg 00366 */ 00367 static int thread_diagnostic_command_request_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00368 { 00369 (void) source_address; 00370 (void) source_port; 00371 00372 thread_diagnostic_command_t *this = thread_diagnostic_find_by_service(service_id); 00373 protocol_interface_info_entry_t *cur; 00374 uint8_t *ptr = NULL; 00375 uint8_t *request_tlv_ptr = NULL; 00376 uint16_t request_tlv_len; 00377 int response_len; 00378 uint8_t *response_ptr = NULL; 00379 sn_coap_msg_code_e return_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00380 00381 if (!this) {//check if there is request 00382 return -1; 00383 } 00384 cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00385 if (!cur) { 00386 return -1; 00387 } 00388 00389 tr_debug("Thread diagnostic command get request"); 00390 00391 request_tlv_len = thread_diagcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, DIAGCOP_TLV_TYPE_LIST, &request_tlv_ptr); 00392 00393 // the following function calculates the total memory that is needed to be allocated for response. 00394 // If the request_tlv_len is 0 then the memory allocated is for all the diagnostic command tlvs 00395 response_len = thread_diagnostic_configuration_calc(cur,request_tlv_ptr, request_tlv_len); 00396 if(response_len < 1){ 00397 if (request_tlv_len > 0) { 00398 // TLV was ommitted but ok request. respond with ok status 00399 goto send_response; 00400 } 00401 goto failure; 00402 } 00403 ptr = response_ptr = ns_dyn_mem_alloc(response_len); 00404 if (!response_ptr) { 00405 return_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR; 00406 goto failure; 00407 } 00408 00409 ptr = thread_diagnostic_get_build(cur, ptr, request_tlv_ptr, 00410 request_tlv_len); 00411 00412 send_response: 00413 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, 00414 request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, 00415 response_ptr,ptr - response_ptr ); 00416 ns_dyn_mem_free(response_ptr); 00417 return 0; 00418 00419 failure: 00420 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, return_code, COAP_CT_NONE, NULL, 0); 00421 return 0; 00422 } 00423 /** 00424 * Thread diagnostics reset d/dr 00425 */ 00426 static int thread_diagnostic_command_reset_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00427 { 00428 (void) source_address; 00429 (void) source_port; 00430 00431 thread_diagnostic_command_t *this = thread_diagnostic_find_by_service(service_id); 00432 if (!this) {//check if there is request 00433 return -1; 00434 } 00435 00436 tr_debug("Thread diagnostic command reset request"); 00437 00438 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, 00439 request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_TEXT_PLAIN, NULL, 0); 00440 return 0; 00441 } 00442 00443 /** 00444 * Thread diagnostics query d/dq 00445 */ 00446 static int thread_diagnostic_command_query_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00447 { 00448 uint8_t address_copy[16]; 00449 protocol_interface_info_entry_t *cur; 00450 uint8_t *response_ptr = NULL; 00451 uint8_t *ptr = NULL; 00452 uint8_t *request_tlv_ptr; 00453 uint16_t response_len; 00454 uint16_t request_tlv_len; 00455 sn_coap_msg_code_e return_code = COAP_MSG_CODE_EMPTY; 00456 int8_t response = -1; 00457 00458 /* Source_address is freed when calling coap_service_response_send(). 00459 * Anyhow, We need to use it when sending request, so let's make a copy! */ 00460 memcpy(address_copy, source_address, 16); 00461 00462 thread_diagnostic_command_t *this = thread_diagnostic_find_by_service(service_id); 00463 if (!this) {//check if there is request 00464 return -1; 00465 } 00466 cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00467 if (!cur) { 00468 return -1; 00469 } 00470 00471 tr_debug("Thread diagnostic command query request from %s:%d", trace_array(source_address, 16), source_port); 00472 // build response 00473 request_tlv_len = thread_diagcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, DIAGCOP_TLV_TYPE_LIST, &request_tlv_ptr); 00474 00475 // the following function calculates the total memory that is needed to be allocated for response. 00476 // If the request_tlv_len is 0 then the memory allocated is for all the diagnostic command tlvs 00477 response_len = thread_diagnostic_configuration_calc(cur, request_tlv_ptr, request_tlv_len); 00478 if(response_len < 1){ 00479 if (request_tlv_len > 0) { 00480 // TLV was ommitted but ok request. respond with ok status 00481 goto send_response; 00482 } 00483 return_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00484 goto failure; 00485 } 00486 ptr = response_ptr = ns_dyn_mem_alloc(response_len); 00487 if (!response_ptr) { 00488 return_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR; 00489 goto failure; 00490 } 00491 00492 ptr = thread_diagnostic_get_build(cur, response_ptr, request_tlv_ptr, request_tlv_len); 00493 00494 /* Send ACK to confirmable request */ 00495 if(request_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE){ 00496 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, return_code, COAP_CT_NONE, NULL, 0); 00497 response = 0; 00498 } 00499 00500 /* Send reply to d/da */ 00501 send_response: 00502 coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, address_copy, source_port, COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, 00503 THREAD_URI_DIAGNOSTIC_ANSWER, COAP_CT_OCTET_STREAM, response_ptr, ptr - response_ptr, NULL); 00504 00505 ns_dyn_mem_free(response_ptr); 00506 00507 return response; 00508 00509 failure: 00510 if(request_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE){ 00511 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, return_code, COAP_CT_NONE, NULL, 0); 00512 response = 0; 00513 } 00514 return response; 00515 } 00516 00517 /** 00518 * Public interface functions 00519 */ 00520 int thread_diagnostic_init(int8_t interface_id) 00521 { 00522 00523 thread_diagnostic_command_t *this = thread_diagnostic_command_find(interface_id); 00524 if (this) { 00525 return 0; 00526 } 00527 00528 this = ns_dyn_mem_alloc(sizeof(thread_diagnostic_command_t)); 00529 if (!this) { 00530 return -2; 00531 } 00532 00533 this->interface_id = interface_id; 00534 00535 this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL); 00536 if (this->coap_service_id < 0) { 00537 tr_error("Thread diagnostic init failed"); 00538 ns_dyn_mem_free(this); 00539 return -3; 00540 } 00541 /** 00542 * Thread Management uri registration 00543 */ 00544 coap_service_register_uri(this->coap_service_id, THREAD_URI_DIAGNOSTIC_REQUEST, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_diagnostic_command_request_cb); 00545 coap_service_register_uri(this->coap_service_id, THREAD_URI_DIAGNOSTIC_RESET, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_diagnostic_command_reset_cb); 00546 coap_service_register_uri(this->coap_service_id, THREAD_URI_DIAGNOSTIC_QUERY, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_diagnostic_command_query_cb); 00547 ns_list_add_to_start(&instance_list, this); 00548 00549 return 0; 00550 } 00551 00552 int thread_diagnostic_delete(int8_t interface_id) 00553 { 00554 thread_diagnostic_command_t *this = thread_diagnostic_command_find(interface_id); 00555 00556 if (!this) { 00557 return -1; 00558 } 00559 00560 coap_service_delete(this->coap_service_id); 00561 ns_list_remove(&instance_list, this); 00562 ns_dyn_mem_free(this); 00563 return 0; 00564 } 00565 00566 #endif
Generated on Tue Aug 9 2022 00:37:22 by
1.7.2