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