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