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_management_client.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 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_cb_ptr = NULL; 00150 this->interface_id = interface_id; 00151 this->coap_asd_msg_id = 0; 00152 //TODO: Check if to use ephemeral port here 00153 this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL); 00154 ns_list_add_to_start(&instance_list, this); 00155 } 00156 return; 00157 } 00158 00159 void thread_management_client_delete(int8_t interface_id) 00160 { 00161 thread_management_t *this = thread_management_find(interface_id); 00162 if (!this) { 00163 return; 00164 } 00165 00166 coap_service_delete(this->coap_service_id); 00167 ns_list_remove(&instance_list, this); 00168 ns_dyn_mem_free(this); 00169 return; 00170 } 00171 int8_t thread_management_client_service_id_get(int8_t interface_id) 00172 { 00173 thread_management_t *this = thread_management_find(interface_id); 00174 if (!this) { 00175 return -1; 00176 } 00177 return this->coap_service_id; 00178 } 00179 00180 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) 00181 { 00182 thread_management_t *this = thread_management_find(interface_id); 00183 uint8_t payload[30];//!< max length 4 + 2, 4 + 8, 4 + 8, 00184 uint8_t destination[16]; 00185 uint8_t *ptr; 00186 protocol_interface_info_entry_t *cur; 00187 00188 if (!this || !mac || !id_cb) { 00189 return -1; 00190 } 00191 00192 if (0 != thread_management_get_leader_address(interface_id, destination)) { 00193 return -2; 00194 } 00195 00196 cur = protocol_stack_interface_info_get_by_id(interface_id); 00197 if (!cur || !cur->thread_info) { 00198 return -3; 00199 } 00200 00201 this->router_id_cb_ptr = id_cb; 00202 ptr = payload; 00203 if (router_id < 0xfffe) { 00204 ptr = thread_tmfcop_tlv_data_write_uint16(ptr, TMFCOP_TLV_RLOC16, router_id); 00205 } 00206 ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_MAC_ADDRESS, 8, mac); 00207 00208 tr_debug("thread router id get id: %d, mac %s", router_id, trace_array(mac, 8)); 00209 00210 ptr = thread_tmfcop_tlv_data_write_uint8(ptr, TMFCOP_TLV_STATUS, status); 00211 00212 return coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT, 00213 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); 00214 } 00215 00216 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) 00217 { 00218 thread_management_t *this = thread_management_find(interface_id); 00219 uint8_t payload[30];//!< max length 4 + 2, 4 + 8, 4 + 8, 00220 uint8_t destination[16]; 00221 uint8_t *ptr; 00222 00223 if (!this || !mac || router_id >= 0xfffe) { 00224 return -1; 00225 } 00226 00227 if (0 != thread_management_get_leader_address(interface_id, destination)) { 00228 return -2; 00229 } 00230 00231 this->router_id_release_cb_ptr = id_cb; 00232 ptr = payload; 00233 ptr = thread_tmfcop_tlv_data_write_uint16(ptr, TMFCOP_TLV_RLOC16, router_id); 00234 ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_MAC_ADDRESS, 8, mac); 00235 00236 tr_debug("thread router id release id: %d, mac %s", router_id, trace_array(mac, 8)); 00237 00238 coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT, 00239 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); 00240 return 0; 00241 } 00242 00243 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) 00244 { 00245 thread_management_t *this = thread_management_find_by_service(service_id); 00246 (void) source_address; 00247 (void) source_port; 00248 if (!this) { 00249 return -1; 00250 } 00251 00252 this->coap_asd_msg_id = 0; //clear the coap message id 00253 00254 if (this->network_data_set_cb_ptr) { 00255 if (response_ptr) { 00256 // If we get response status is OK 00257 this->network_data_set_cb_ptr(this->interface_id, 0, response_ptr->payload_ptr, response_ptr->payload_len); 00258 } else { 00259 this->network_data_set_cb_ptr(this->interface_id, -1, NULL, 0); 00260 } 00261 } 00262 00263 return 0; 00264 } 00265 00266 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) 00267 { 00268 thread_management_t *this = thread_management_find(interface_id); 00269 uint8_t destination[16]; 00270 00271 if (!this) { 00272 return -1; 00273 } 00274 00275 if (thread_management_get_leader_address(interface_id, destination)) { 00276 return -2; 00277 } 00278 00279 this->network_data_set_cb_ptr = set_cb; 00280 tr_debug("thread network data send to %s", trace_ipv6(destination)); 00281 00282 this->coap_asd_msg_id = coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT, 00283 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); 00284 00285 return 0; 00286 } 00287 00288 int thread_management_client_network_data_unregister(int8_t interface_id, uint16_t rloc16) 00289 { 00290 thread_management_t *this = thread_management_find(interface_id); 00291 uint8_t payload[4]; 00292 uint8_t *ptr; 00293 uint8_t destination[16]; 00294 00295 if (!this) { 00296 return -1; 00297 } 00298 00299 if (thread_management_get_leader_address(interface_id, destination)) { 00300 return -2; 00301 } 00302 ptr = payload; 00303 ptr = thread_tmfcop_tlv_data_write_uint16(ptr,TMFCOP_TLV_RLOC16,rloc16); 00304 00305 tr_debug("thread network data unregister"); 00306 00307 this->coap_asd_msg_id = coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT, 00308 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); 00309 return 0; 00310 } 00311 00312 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) 00313 { 00314 thread_management_t *this = thread_management_find_by_service(service_id); 00315 uint8_t *nd_data_options_ptr = NULL; 00316 int8_t status = -1; 00317 uint16_t nd_data_options_len = 0; 00318 (void) source_address; 00319 (void) source_port; 00320 if (!this) { 00321 return -1; 00322 } 00323 00324 if (response_ptr) { 00325 status = 0; // If we get response status is OK 00326 nd_data_options_len = thread_meshcop_tlv_find(response_ptr->payload_ptr, response_ptr->payload_len, TMFCOP_TLV_ND_DATA, &nd_data_options_ptr); 00327 } 00328 00329 if (this->neighbor_discovery_cb_ptr) { 00330 this->neighbor_discovery_cb_ptr(this->interface_id, status, nd_data_options_ptr, nd_data_options_len); 00331 } 00332 00333 return 0; 00334 } 00335 00336 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) 00337 { 00338 thread_management_t *this = thread_management_find(interface_id); 00339 uint8_t payload[2 + options_len]; //type + length + num of options 00340 uint8_t *ptr = &payload[2]; 00341 uint8_t payload_len; 00342 00343 if (!this || !options || options_len == 0) { 00344 return -1; 00345 } 00346 00347 this->neighbor_discovery_cb_ptr = set_cb; 00348 tr_debug("thread neighbor discovery data request"); 00349 00350 memcpy(ptr, options, options_len); 00351 thread_tmfcop_tlv_data_write_header(payload, TMFCOP_TLV_ND_OPTION, options_len); 00352 payload_len = 2 + options_len; //type + length + options 00353 00354 coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT, 00355 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); 00356 return 0; 00357 } 00358 00359 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) 00360 { 00361 thread_management_t *this = thread_management_find_by_service(service_id); 00362 (void)source_address; 00363 (void)source_port; 00364 uint8_t state; 00365 00366 tr_debug("Receiving active set response from leader"); 00367 00368 if(!this){ 00369 return -1; 00370 } 00371 00372 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00373 00374 if(!cur || !cur->thread_info){ 00375 return -2; 00376 } 00377 00378 if(!response_ptr || response_ptr->coap_status == COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED || !response_ptr->payload_ptr){ 00379 tr_error("active set failed"); 00380 goto getout; 00381 } 00382 if (1 > thread_meshcop_tlv_data_get_uint8(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_STATE, &state) || state != 1) { 00383 tr_error("active set rejected"); 00384 goto getout; 00385 } 00386 // TODO this is problematic we can not advertise before leader distributes the data 00387 // Current approach is to wait for leader 00388 // Spec says we could form own partition or just learn the older ones 00389 // We could then just clear timestamp from active set and learn new one. 00390 // thread_active_configuration_dataset_query_done(cur); 00391 return 0; 00392 00393 getout: 00394 00395 return 0; 00396 } 00397 00398 int8_t thread_management_client_active_set(int8_t interface_id, uint8_t *dst_address) 00399 { 00400 thread_management_t *this = thread_management_find(interface_id); 00401 uint16_t response_len; 00402 uint8_t *response_ptr, *ptr; 00403 tr_debug("Sending active set to leader"); 00404 00405 response_len = thread_joiner_application_next_active_config_length(interface_id); 00406 if (!this || response_len < 1) { 00407 return -1; 00408 } 00409 00410 response_ptr = ns_dyn_mem_alloc(response_len); 00411 if(!response_ptr) { 00412 tr_warn("Out of mem"); 00413 return -2; 00414 } 00415 ptr = thread_joiner_application_next_active_config_write(interface_id, response_ptr); 00416 00417 if (0 == coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, dst_address, THREAD_MANAGEMENT_PORT, 00418 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)) { 00419 tr_warn("request send failed"); 00420 } 00421 ns_dyn_mem_free(response_ptr); 00422 return 0; 00423 } 00424 00425 00426 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) 00427 { 00428 thread_management_t *this = thread_management_find_by_service(service_id); 00429 (void)source_address; 00430 (void)source_port; 00431 uint8_t state; 00432 00433 tr_debug("Receiving pending set response from leader"); 00434 00435 if(!this){ 00436 return -1; 00437 } 00438 00439 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00440 00441 if(!cur || !cur->thread_info){ 00442 return -2; 00443 } 00444 00445 if(!response_ptr || response_ptr->coap_status == COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED || !response_ptr->payload_ptr){ 00446 tr_error("pending set failed"); 00447 goto getout; 00448 } 00449 if (1 > thread_meshcop_tlv_data_get_uint8(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_STATE, &state) || state != 1) { 00450 tr_error("pending set rejected"); 00451 goto getout; 00452 } 00453 00454 return 0; 00455 00456 getout: 00457 return 0; 00458 } 00459 00460 int8_t thread_management_client_pending_set(int8_t interface_id, uint8_t *dst_address) 00461 { 00462 thread_management_t *this = thread_management_find(interface_id); 00463 uint16_t response_len; 00464 uint8_t *response_ptr, *ptr; 00465 tr_debug("Sending Pending set to leader"); 00466 00467 if (!this) { 00468 return -1; 00469 } 00470 00471 response_len = thread_joiner_application_next_pending_config_length(interface_id); 00472 00473 response_ptr = ns_dyn_mem_alloc(response_len); 00474 if(!response_ptr) { 00475 tr_warn("Out of mem"); 00476 return -2; 00477 } 00478 ptr = thread_joiner_application_next_pending_config_build(interface_id,response_ptr); 00479 00480 if (0 == coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, dst_address, THREAD_MANAGEMENT_PORT, 00481 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)) { 00482 tr_warn("request send failed"); 00483 } 00484 ns_dyn_mem_free(response_ptr); 00485 return 0; 00486 } 00487 00488 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) 00489 { 00490 thread_management_t *this = thread_management_find_by_service(service_id); 00491 (void)source_address; 00492 (void)source_port; 00493 uint8_t state; 00494 00495 tr_debug("Thread provisioning Received"); 00496 00497 if (!this) { 00498 return 0; 00499 } 00500 00501 thread_joiner_application_provisioning_set(this->interface_id, PROVISIONING_STATUS_NOT_DONE); 00502 00503 // CoAP request timed out 00504 if(!response_ptr) { 00505 return 0; 00506 } 00507 00508 if (response_ptr->msg_code != COAP_MSG_CODE_RESPONSE_CHANGED) { 00509 tr_error("Provisioning failed"); 00510 thread_joiner_application_provisioning_set(this->interface_id, PROVISIONING_STATUS_REJECTED); 00511 return 0; 00512 } 00513 00514 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00515 00516 if(!cur || !cur->thread_info || 1 > thread_meshcop_tlv_data_get_uint8(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_STATE, &state)){ 00517 tr_error("provisioning response failed"); 00518 return 0; 00519 } 00520 tr_debug("Thread provisioning status %d",state); 00521 00522 if (state == 1) { 00523 thread_joiner_application_provisioning_set(this->interface_id, PROVISIONING_STATUS_DONE); 00524 } else { 00525 thread_joiner_application_provisioning_set(this->interface_id, PROVISIONING_STATUS_REJECTED); 00526 } 00527 00528 return 0; 00529 } 00530 00531 int thread_management_client_provision_request(int8_t interface_id, uint8_t *dst_address, uint16_t port) 00532 { 00533 thread_management_t *this; 00534 uint8_t *ptr, *data_ptr; 00535 uint16_t length; 00536 00537 if (thread_joiner_application_provisioning_get(interface_id) == PROVISIONING_STATUS_ONGOING) { 00538 // wait for response to to the message 00539 return 0; 00540 } 00541 00542 tr_debug("Thread provisioning start send"); 00543 this = thread_management_find(interface_id); 00544 device_configuration_s *device_configuration_ptr = thread_joiner_application_get_device_config(interface_id); 00545 00546 if(!this || !device_configuration_ptr) { 00547 return -1; 00548 } 00549 length = thread_joiner_application_device_configuration_length(device_configuration_ptr); 00550 length += 3;// State 00551 00552 data_ptr = ptr = ns_dyn_mem_alloc(length); 00553 if (!ptr) { 00554 tr_error("Failed to start Commissioning"); 00555 return -1; 00556 } 00557 ptr = thread_joiner_application_device_configuration_build(ptr, device_configuration_ptr); 00558 ptr = thread_tmfcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 1); 00559 00560 00561 thread_joiner_application_provisioning_set(interface_id, PROVISIONING_STATUS_ONGOING); 00562 00563 coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, dst_address, port, 00564 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_JOINER_APPLICATION_REQUEST, COAP_CT_OCTET_STREAM, 00565 data_ptr, ptr - data_ptr, thread_management_client_provision_request_cb); 00566 00567 ns_dyn_mem_free(data_ptr); 00568 00569 return 0; 00570 } 00571 00572 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) 00573 { 00574 (void) service_id; 00575 (void) source_address; 00576 (void) source_port; 00577 (void) response_ptr; 00578 return 0; 00579 } 00580 00581 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]) 00582 { 00583 thread_management_t *this = thread_management_find(interface_id); 00584 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00585 00586 if (!this || !cur) { 00587 tr_warn("No resolution client or protocol info!"); 00588 return; 00589 } 00590 00591 tr_debug("Thread resolution client; proactive address notification"); 00592 00593 uint8_t payload[2 + 16 + 2 + 2 + 2 + 8]; 00594 uint8_t *ptr; 00595 00596 ptr = payload; 00597 ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_TARGET_EID, 16, address); 00598 ptr = thread_tmfcop_tlv_data_write_uint16(ptr, TMFCOP_TLV_RLOC16, rloc); 00599 ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_ML_EID, 8, ml_eid); 00600 00601 coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, 00602 dst_addr, THREAD_MANAGEMENT_PORT, 00603 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, 00604 THREAD_URI_ADDRESS_NOTIFICATION, COAP_CT_OCTET_STREAM, 00605 payload, ptr - payload, thread_management_client_proactive_an_cb); 00606 } 00607 00608 void thread_management_client_pending_coap_request_kill(int8_t interface_id) 00609 { 00610 thread_management_t *this = thread_management_find(interface_id); 00611 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00612 00613 if (!this || !cur) { 00614 return; 00615 } 00616 00617 cur->thread_info->localServerDataBase.publish_active = false; 00618 00619 if (this->coap_asd_msg_id != 0) { 00620 coap_service_request_delete(this->coap_service_id, this->coap_asd_msg_id); 00621 this->coap_asd_msg_id = 0; 00622 } 00623 00624 if (cur->thread_info->routerIdReqCoapID != 0) { 00625 coap_service_request_delete(this->coap_service_id, cur->thread_info->routerIdReqCoapID); 00626 cur->thread_info->routerIdReqCoapID = 0; 00627 } 00628 } 00629 00630 #endif
Generated on Fri Jul 22 2022 04:54:03 by
1.7.2
