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_management_client.c
00001 /* 00002 * Copyright (c) 2014-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 00030 00031 #include "nsconfig.h" 00032 #ifdef HAVE_THREAD 00033 #include <ns_types.h> 00034 #include "ns_list.h" 00035 #include "ns_trace.h" 00036 #include "nsdynmemLIB.h" 00037 #include "common_functions.h" 00038 #include "thread_tmfcop_lib.h" 00039 00040 #include "coap_service_api.h" 00041 00042 #include "thread_common.h" 00043 #include "thread_config.h" 00044 #include "thread_management_if.h" 00045 #include "6LoWPAN/Thread/thread_constants.h" 00046 #include "6LoWPAN/Thread/thread_tmfcop_lib.h" 00047 #include "6LoWPAN/Thread/thread_management_internal.h" 00048 #include "6LoWPAN/Thread/thread_joiner_application.h" 00049 #include "6LoWPAN/Thread/thread_network_data_lib.h" 00050 #include "6LoWPAN/Thread/thread_bootstrap.h" 00051 #include "6LoWPAN/Thread/thread_management_client.h" 00052 #include "NWK_INTERFACE/Include/protocol.h" 00053 00054 #define TRACE_GROUP TRACE_GROUP_THREAD_MANAGEMENT_CLIENT 00055 00056 typedef struct thread_management { 00057 thread_management_client_router_id_cb *router_id_cb_ptr; 00058 thread_management_client_router_id_cb *router_id_release_cb_ptr; 00059 thread_management_client_network_data_set_cb *network_data_set_cb_ptr; 00060 thread_management_client_network_data_set_cb *neighbor_discovery_cb_ptr; 00061 uint16_t coap_asd_msg_id; // COAP msg id for a/sd 00062 int8_t interface_id; 00063 int8_t coap_service_id; 00064 ns_list_link_t link; 00065 } thread_management_t; 00066 00067 static NS_LIST_DEFINE(instance_list, thread_management_t, link); 00068 00069 static thread_management_t *thread_management_find(int8_t interface_id) 00070 { 00071 thread_management_t *this = NULL; 00072 ns_list_foreach(thread_management_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 static thread_management_t *thread_management_find_by_service(int8_t service_id) 00081 { 00082 thread_management_t *this = NULL; 00083 ns_list_foreach(thread_management_t, cur_ptr, &instance_list) { 00084 if (cur_ptr->coap_service_id == service_id) { 00085 this = cur_ptr; 00086 break; 00087 } 00088 } 00089 return this; 00090 } 00091 00092 static int thread_management_client_get_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00093 { 00094 thread_management_t *this = thread_management_find_by_service(service_id); 00095 uint8_t *router_id_mask_ptr; 00096 uint16_t router_id; 00097 uint8_t *ptr; 00098 int8_t status = 0; 00099 (void)source_address; 00100 (void)source_port; 00101 00102 tr_debug("Thread router id client cb"); 00103 if (!this) { 00104 return -1; 00105 } 00106 00107 if ((!response_ptr) || 9 > thread_meshcop_tlv_find(response_ptr->payload_ptr, response_ptr->payload_len, TMFCOP_TLV_ROUTER_MASK, &router_id_mask_ptr) || 00108 2 > thread_meshcop_tlv_data_get_uint16(response_ptr->payload_ptr, response_ptr->payload_len, TMFCOP_TLV_RLOC16, &router_id) || 00109 1 > thread_meshcop_tlv_find(response_ptr->payload_ptr, response_ptr->payload_len, TMFCOP_TLV_STATUS, &ptr) || *ptr != 0) { 00110 // Failure in message 00111 status = -1; 00112 router_id_mask_ptr = NULL; 00113 router_id = 0xfffe; 00114 } 00115 00116 if (this->router_id_cb_ptr) { 00117 this->router_id_cb_ptr(this->interface_id, status, router_id, router_id_mask_ptr); 00118 } 00119 00120 return 0; 00121 } 00122 00123 static int thread_management_client_release_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00124 { 00125 thread_management_t *this = thread_management_find_by_service(service_id); 00126 (void) source_address; 00127 (void) source_port; 00128 (void) response_ptr; 00129 if (this && this->router_id_release_cb_ptr) { 00130 this->router_id_release_cb_ptr(this->interface_id, 0, 0xfffe, NULL); 00131 } 00132 return 0; 00133 } 00134 00135 /** 00136 * Public Api functions 00137 */ 00138 void thread_management_client_init(int8_t interface_id) 00139 { 00140 thread_management_t *this = thread_management_find(interface_id); 00141 if (this) { 00142 return; 00143 } 00144 00145 this = ns_dyn_mem_alloc(sizeof(thread_management_t)); 00146 00147 if (this) { 00148 this->network_data_set_cb_ptr = NULL; 00149 this->router_id_release_cb_ptr = NULL; 00150 this->neighbor_discovery_cb_ptr = NULL; 00151 this->router_id_cb_ptr = NULL; 00152 this->interface_id = interface_id; 00153 this->coap_asd_msg_id = 0; 00154 //TODO: Check if to use ephemeral port here 00155 this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL); 00156 ns_list_add_to_start(&instance_list, this); 00157 } 00158 return; 00159 } 00160 00161 void thread_management_client_delete(int8_t interface_id) 00162 { 00163 thread_management_t *this = thread_management_find(interface_id); 00164 if (!this) { 00165 return; 00166 } 00167 00168 coap_service_delete(this->coap_service_id); 00169 ns_list_remove(&instance_list, this); 00170 ns_dyn_mem_free(this); 00171 return; 00172 } 00173 int8_t thread_management_client_service_id_get(int8_t interface_id) 00174 { 00175 thread_management_t *this = thread_management_find(interface_id); 00176 if (!this) { 00177 return -1; 00178 } 00179 return this->coap_service_id; 00180 } 00181 00182 int thread_management_client_router_id_get(int8_t interface_id, uint8_t mac[8], uint16_t router_id, thread_management_client_router_id_cb *id_cb, uint8_t status) 00183 { 00184 thread_management_t *this = thread_management_find(interface_id); 00185 uint8_t payload[30];//!< max length 4 + 2, 4 + 8, 4 + 8, 00186 uint8_t destination[16]; 00187 uint8_t *ptr; 00188 protocol_interface_info_entry_t *cur; 00189 00190 if (!this || !mac || !id_cb) { 00191 return -1; 00192 } 00193 00194 if (0 != thread_management_get_leader_address(interface_id, destination)) { 00195 return -2; 00196 } 00197 00198 cur = protocol_stack_interface_info_get_by_id(interface_id); 00199 if (!cur || !cur->thread_info) { 00200 return -3; 00201 } 00202 00203 this->router_id_cb_ptr = id_cb; 00204 ptr = payload; 00205 if (router_id < 0xfffe) { 00206 ptr = thread_tmfcop_tlv_data_write_uint16(ptr, TMFCOP_TLV_RLOC16, router_id); 00207 } 00208 ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_MAC_ADDRESS, 8, mac); 00209 00210 tr_debug("thread router id get id: %d, mac %s", router_id, trace_array(mac, 8)); 00211 00212 ptr = thread_tmfcop_tlv_data_write_uint8(ptr, TMFCOP_TLV_STATUS, status); 00213 00214 return coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT, 00215 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_ROUTER_ID_ASSIGNMENT, COAP_CT_OCTET_STREAM, payload, ptr - payload, thread_management_client_get_cb); 00216 } 00217 00218 int thread_management_client_router_id_release(int8_t interface_id, uint8_t mac[8], uint16_t router_id, thread_management_client_router_id_cb *id_cb) 00219 { 00220 thread_management_t *this = thread_management_find(interface_id); 00221 uint8_t payload[30];//!< max length 4 + 2, 4 + 8, 4 + 8, 00222 uint8_t destination[16]; 00223 uint8_t *ptr; 00224 00225 if (!this || !mac || router_id >= 0xfffe) { 00226 return -1; 00227 } 00228 00229 if (0 != thread_management_get_leader_address(interface_id, destination)) { 00230 return -2; 00231 } 00232 00233 this->router_id_release_cb_ptr = id_cb; 00234 ptr = payload; 00235 ptr = thread_tmfcop_tlv_data_write_uint16(ptr, TMFCOP_TLV_RLOC16, router_id); 00236 ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_MAC_ADDRESS, 8, mac); 00237 00238 tr_debug("thread router id release id: %d, mac %s", router_id, trace_array(mac, 8)); 00239 00240 coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT, 00241 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_ROUTER_ID_RELEASE, COAP_CT_OCTET_STREAM, payload, ptr - payload, thread_management_client_release_cb); 00242 return 0; 00243 } 00244 00245 static int thread_management_client_register_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00246 { 00247 thread_management_t *this = thread_management_find_by_service(service_id); 00248 (void) source_address; 00249 (void) source_port; 00250 if (!this) { 00251 return -1; 00252 } 00253 00254 this->coap_asd_msg_id = 0; //clear the coap message id 00255 00256 if (this->network_data_set_cb_ptr) { 00257 if (response_ptr) { 00258 // If we get response status is OK 00259 this->network_data_set_cb_ptr(this->interface_id, 0, response_ptr->payload_ptr, response_ptr->payload_len); 00260 } else { 00261 this->network_data_set_cb_ptr(this->interface_id, -1, NULL, 0); 00262 } 00263 } 00264 00265 return 0; 00266 } 00267 00268 int thread_management_client_network_data_register(int8_t interface_id, uint8_t *data_ptr, uint16_t data_len, thread_management_client_network_data_set_cb *set_cb) 00269 { 00270 thread_management_t *this = thread_management_find(interface_id); 00271 uint8_t destination[16]; 00272 00273 if (!this) { 00274 return -1; 00275 } 00276 00277 if (thread_management_get_leader_address(interface_id, destination)) { 00278 return -2; 00279 } 00280 00281 this->network_data_set_cb_ptr = set_cb; 00282 tr_debug("thread network data send to %s", trace_ipv6(destination)); 00283 00284 this->coap_asd_msg_id = coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT, 00285 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_NETWORK_DATA, COAP_CT_OCTET_STREAM, data_ptr, data_len, thread_management_client_register_cb); 00286 00287 return 0; 00288 } 00289 00290 int thread_management_client_network_data_unregister(int8_t interface_id, uint16_t rloc16) 00291 { 00292 thread_management_t *this = thread_management_find(interface_id); 00293 uint8_t payload[4]; 00294 uint8_t *ptr; 00295 uint8_t destination[16]; 00296 00297 if (!this) { 00298 return -1; 00299 } 00300 00301 if (thread_management_get_leader_address(interface_id, destination)) { 00302 return -2; 00303 } 00304 ptr = payload; 00305 ptr = thread_tmfcop_tlv_data_write_uint16(ptr,TMFCOP_TLV_RLOC16,rloc16); 00306 00307 tr_debug("thread network data unregister"); 00308 00309 this->coap_asd_msg_id = coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT, 00310 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_NETWORK_DATA, COAP_CT_OCTET_STREAM, payload, ptr - payload, thread_management_client_register_cb); 00311 return 0; 00312 } 00313 00314 static int thread_management_client_neighbor_discovery_data_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00315 { 00316 thread_management_t *this = thread_management_find_by_service(service_id); 00317 uint8_t *nd_data_options_ptr = NULL; 00318 int8_t status = -1; 00319 uint16_t nd_data_options_len = 0; 00320 (void) source_address; 00321 (void) source_port; 00322 if (!this) { 00323 return -1; 00324 } 00325 00326 if (response_ptr) { 00327 status = 0; // If we get response status is OK 00328 nd_data_options_len = thread_meshcop_tlv_find(response_ptr->payload_ptr, response_ptr->payload_len, TMFCOP_TLV_ND_DATA, &nd_data_options_ptr); 00329 } 00330 00331 if (this->neighbor_discovery_cb_ptr) { 00332 this->neighbor_discovery_cb_ptr(this->interface_id, status, nd_data_options_ptr, nd_data_options_len); 00333 } 00334 00335 return 0; 00336 } 00337 00338 int thread_management_client_get_interface_id_by_service_id(int8_t service_id) 00339 { 00340 thread_management_t *this = thread_management_find_by_service(service_id); 00341 if (!this) { 00342 return -1; 00343 } 00344 return this->interface_id; 00345 } 00346 00347 int thread_management_client_neighbor_discovery_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_management_client_network_data_set_cb *set_cb) 00348 { 00349 thread_management_t *this = thread_management_find(interface_id); 00350 uint8_t payload[2 + options_len]; //type + length + num of options 00351 uint8_t *ptr = &payload[2]; 00352 uint8_t payload_len; 00353 00354 if (!this || !options || options_len == 0) { 00355 return -1; 00356 } 00357 00358 this->neighbor_discovery_cb_ptr = set_cb; 00359 tr_debug("thread neighbor discovery data request"); 00360 00361 memcpy(ptr, options, options_len); 00362 thread_tmfcop_tlv_data_write_header(payload, TMFCOP_TLV_ND_OPTION, options_len); 00363 payload_len = 2 + options_len; //type + length + options 00364 00365 coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT, 00366 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_NEIGHBOR_DISCOVERY_DATA_REQ, COAP_CT_OCTET_STREAM, payload, payload_len, thread_management_client_neighbor_discovery_data_cb); 00367 return 0; 00368 } 00369 00370 static int thread_management_client_active_set_response_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00371 { 00372 thread_management_t *this = thread_management_find_by_service(service_id); 00373 (void)source_address; 00374 (void)source_port; 00375 uint8_t state; 00376 00377 tr_debug("Receiving active set response from leader"); 00378 00379 if(!this){ 00380 return -1; 00381 } 00382 00383 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00384 00385 if(!cur || !cur->thread_info){ 00386 return -2; 00387 } 00388 00389 if(!response_ptr || response_ptr->coap_status == COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED || !response_ptr->payload_ptr){ 00390 tr_error("active set failed"); 00391 goto getout; 00392 } 00393 if (1 > thread_meshcop_tlv_data_get_uint8(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_STATE, &state) || state != 1) { 00394 tr_error("active set rejected"); 00395 goto getout; 00396 } 00397 // TODO this is problematic we can not advertise before leader distributes the data 00398 // Current approach is to wait for leader 00399 // Spec says we could form own partition or just learn the older ones 00400 // We could then just clear timestamp from active set and learn new one. 00401 // thread_active_configuration_dataset_query_done(cur); 00402 return 0; 00403 00404 getout: 00405 00406 return 0; 00407 } 00408 00409 int8_t thread_management_client_active_set(int8_t interface_id, uint8_t *dst_address) 00410 { 00411 thread_management_t *this = thread_management_find(interface_id); 00412 uint16_t response_len; 00413 uint8_t *response_ptr, *ptr; 00414 tr_debug("Sending active set to leader"); 00415 00416 response_len = thread_joiner_application_next_active_config_length(interface_id); 00417 if (!this || response_len < 1) { 00418 return -1; 00419 } 00420 00421 response_ptr = ns_dyn_mem_alloc(response_len); 00422 if(!response_ptr) { 00423 tr_warn("Out of mem"); 00424 return -2; 00425 } 00426 ptr = thread_joiner_application_next_active_config_write(interface_id, response_ptr); 00427 00428 if (0 == coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, dst_address, THREAD_MANAGEMENT_PORT, 00429 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_ACTIVE_SET, COAP_CT_OCTET_STREAM, response_ptr, (uint16_t)(ptr -response_ptr), thread_management_client_active_set_response_cb)) { 00430 tr_warn("request send failed"); 00431 } 00432 ns_dyn_mem_free(response_ptr); 00433 return 0; 00434 } 00435 00436 00437 static int thread_management_client_pending_set_response_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00438 { 00439 thread_management_t *this = thread_management_find_by_service(service_id); 00440 (void)source_address; 00441 (void)source_port; 00442 uint8_t state; 00443 00444 tr_debug("Receiving pending set response from leader"); 00445 00446 if(!this){ 00447 return -1; 00448 } 00449 00450 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00451 00452 if(!cur || !cur->thread_info){ 00453 return -2; 00454 } 00455 00456 if(!response_ptr || response_ptr->coap_status == COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED || !response_ptr->payload_ptr){ 00457 tr_error("pending set failed"); 00458 goto getout; 00459 } 00460 if (1 > thread_meshcop_tlv_data_get_uint8(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_STATE, &state) || state != 1) { 00461 tr_error("pending set rejected"); 00462 goto getout; 00463 } 00464 00465 return 0; 00466 00467 getout: 00468 return 0; 00469 } 00470 00471 int8_t thread_management_client_pending_set(int8_t interface_id, uint8_t *dst_address) 00472 { 00473 thread_management_t *this = thread_management_find(interface_id); 00474 uint16_t response_len; 00475 uint8_t *response_ptr, *ptr; 00476 tr_debug("Sending Pending set to leader"); 00477 00478 if (!this) { 00479 return -1; 00480 } 00481 00482 response_len = thread_joiner_application_next_pending_config_length(interface_id); 00483 00484 response_ptr = ns_dyn_mem_alloc(response_len); 00485 if(!response_ptr) { 00486 tr_warn("Out of mem"); 00487 return -2; 00488 } 00489 ptr = thread_joiner_application_next_pending_config_build(interface_id,response_ptr); 00490 00491 if (0 == coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, dst_address, THREAD_MANAGEMENT_PORT, 00492 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_PENDING_SET, COAP_CT_OCTET_STREAM, response_ptr, (uint16_t) (ptr - response_ptr), thread_management_client_pending_set_response_cb)) { 00493 tr_warn("request send failed"); 00494 } 00495 ns_dyn_mem_free(response_ptr); 00496 return 0; 00497 } 00498 00499 static int thread_management_client_provision_request_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00500 { 00501 thread_management_t *this = thread_management_find_by_service(service_id); 00502 (void)source_address; 00503 (void)source_port; 00504 uint8_t state; 00505 00506 tr_debug("Thread provisioning Received"); 00507 00508 if (!this) { 00509 return 0; 00510 } 00511 00512 thread_joiner_application_provisioning_set(this->interface_id, PROVISIONING_STATUS_NOT_DONE); 00513 00514 // CoAP request timed out 00515 if(!response_ptr) { 00516 return 0; 00517 } 00518 00519 if (response_ptr->msg_code != COAP_MSG_CODE_RESPONSE_CHANGED) { 00520 tr_error("Provisioning failed"); 00521 thread_joiner_application_provisioning_set(this->interface_id, PROVISIONING_STATUS_REJECTED); 00522 return 0; 00523 } 00524 00525 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00526 00527 if(!cur || !cur->thread_info || 1 > thread_meshcop_tlv_data_get_uint8(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_STATE, &state)){ 00528 tr_error("provisioning response failed"); 00529 return 0; 00530 } 00531 tr_debug("Thread provisioning status %d",state); 00532 00533 if (state == 1) { 00534 thread_joiner_application_provisioning_set(this->interface_id, PROVISIONING_STATUS_DONE); 00535 } else { 00536 thread_joiner_application_provisioning_set(this->interface_id, PROVISIONING_STATUS_REJECTED); 00537 } 00538 00539 return 0; 00540 } 00541 00542 int thread_management_client_provision_request(int8_t interface_id, uint8_t *dst_address, uint16_t port) 00543 { 00544 thread_management_t *this; 00545 uint8_t *ptr, *data_ptr; 00546 uint16_t length; 00547 00548 if (thread_joiner_application_provisioning_get(interface_id) == PROVISIONING_STATUS_ONGOING) { 00549 // wait for response to to the message 00550 return 0; 00551 } 00552 00553 tr_debug("Thread provisioning start send"); 00554 this = thread_management_find(interface_id); 00555 device_configuration_s *device_configuration_ptr = thread_joiner_application_get_device_config(interface_id); 00556 00557 if(!this || !device_configuration_ptr) { 00558 return -1; 00559 } 00560 length = thread_joiner_application_device_configuration_length(device_configuration_ptr); 00561 length += 3;// State 00562 00563 data_ptr = ptr = ns_dyn_mem_alloc(length); 00564 if (!ptr) { 00565 tr_error("Failed to start Commissioning"); 00566 return -1; 00567 } 00568 ptr = thread_joiner_application_device_configuration_build(ptr, device_configuration_ptr); 00569 ptr = thread_tmfcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 1); 00570 00571 00572 thread_joiner_application_provisioning_set(interface_id, PROVISIONING_STATUS_ONGOING); 00573 00574 coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, dst_address, port, 00575 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_JOINER_APPLICATION_REQUEST, COAP_CT_OCTET_STREAM, 00576 data_ptr, ptr - data_ptr, thread_management_client_provision_request_cb); 00577 00578 ns_dyn_mem_free(data_ptr); 00579 00580 return 0; 00581 } 00582 00583 static int thread_management_client_proactive_an_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00584 { 00585 (void) service_id; 00586 (void) source_address; 00587 (void) source_port; 00588 (void) response_ptr; 00589 return 0; 00590 } 00591 00592 void thread_management_client_proactive_an(int8_t interface_id, const uint8_t address[16], const uint16_t rloc, const uint8_t ml_eid[8], const uint8_t dst_addr[16]) 00593 { 00594 thread_management_t *this = thread_management_find(interface_id); 00595 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00596 00597 if (!this || !cur) { 00598 tr_warn("No resolution client or protocol info!"); 00599 return; 00600 } 00601 00602 tr_debug("Thread resolution client; proactive address notification"); 00603 00604 uint8_t payload[2 + 16 + 2 + 2 + 2 + 8]; 00605 uint8_t *ptr; 00606 00607 ptr = payload; 00608 ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_TARGET_EID, 16, address); 00609 ptr = thread_tmfcop_tlv_data_write_uint16(ptr, TMFCOP_TLV_RLOC16, rloc); 00610 ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_ML_EID, 8, ml_eid); 00611 00612 coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, 00613 dst_addr, THREAD_MANAGEMENT_PORT, 00614 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, 00615 THREAD_URI_ADDRESS_NOTIFICATION, COAP_CT_OCTET_STREAM, 00616 payload, ptr - payload, thread_management_client_proactive_an_cb); 00617 } 00618 00619 void thread_management_client_pending_coap_request_kill(int8_t interface_id) 00620 { 00621 thread_management_t *this = thread_management_find(interface_id); 00622 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00623 00624 if (!this || !cur) { 00625 return; 00626 } 00627 00628 cur->thread_info->localServerDataBase.publish_active = false; 00629 00630 if (this->coap_asd_msg_id != 0) { 00631 coap_service_request_delete(this->coap_service_id, this->coap_asd_msg_id); 00632 this->coap_asd_msg_id = 0; 00633 } 00634 00635 if (cur->thread_info->routerIdReqCoapID != 0) { 00636 coap_service_request_delete(this->coap_service_id, cur->thread_info->routerIdReqCoapID); 00637 cur->thread_info->routerIdReqCoapID = 0; 00638 } 00639 } 00640 00641 #endif
Generated on Tue Aug 9 2022 00:37:23 by
1.7.2