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_commissioning_api.c
00001 /* 00002 * Copyright (c) 2015-2019, 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 /*Nanostack includes*/ 00031 #include "nsconfig.h" 00032 00033 #include <string.h> 00034 #include "ns_types.h" 00035 #include "ns_list.h" 00036 #include "ns_trace.h" 00037 #include "nsdynmemLIB.h" 00038 #include "randLIB.h" 00039 #include "common_functions.h" 00040 #include "ns_sha256.h" 00041 00042 /*thread includes*/ 00043 #include "thread_config.h" 00044 #include "thread_management_if.h" 00045 #include "thread_meshcop_lib.h" 00046 #include "thread_management_api.h" 00047 #include "thread_commissioning_api.h" 00048 #include "thread_beacon.h" 00049 /*Private includes*/ 00050 #include "6LoWPAN/Thread/thread_common.h" 00051 #include "6LoWPAN/Thread/thread_management_internal.h" 00052 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h"// Get coordinator address 00053 00054 #define TRACE_GROUP TRACE_GROUP_THREAD_COMMISSIONING_API 00055 #ifdef HAVE_THREAD 00056 00057 #include "coap_service_api.h" 00058 00059 typedef struct device { 00060 uint8_t PSKd[32]; 00061 uint8_t kek[32];// shal libs needs 32 bytes kek is first 16 00062 uint8_t EUI64[8]; 00063 uint8_t IID[8]; 00064 thread_commissioning_joiner_finalisation_cb *joining_device_cb_ptr; 00065 uint16_t joiner_router_rloc; 00066 uint8_t PSKd_len; 00067 bool send_kek: 1; 00068 bool short_eui64: 1;/*< Use short format for bloom filter creation*/ 00069 00070 ns_list_link_t link; 00071 } device_t; 00072 00073 typedef NS_LIST_HEAD (device_t, link) device_list_t; 00074 00075 typedef struct commissioner_entry { 00076 device_list_t device_list; 00077 uint8_t destination_address[16]; 00078 uint8_t final_dest_address[16]; // Relay message final destination 00079 uint8_t leader_address[16]; // leader ALOC for contacting the leader 00080 uint8_t PSKc_ptr[16]; 00081 thread_commissioning_status_cb *status_cb_ptr; 00082 uint16_t destination_port; 00083 uint16_t session_id; 00084 int8_t management_instance; 00085 int8_t interface_id; 00086 int8_t coap_service_id; 00087 int8_t coap_secure_service_id; 00088 int8_t coap_secure_virtual_service_id; 00089 int8_t coap_udp_proxy_service_id; 00090 bool registered: 1; 00091 bool native_commissioner: 1; 00092 00093 ns_list_link_t link; 00094 } commissioner_t; 00095 00096 static NS_LIST_DEFINE(instance_list, commissioner_t, link); 00097 00098 const uint8_t any_device[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 00099 00100 /* 00101 * Commissioned device handlers; 00102 */ 00103 static device_t *device_create(commissioner_t *commissioner_ptr) 00104 { 00105 device_t *device_ptr = ns_dyn_mem_alloc(sizeof(device_t)); 00106 if (device_ptr) { 00107 memset(device_ptr, 0, sizeof(device_t)); 00108 device_ptr->send_kek = false; 00109 device_ptr->joining_device_cb_ptr = NULL; 00110 ns_list_add_to_start(&commissioner_ptr->device_list, device_ptr); 00111 } 00112 return device_ptr; 00113 } 00114 00115 static void device_delete(commissioner_t *commissioner_ptr, device_t *device_ptr) 00116 { 00117 if (device_ptr) { 00118 ns_list_remove(&commissioner_ptr->device_list, device_ptr); 00119 ns_dyn_mem_free(device_ptr); 00120 } 00121 return; 00122 } 00123 00124 static device_t *device_find(commissioner_t *commissioner_ptr, uint8_t EUI64[8]) 00125 { 00126 device_t *this = NULL; 00127 if (!commissioner_ptr || !EUI64) { 00128 return NULL; 00129 } 00130 00131 ns_list_foreach(device_t, cur_ptr, &commissioner_ptr->device_list) { 00132 if (memcmp(cur_ptr->EUI64, EUI64, 8) == 0) { 00133 this = cur_ptr; 00134 break; 00135 } 00136 } 00137 return this; 00138 } 00139 00140 static device_t *device_find_by_iid(commissioner_t *commissioner_ptr, uint8_t IID[8]) 00141 { 00142 device_t *this = NULL; 00143 if (!IID) { 00144 return NULL; 00145 } 00146 ns_list_foreach(device_t, cur_ptr, &commissioner_ptr->device_list) { 00147 tr_debug("device iid %s and commissioner iid %s", trace_array(cur_ptr->IID, 8), trace_array(IID, 8)); 00148 if (memcmp(cur_ptr->IID, IID, 8) == 0) { 00149 this = cur_ptr; 00150 break; 00151 } 00152 } 00153 return this; 00154 } 00155 #define device_get_first(commissioner) ns_list_get_first(&commissioner->device_list) 00156 00157 00158 /* Commissioner class handlers*/ 00159 static commissioner_t *commissioner_find(int8_t interface_id) 00160 { 00161 commissioner_t *this = NULL; 00162 ns_list_foreach(commissioner_t, cur_ptr, &instance_list) { 00163 if (cur_ptr->interface_id == interface_id) { 00164 this = cur_ptr; 00165 break; 00166 } 00167 } 00168 return this; 00169 } 00170 static commissioner_t *commissioner_find_by_service(int8_t service_id) 00171 { 00172 commissioner_t *this = NULL; 00173 ns_list_foreach(commissioner_t, cur_ptr, &instance_list) { 00174 if (cur_ptr->coap_service_id == service_id || cur_ptr->coap_secure_virtual_service_id == service_id || cur_ptr->coap_secure_service_id == service_id || cur_ptr->coap_udp_proxy_service_id == service_id) { 00175 this = cur_ptr; 00176 break; 00177 } 00178 } 00179 return this; 00180 } 00181 static commissioner_t *commissioner_create(int8_t interface_id) 00182 { 00183 commissioner_t *this = ns_dyn_mem_alloc(sizeof(commissioner_t)); 00184 if (this) { 00185 memset(this, 0, sizeof(commissioner_t)); 00186 this->interface_id = interface_id; 00187 this->registered = false; 00188 ns_list_init(&this->device_list); 00189 ns_list_add_to_start(&instance_list, this); 00190 } 00191 return this; 00192 } 00193 00194 static void commissioner_delete(commissioner_t *this) 00195 { 00196 if (this) { 00197 device_t *device_ptr = device_get_first(this); 00198 while (device_ptr != NULL) { 00199 device_delete(this, device_ptr); 00200 device_ptr = device_get_first(this); 00201 } 00202 ns_list_remove(&instance_list, this); 00203 ns_dyn_mem_free(this); 00204 } 00205 return; 00206 } 00207 00208 /*Internal helper functions*/ 00209 static int commissioning_meshcop_map_state(commissioning_state_e state) 00210 { 00211 if (state == COMMISSIONING_STATE_ACCEPT) { 00212 return 1; 00213 } else if (state == COMMISSIONING_STATE_PENDING) { 00214 return 0; 00215 } 00216 00217 return -1; 00218 } 00219 00220 00221 static int commission_finalisation_resp_send(int8_t coap_service_id, device_t *device_ptr, sn_coap_hdr_s *request_ptr, commissioning_state_e state) 00222 { 00223 commissioner_t *this = commissioner_find_by_service(coap_service_id); 00224 uint8_t payload[11];// 4 + 1 + 4 + 2 00225 uint8_t *ptr; 00226 00227 if (!this || !request_ptr || !device_ptr) { 00228 return -1; 00229 } 00230 00231 ptr = payload; 00232 ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, (uint8_t)commissioning_meshcop_map_state(state)); 00233 00234 thci_trace("Device - Comm|Direction - sent|EUI - %s|Type - JOIN_FIN.resp|Length - %d|Payload - %s", trace_array(device_ptr->EUI64, 8), (int)(ptr - payload), trace_array(payload, ptr - payload)); 00235 tr_debug("finalisation response send state:%d value:%d ", state, (uint8_t)commissioning_meshcop_map_state(state)); 00236 coap_service_response_send(coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload); 00237 return 0; 00238 } 00239 00240 /* 00241 * Callback functions 00242 */ 00243 00244 static int thread_commissioning_active_get_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00245 { 00246 commissioner_t *this = commissioner_find_by_service(service_id); 00247 commissioning_state_e state = COMMISSIONING_STATE_REJECT;// Default is accept if we get error it is rejected 00248 uint8_t *ptr; 00249 uint16_t len; 00250 (void) source_address; 00251 (void) source_port; 00252 00253 /* Transaction failed */ 00254 if (!response_ptr) { 00255 return -1; 00256 } 00257 00258 tr_debug("management get response from comm module"); 00259 if (!this) { 00260 return -2; 00261 } 00262 00263 if ((len = thread_meshcop_tlv_find(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_NETWORK_MESH_LOCAL_ULA, &ptr)) > 0) { 00264 state = COMMISSIONING_STATE_ACCEPT; 00265 tr_debug(" TLV ml prefix=%s\r\n", trace_array(ptr, len)); 00266 memcpy(this->leader_address, ptr, 8); 00267 memcpy(this->leader_address + 8, ADDR_SHORT_ADR_SUFFIC, 6); 00268 common_write_16_bit(0xfc00, this->leader_address + 14); 00269 } 00270 00271 if (this->status_cb_ptr) { 00272 this->status_cb_ptr(this->interface_id, this->session_id, state); 00273 } 00274 return 0; 00275 } 00276 00277 static int commissioning_leader_petition_recv_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00278 { 00279 commissioner_t *this = commissioner_find_by_service(service_id); 00280 commissioning_state_e state = COMMISSIONING_STATE_REJECT; 00281 uint16_t session_id = 0; 00282 uint8_t *ptr = NULL; 00283 char *uri_ptr = THREAD_URI_ACTIVE_GET; 00284 (void) source_address; 00285 (void) source_port; 00286 00287 tr_debug("Thread Petition response received service %d", service_id); 00288 if (!this) { 00289 return -1; 00290 } 00291 00292 if (!response_ptr || !response_ptr->payload_ptr || response_ptr->payload_len < 1) { 00293 tr_debug("invalid response"); 00294 thci_trace("commissionerPetitionError"); 00295 goto user_response; 00296 } 00297 00298 if ((2 <= thread_meshcop_tlv_data_get_uint16(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) && 00299 (1 <= thread_meshcop_tlv_find(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_STATE, &ptr) && *ptr == 1)) { 00300 state = COMMISSIONING_STATE_ACCEPT; 00301 thci_trace("commissionerPetitionAccepted"); 00302 this->session_id = session_id; 00303 this->registered = true; 00304 //@TODO order keep alive timer for the message and start sending it periodically 00305 } 00306 tr_debug("petition response session_id: %d state:%d", session_id, state); 00307 00308 // if registered and native commissioner send ACTIVE_GET to BBR to get mesh parameters 00309 // if not native set leader ALOC from stack 00310 if (this->native_commissioner) { 00311 coap_service_request_send(service_id, COAP_REQUEST_OPTIONS_NONE, this->destination_address, this->destination_port, 00312 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, uri_ptr, COAP_CT_OCTET_STREAM, NULL, 0, thread_commissioning_active_get_cb); 00313 return 0; 00314 } else { 00315 thread_management_get_leader_aloc(this->interface_id, this->leader_address); 00316 } 00317 00318 user_response: 00319 if (state == COMMISSIONING_STATE_REJECT) { 00320 thci_trace("commissionerPetitionRejected"); 00321 } 00322 if (this->status_cb_ptr) { 00323 this->status_cb_ptr(this->interface_id, this->session_id, state); 00324 } 00325 return 0; 00326 } 00327 00328 static int commissioning_keep_alive_recv_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr) 00329 { 00330 commissioner_t *this = commissioner_find_by_service(service_id); 00331 uint8_t *ptr; 00332 (void) source_address; 00333 (void) source_port; 00334 00335 tr_debug("Thread keep alive response received"); 00336 if (!this) { 00337 tr_warn("commissioner service missing!"); 00338 thci_trace("commissionerError"); 00339 return -1; 00340 } 00341 if (!response_ptr) { 00342 tr_warn("commission ka response without ptr!"); 00343 thci_trace("commissionerError"); 00344 return -1; 00345 } 00346 00347 if (1 <= thread_meshcop_tlv_find(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_STATE, &ptr) && *ptr == 1) { 00348 // only handle success 00349 return 0; 00350 } 00351 00352 this->session_id = 0; 00353 this->registered = false; 00354 if (this->status_cb_ptr) { 00355 this->status_cb_ptr(this->interface_id, this->session_id, COMMISSIONING_STATE_REJECT); 00356 } 00357 00358 return -2; 00359 } 00360 00361 static int commission_finalisation_req_recv_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00362 { 00363 commissioner_t *this = commissioner_find_by_service(service_id); 00364 uint8_t address[16]; 00365 device_t *device_ptr; 00366 int ret = -1;// always reject 00367 (void) source_port; 00368 00369 tr_debug("joiner finalisation recv addr %s", trace_ipv6(source_address)); 00370 if (!this || !source_address || !request_ptr) { 00371 return -1; 00372 } 00373 00374 device_ptr = device_find_by_iid(this, &source_address[8]); 00375 if (device_ptr) { 00376 ret = 0; // accept even without application confirmation 00377 } 00378 thci_trace("Device - Comm|Direction - recv|EUI - %s|Type - JOIN_FIN.req|Length - %d|Payload - %s", trace_array(device_ptr->EUI64, 8), request_ptr->payload_len, trace_array(request_ptr->payload_ptr, request_ptr->payload_len)); 00379 memcpy(address, source_address, 16); 00380 00381 if (device_ptr) { 00382 if (device_ptr->joining_device_cb_ptr) { 00383 ret = device_ptr->joining_device_cb_ptr(this->interface_id, &source_address[8], request_ptr->payload_ptr, request_ptr->payload_len); 00384 } 00385 00386 device_ptr->send_kek = true; 00387 } 00388 00389 if (ret == 0) { 00390 thci_trace("commissionerJoinerAccepted"); 00391 } 00392 00393 commission_finalisation_resp_send(service_id, device_ptr, request_ptr, ret == 0 ? COMMISSIONING_STATE_ACCEPT : COMMISSIONING_STATE_REJECT); 00394 coap_service_close_secure_connection(service_id, address, source_port); 00395 00396 return 0; 00397 } 00398 static int commission_application_provision_req_recv_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00399 { 00400 commissioner_t *this = commissioner_find_by_service(service_id); 00401 uint8_t payload[11];// 4 + 1 + 4 + 2 00402 uint8_t *ptr; 00403 00404 (void) source_port; 00405 00406 tr_debug("joiner application provisioning recv addr %s", trace_ipv6(source_address)); 00407 if (!this || !source_address || !request_ptr) { 00408 return -1; 00409 } 00410 00411 thci_trace("Device - Comm|Direction - recv|EUI - %s|Type - JOIN_APP.req|Length - %d|Payload - %s", trace_array(&source_address[8], 8), request_ptr->payload_len, trace_array(request_ptr->payload_ptr, request_ptr->payload_len)); 00412 00413 ptr = payload; 00414 ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 1); 00415 00416 thci_trace("Device - Comm|Direction - sent|EUI - %s|Type - JOIN_APP.resp|Length - %d|Payload - %s", trace_array(&source_address[8], 8), (int)(ptr - payload), trace_array(payload, ptr - payload)); 00417 coap_service_response_send(service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload); 00418 return 0; 00419 } 00420 00421 static int commission_dataset_changed_notify_recv_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00422 { 00423 (void)source_address; 00424 (void)source_port; 00425 00426 tr_debug("Dataset changed - notification received from: %s", trace_ipv6(source_address)); 00427 commissioner_t *this = commissioner_find_by_service(service_id); 00428 00429 if (!this) { 00430 return -1; 00431 } 00432 00433 coap_service_request_send(service_id, COAP_REQUEST_OPTIONS_NONE, this->destination_address, this->destination_port, 00434 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_ACTIVE_GET, COAP_CT_OCTET_STREAM, NULL, 0, thread_commissioning_active_get_cb); 00435 00436 coap_service_response_send(service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_NONE, NULL, 0); 00437 00438 return 0; 00439 } 00440 static int thread_commission_udp_proxy_receive_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00441 { 00442 tr_debug("Recv UDP_RX.ntf"); 00443 00444 commissioner_t *this = commissioner_find_by_service(service_id); 00445 uint8_t *udp_encapsulation_ptr, *udp_tmf_ptr; 00446 uint16_t udp_encapsulation_len, udp_tmf_len; 00447 uint8_t *ipv6_addr_ptr; 00448 uint16_t ipv6_addr_len; 00449 uint16_t dest_port; 00450 00451 (void) source_port; 00452 00453 if (!this || !source_address || !request_ptr) { 00454 return -1; // goto error response 00455 } 00456 00457 udp_encapsulation_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_UDP_ENCAPSULATION, &udp_encapsulation_ptr); 00458 ipv6_addr_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_IPV6_ADDRESS, &ipv6_addr_ptr); 00459 00460 if (udp_encapsulation_len == 0 || ipv6_addr_len < 16) { 00461 tr_warn("Corrupted UDP_RX.ntf received (%d, %d)", udp_encapsulation_len, ipv6_addr_len); 00462 return -1; 00463 } 00464 00465 dest_port = common_read_16_bit(udp_encapsulation_ptr + 2); 00466 udp_tmf_len = udp_encapsulation_len - 4; 00467 udp_tmf_ptr = udp_encapsulation_ptr + 4; 00468 00469 tr_debug("UDP_RX tmf: %s", trace_array(udp_tmf_ptr, udp_tmf_len)); 00470 00471 coap_service_virtual_socket_recv(this->coap_udp_proxy_service_id, ipv6_addr_ptr, dest_port, udp_tmf_ptr, udp_tmf_len); 00472 00473 return -1; // no response sent 00474 } 00475 00476 static uint8_t *bloom_filter_calculate(uint8_t *bloom_filter_ptr, device_list_t device_list, int *steering_tlv_max_length) 00477 { 00478 memset(bloom_filter_ptr, 0, *steering_tlv_max_length); 00479 ns_list_foreach(device_t, cur_ptr, &device_list) { 00480 if (memcmp(cur_ptr->EUI64, any_device, 8) != 0) { 00481 tr_debug("eui64 used on commissioning side = %s", trace_array(cur_ptr->EUI64, 8)); 00482 cur_ptr->IID[0] |= 2; //Changed IID to MAC extended address for bloom filter calculation 00483 thread_beacon_calculate_bloom_filter(bloom_filter_ptr, *steering_tlv_max_length, cur_ptr->IID, 8); 00484 cur_ptr->IID[0] &= ~2;//Restore IID 00485 } else { 00486 bloom_filter_ptr[0] = 0xff; 00487 *steering_tlv_max_length = 1; 00488 break; 00489 } 00490 } 00491 00492 return bloom_filter_ptr; 00493 } 00494 static int thread_commissioner_set_steering_data(commissioner_t *this, uint16_t session_id, uint8_t *steering_data_ptr, uint8_t steering_data_len) 00495 { 00496 uint8_t payload[24];/* 4 + 16 + 4*/ 00497 uint8_t *ptr; 00498 int8_t coap_service_id; 00499 if (!this || steering_data_len > 16) { 00500 return -1; 00501 } 00502 00503 ptr = payload; 00504 ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_STEERING_DATA, steering_data_len, steering_data_ptr); 00505 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_COMMISSIONER_SESSION_ID, session_id); 00506 00507 tr_debug("thread commissioner set steering data %s", trace_array(steering_data_ptr, steering_data_len)); 00508 memcpy(this->final_dest_address, this->leader_address, 16); 00509 //default uri for thread version 1.1 00510 char *uri = THREAD_URI_COMMISSIONER_SET; 00511 00512 if (this->native_commissioner) { 00513 coap_service_id = this->coap_udp_proxy_service_id; 00514 } else { 00515 coap_service_id = this->coap_service_id; 00516 } 00517 00518 coap_service_request_send(coap_service_id, COAP_REQUEST_OPTIONS_NONE, this->destination_address, this->destination_port, 00519 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, uri, COAP_CT_OCTET_STREAM, payload, ptr - payload, NULL); 00520 00521 return 0; 00522 } 00523 00524 static int commission_steering_data_update(commissioner_t *this) 00525 { 00526 //variable for steering tlv length - maximum possible length is 16 bytes - section 8.10.1.9 Max length 00527 int steering_tlv_length = 16; 00528 uint8_t bloom_filter_ptr[16]; 00529 int ret; 00530 00531 //bloom filter calculation function call 00532 bloom_filter_calculate(bloom_filter_ptr, this->device_list, &steering_tlv_length); 00533 tr_debug("Steering bloom set :%s", trace_array(bloom_filter_ptr, 16)); 00534 ret = thread_commissioner_set_steering_data(this, this->session_id, bloom_filter_ptr, steering_tlv_length); 00535 if (ret) { 00536 tr_warn("Steering data set failed %d", ret); 00537 return -1; 00538 } 00539 00540 return 0; 00541 } 00542 00543 /* 00544 * These functions are the relay endpoint for commissioner device. 00545 * this can be either: 00546 * secure native commissioner 00547 * or unsecure native commissioner 00548 * */ 00549 static int commission_relay_rx_recv_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00550 { 00551 commissioner_t *this = commissioner_find_by_service(service_id); 00552 uint8_t joiner_address[16] = { 0xfe, 0x80 }; 00553 uint8_t *joiner_iid_ptr; 00554 uint8_t *udp_ptr; 00555 uint16_t udp_len; 00556 uint16_t joiner_port; 00557 uint16_t joiner_router_rloc; 00558 device_t *device_ptr; 00559 (void) source_port; 00560 00561 if (!this || !source_address || !request_ptr) { 00562 return -1; // goto error response 00563 } 00564 00565 if ((0 == (udp_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_JOINER_ENCAPSULATION, &udp_ptr))) || 00566 (8 > thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_JOINER_IID, &joiner_iid_ptr)) || 00567 (2 > thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_JOINER_UDP_PORT, &joiner_port)) || 00568 (2 > thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_JOINER_ROUTER_LOCATOR, &joiner_router_rloc))) { 00569 tr_warn("Corrupted relay packet received"); 00570 return -1; 00571 } 00572 00573 memcpy(&joiner_address[8], joiner_iid_ptr, 8); 00574 tr_debug("Relay RX from (%x) addr %s, port %d, len:%d", joiner_router_rloc, trace_ipv6(joiner_address), joiner_port, udp_len); 00575 00576 device_ptr = device_find_by_iid(this, joiner_iid_ptr); 00577 if (!device_ptr) { 00578 tr_warn("unknown device connected"); 00579 //Interop HACK 00580 device_ptr = device_find(this, (uint8_t *)any_device); 00581 if (!device_ptr) { 00582 tr_warn("No catch all device added"); 00583 return -1; 00584 } 00585 00586 memcpy(device_ptr->IID, &joiner_address[8], 8); 00587 memcpy(device_ptr->EUI64, &joiner_address[8], 8); // This is wrong as we cannot reverse the SHA1 But ok For Any device 00588 device_ptr->EUI64[0] ^= 2;// We are searching for list of eui64 so need to flip 00589 if (commission_steering_data_update(this) != 0) { 00590 return -1; 00591 } 00592 tr_warn("catching device for iid:%s", trace_array(&joiner_address[8], 8)); 00593 } 00594 device_ptr->joiner_router_rloc = joiner_router_rloc; 00595 coap_service_virtual_socket_recv(this->coap_secure_virtual_service_id, joiner_address, joiner_port, udp_ptr, udp_len); 00596 return -1; // no response sent 00597 } 00598 00599 static int commission_virtual_socket_send_cb(int8_t service_id, uint8_t destination_addr_ptr[static 16], uint16_t port, const uint8_t *data_ptr, uint16_t data_len) 00600 { 00601 commissioner_t *this = commissioner_find_by_service(service_id); 00602 uint8_t destination_address[16]; 00603 uint16_t destination_port; 00604 device_t *device_ptr; 00605 uint8_t *payload_ptr; 00606 uint8_t *ptr; 00607 uint16_t payload_len; 00608 uint8_t destination_service_id; 00609 00610 tr_debug("Relay RX send addr %s, port %d, len:%d", trace_ipv6(destination_addr_ptr), port, data_len); 00611 if (!this || !destination_addr_ptr || !data_ptr) { 00612 return -1; 00613 } 00614 00615 device_ptr = device_find_by_iid(this, &destination_addr_ptr[8]); 00616 if (!device_ptr) { 00617 return -2; 00618 } 00619 payload_len = 4 + data_len + 4 + 8 + 4 + 2; 00620 00621 if (device_ptr->send_kek) { 00622 payload_len += 4 + 16; 00623 } 00624 00625 payload_ptr = ns_dyn_mem_alloc(payload_len); 00626 if (!payload_ptr) { 00627 return -3; 00628 } 00629 if (this->native_commissioner) { 00630 destination_service_id = this->coap_secure_service_id; 00631 memcpy(destination_address, this->destination_address, 16); 00632 destination_port = this->destination_port; 00633 } else { 00634 memset(destination_address, 0, 16); 00635 destination_service_id = this->coap_service_id; 00636 thread_management_get_ml_prefix(this->interface_id, destination_address); 00637 common_write_16_bit(0xfffe, &destination_address[11]); 00638 common_write_16_bit(device_ptr->joiner_router_rloc, &destination_address[14]); 00639 destination_port = THREAD_MANAGEMENT_PORT; 00640 } 00641 00642 tr_debug("Relay destination %s:%d", trace_ipv6(destination_address), destination_port); 00643 00644 ptr = payload_ptr; 00645 ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_JOINER_ENCAPSULATION, data_len, data_ptr); 00646 ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_JOINER_IID, 8, &destination_addr_ptr[8]); 00647 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_JOINER_UDP_PORT, port); 00648 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_JOINER_ROUTER_LOCATOR, device_ptr->joiner_router_rloc); 00649 00650 if (device_ptr->send_kek) { 00651 tr_debug("Relay RX Send KEK"); 00652 ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_JOINER_ROUTER_KEK, 16, device_ptr->kek); 00653 device_ptr->send_kek = false; 00654 } 00655 00656 coap_service_request_send(destination_service_id, COAP_REQUEST_OPTIONS_NONE, destination_address, destination_port, 00657 COAP_MSG_TYPE_NON_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_RELAY_TRANSMIT, COAP_CT_OCTET_STREAM, payload_ptr, ptr - payload_ptr, NULL); 00658 00659 ns_dyn_mem_free(payload_ptr); 00660 00661 return 0; 00662 } 00663 00664 static int commissioning_security_done_cb(int8_t service_id, uint8_t address[static 16], uint8_t keyblock[static 40]) 00665 { 00666 commissioner_t *this = commissioner_find_by_service(service_id); 00667 device_t *device_ptr; 00668 00669 if (!this) { 00670 return -1; 00671 } 00672 00673 tr_debug("Commissioner security done addr %s keyblock %s", trace_ipv6(address), trace_array(keyblock, 40)); 00674 device_ptr = device_find_by_iid(this, &address[8]); 00675 if (!device_ptr) { 00676 tr_debug("Commissioner device not found"); 00677 thci_trace("commissionerBrError"); 00678 return -1; 00679 } 00680 ns_sha256(keyblock, 40, device_ptr->kek); 00681 00682 return 0; 00683 } 00684 00685 static int joiner_commissioner_security_start_cb(int8_t service_id, uint8_t address[static 16], uint16_t port, uint8_t *pw, uint8_t *pw_len) 00686 { 00687 int ret = -1; 00688 (void)port; 00689 tr_info("commissionerJoinerDtlsSessionStarted"); 00690 00691 commissioner_t *this = commissioner_find_by_service(service_id); 00692 00693 if (!this) { 00694 return ret; 00695 } 00696 00697 device_t *device_ptr = device_find_by_iid(this, &address[8]); 00698 00699 if (device_ptr) { 00700 memcpy(pw, device_ptr->PSKd, device_ptr->PSKd_len); 00701 *pw_len = device_ptr->PSKd_len; 00702 ret = 0; 00703 // ret = coap_service_security_key_set( service_id, address, port, device_ptr->PSKd, device_ptr->PSKd_len ); 00704 } 00705 00706 return ret; 00707 } 00708 00709 static int commissioner_br_security_start_cb(int8_t service_id, uint8_t address[static 16], uint16_t port, uint8_t *pw, uint8_t *pw_len) 00710 { 00711 int ret = -1; 00712 (void)address; 00713 (void)port; 00714 tr_info("commissionerBrDtlsSessionStarted"); 00715 commissioner_t *this = commissioner_find_by_service(service_id); 00716 if (this) { 00717 memcpy(pw, this->PSKc_ptr, 16); 00718 *pw_len = 16; 00719 ret = 0; 00720 // ret = coap_service_security_key_set( service_id, address, port, this->PSKc_ptr, this->PSKc_len ); 00721 } 00722 00723 return ret; 00724 } 00725 00726 static int commissioner_br_security_done_cb(int8_t service_id, uint8_t address[16], uint8_t keyblock[static 40]) 00727 { 00728 (void)service_id; 00729 (void)address; 00730 (void)keyblock; 00731 thci_trace("commissionerBrAccepted"); 00732 thci_trace("commissionerPetitionStarted"); 00733 return 0; 00734 } 00735 00736 static int thread_commission_udp_proxy_virtual_socket_send_cb(int8_t service_id, uint8_t destination_addr_ptr[static 16], uint16_t port, const uint8_t *data_ptr, uint16_t data_len) 00737 { 00738 (void) port; 00739 uint8_t *payload_ptr; 00740 uint8_t *ptr; 00741 uint16_t payload_len; 00742 uint16_t source_port; 00743 00744 commissioner_t *this = commissioner_find_by_service(service_id); 00745 if (!this) { 00746 return -1; 00747 } 00748 00749 tr_debug("UDP_TX.ntf tmf: %s", trace_array(data_ptr, data_len)); 00750 if (!this || !destination_addr_ptr || !data_ptr) { 00751 return -1; 00752 } 00753 00754 payload_len = 2 + THREAD_IPV6_ADDRESS_TLV_LENGTH + 4 + 4 + data_len; // MESHCOP_TLV_IPV6_ADDRESS + MESHCOP_TLV_UDP_ENCAPSULATION 00755 00756 payload_ptr = ns_dyn_mem_alloc(payload_len); 00757 if (!payload_ptr) { 00758 return -3; 00759 } 00760 00761 ptr = payload_ptr; 00762 00763 tr_debug("br_address %s final dest_address %s and port %d", trace_ipv6(this->destination_address), 00764 trace_ipv6(this->final_dest_address), this->destination_port); 00765 00766 /* MESHCOP_TLV_IPV6_ADDRESS */ 00767 ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_IPV6_ADDRESS, THREAD_IPV6_ADDRESS_TLV_LENGTH, this->final_dest_address); 00768 00769 /* MESHCOP_TLV_UDP_ENCAPSULATION */ 00770 *ptr++ = MESHCOP_TLV_UDP_ENCAPSULATION; 00771 *ptr++ = 0xff; 00772 ptr = common_write_16_bit(2 + 2 + data_len, ptr); // length (Port x 2 + TMF message) 00773 source_port = randLIB_get_16bit(); // ephemeral port, 16-bit number 00774 ptr = common_write_16_bit(source_port, ptr); // source port, 00775 ptr = common_write_16_bit(THREAD_MANAGEMENT_PORT, ptr); // destination port 00776 memcpy(ptr, data_ptr, data_len); 00777 ptr += data_len; 00778 00779 /* Send UDP_TX.ntf */ 00780 coap_service_request_send(this->coap_secure_service_id, COAP_REQUEST_OPTIONS_NONE, this->destination_address, this->destination_port, 00781 COAP_MSG_TYPE_NON_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_UDP_TRANSMIT_NOTIFICATION, COAP_CT_OCTET_STREAM, payload_ptr, ptr - payload_ptr, NULL); 00782 00783 ns_dyn_mem_free(payload_ptr); 00784 00785 return 0; 00786 } 00787 00788 /* 00789 Public api functions 00790 */ 00791 int thread_commissioning_register(int8_t interface_id, uint8_t PSKc[static 16]) 00792 { 00793 commissioner_t *this = commissioner_find(interface_id); 00794 if (!this) { 00795 this = commissioner_create(interface_id); 00796 } 00797 if (!this) { 00798 return -2; 00799 } 00800 memcpy(this->PSKc_ptr, PSKc, 16); 00801 if (this->registered) { 00802 return 0; 00803 } 00804 this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL); 00805 coap_service_register_uri(this->coap_service_id, THREAD_URI_RELAY_RECEIVE, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_relay_rx_recv_cb); 00806 coap_service_register_uri(this->coap_service_id, THREAD_URI_JOINER_APPLICATION_REQUEST, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_application_provision_req_recv_cb); 00807 coap_service_register_uri(this->coap_service_id, THREAD_URI_DATASET_CHANGED, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_dataset_changed_notify_recv_cb); 00808 00809 this->coap_secure_service_id = coap_service_initialize(this->interface_id, THREAD_COMMISSIONING_PORT, COAP_SERVICE_OPTIONS_SECURE | COAP_SERVICE_OPTIONS_SECURE_BYPASS, commissioner_br_security_start_cb, commissioner_br_security_done_cb); 00810 coap_service_register_uri(this->coap_secure_service_id, THREAD_URI_RELAY_RECEIVE, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_relay_rx_recv_cb); 00811 coap_service_register_uri(this->coap_secure_service_id, THREAD_URI_UDP_RECVEIVE_NOTIFICATION, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_commission_udp_proxy_receive_cb); 00812 00813 this->coap_secure_virtual_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_SECURE | COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET, joiner_commissioner_security_start_cb, commissioning_security_done_cb); 00814 coap_service_register_uri(this->coap_secure_virtual_service_id, THREAD_URI_JOINER_FINALIZATION, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_finalisation_req_recv_cb); 00815 coap_service_virtual_socket_set_cb(this->coap_secure_virtual_service_id, commission_virtual_socket_send_cb); 00816 00817 this->coap_udp_proxy_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET, NULL, NULL); 00818 coap_service_virtual_socket_set_cb(this->coap_udp_proxy_service_id, thread_commission_udp_proxy_virtual_socket_send_cb); 00819 00820 return 0; 00821 } 00822 00823 int thread_commissioning_unregister(int8_t interface_id) 00824 { 00825 commissioner_t *this = commissioner_find(interface_id); 00826 if (!this) { 00827 return -1; 00828 } 00829 if (this->registered) { 00830 // Unregister the commissioner 00831 thread_commissioning_petition_keep_alive(this->interface_id, COMMISSIONING_STATE_REJECT); 00832 } 00833 00834 coap_service_delete(this->coap_service_id); 00835 coap_service_delete(this->coap_secure_service_id); 00836 coap_service_delete(this->coap_secure_virtual_service_id); 00837 coap_service_delete(this->coap_udp_proxy_service_id); 00838 00839 commissioner_delete(this); 00840 return 0; 00841 } 00842 00843 int thread_commissioning_petition_start(int8_t interface_id, char *commissioner_id_ptr, thread_commissioning_status_cb *status_cb_ptr) 00844 { 00845 commissioner_t *this; 00846 uint8_t payload[68];// max length for commissioner id is 64 + 4 byte header 00847 uint8_t commissioner_id_length; 00848 uint8_t service_id; 00849 uint8_t *ptr; 00850 char *uri_ptr; 00851 this = commissioner_find(interface_id); 00852 00853 if (!this) { 00854 return -1; 00855 } 00856 if (!commissioner_id_ptr) { 00857 return -2; 00858 } 00859 commissioner_id_length = strlen(commissioner_id_ptr); 00860 00861 if (commissioner_id_length > 64) { 00862 return -3; 00863 } 00864 00865 if (this->native_commissioner) { 00866 uri_ptr = THREAD_URI_COMMISSIONER_PETITION; 00867 service_id = this->coap_secure_service_id; 00868 } else { 00869 uri_ptr = THREAD_URI_LEADER_PETITION; 00870 service_id = this->coap_service_id; 00871 thread_management_get_leader_aloc(this->interface_id, this->destination_address); 00872 this->destination_port = THREAD_MANAGEMENT_PORT; 00873 } 00874 00875 this->status_cb_ptr = status_cb_ptr; 00876 ptr = payload; 00877 ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_COMMISSIONER_ID, commissioner_id_length, (uint8_t *) commissioner_id_ptr); 00878 00879 tr_debug("Thread Petition send to %s:%d id %s ", trace_ipv6(this->destination_address), this->destination_port, commissioner_id_ptr); 00880 00881 //TODO there must be way to set PSKc for request 00882 //TODO there must be way to make client transactions with security and no security 00883 coap_service_request_send(service_id, COAP_REQUEST_OPTIONS_NONE, this->destination_address, this->destination_port, 00884 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, uri_ptr, COAP_CT_OCTET_STREAM, payload, ptr - payload, commissioning_leader_petition_recv_cb); 00885 return 0; 00886 } 00887 00888 int thread_commissioning_petition_keep_alive(int8_t interface_id, commissioning_state_e state) 00889 { 00890 commissioner_t *this; 00891 uint8_t payload[7]; 00892 uint8_t *ptr; 00893 uint8_t service_id; 00894 char *uri_ptr; 00895 /* length is 00896 state tlv 3 00897 session id tlv 4 00898 */ 00899 this = commissioner_find(interface_id); 00900 00901 if (!this) { 00902 return -1; 00903 } 00904 00905 if (this->native_commissioner) { 00906 uri_ptr = THREAD_URI_COMMISSIONER_KEEP_ALIVE; 00907 service_id = this->coap_secure_service_id; 00908 } else { 00909 uri_ptr = THREAD_URI_LEADER_KEEP_ALIVE; 00910 service_id = this->coap_service_id; 00911 thread_management_get_leader_aloc(this->interface_id, this->destination_address); 00912 } 00913 00914 ptr = payload; 00915 ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, (uint8_t)commissioning_meshcop_map_state(state)); 00916 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_COMMISSIONER_SESSION_ID, this->session_id); 00917 00918 tr_debug("Commissioner keep alive send to %s:%d, session_id=%d, state=%d", 00919 trace_ipv6(this->destination_address), this->destination_port, 00920 this->session_id, state); 00921 thci_trace("commissionerKeepAliveSent"); 00922 if (state != COMMISSIONING_STATE_ACCEPT) { 00923 this->session_id = 0; 00924 } 00925 coap_service_request_send(service_id, COAP_REQUEST_OPTIONS_NONE, this->destination_address, this->destination_port, 00926 COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, uri_ptr, COAP_CT_OCTET_STREAM, payload, ptr - payload, commissioning_keep_alive_recv_cb); 00927 return 0; 00928 } 00929 00930 /* 00931 * PSKD (Pre-Shared Key -Device). A PSKD can be a minimum of six (6) uppercase alphanumeric characters long 00932 * 00933 * */ 00934 int thread_commissioning_device_add(int8_t interface_id, bool short_eui64, uint8_t EUI64[static 8], uint8_t *PSKd_ptr, uint8_t PSKd_len, thread_commissioning_joiner_finalisation_cb *joining_device_cb_ptr) 00935 { 00936 commissioner_t *this; 00937 device_t *device_ptr = NULL; 00938 00939 this = commissioner_find(interface_id); 00940 if (!this || PSKd_len < 1 || PSKd_len > 32 || !PSKd_ptr) { 00941 return -1; 00942 } 00943 00944 if (memcmp(EUI64, any_device, 8) == 0) { 00945 // always add 'any' device to allow multiple 'any' devices 00946 device_ptr = device_create(this); 00947 } 00948 00949 if (!device_ptr) { 00950 // try to find an existing device 00951 device_ptr = device_find(this, EUI64); 00952 } 00953 00954 if (!device_ptr) { 00955 // create device 00956 device_ptr = device_create(this); 00957 } 00958 00959 if (!device_ptr) { 00960 return -2; 00961 } 00962 00963 memcpy(device_ptr->EUI64, EUI64, 8); 00964 if (memcmp(EUI64, any_device, 8) != 0) { 00965 ns_sha256_nbits(EUI64, 8, device_ptr->IID, 64); 00966 device_ptr->IID[0] &= ~2; //local administered bit is set in MAC and flipped in IID 00967 } else { 00968 memcpy(device_ptr->IID, any_device, 8); 00969 } 00970 00971 memcpy(device_ptr->PSKd, PSKd_ptr, PSKd_len); 00972 device_ptr->PSKd_len = PSKd_len; 00973 device_ptr->short_eui64 = short_eui64; 00974 device_ptr->joining_device_cb_ptr = joining_device_cb_ptr; 00975 00976 if (commission_steering_data_update(this) != 0) { 00977 return -2; 00978 } 00979 thci_trace("commissionerNwkDataSynced"); 00980 return 0; 00981 } 00982 00983 int thread_commissioning_device_delete(int8_t interface_id, uint8_t EUI64[static 8]) 00984 { 00985 commissioner_t *this = commissioner_find(interface_id); 00986 00987 if (!this) { 00988 return -1; 00989 } 00990 00991 tr_debug("delete commissioned device EUI64:%s", trace_array(EUI64, 8)); 00992 device_delete(this, device_find(this, EUI64)); 00993 00994 if (commission_steering_data_update(this) != 0) { 00995 return -2; 00996 } 00997 return 0; 00998 } 00999 01000 01001 void *thread_commission_device_get_next(void *ptr, int8_t interface_id, bool *short_eui64, uint8_t EUI64[8], uint8_t PSKd[32], uint8_t *PSKd_len) 01002 { 01003 commissioner_t *this = commissioner_find(interface_id); 01004 if (!this) { 01005 return NULL; 01006 } 01007 device_t *cur_ptr = (device_t *)ptr; 01008 if (cur_ptr == NULL) { 01009 cur_ptr = (device_t *)ns_list_get_first(&this->device_list); 01010 } else { 01011 cur_ptr = (device_t *)ns_list_get_next(&this->device_list, cur_ptr); 01012 } 01013 if (!cur_ptr) { 01014 return NULL; 01015 } 01016 if (short_eui64) { 01017 *short_eui64 = cur_ptr->short_eui64; 01018 } 01019 if (EUI64) { 01020 memcpy(EUI64, cur_ptr->EUI64, 8); 01021 } 01022 if (PSKd) { 01023 memcpy(PSKd, cur_ptr->PSKd, 32); 01024 } 01025 if (PSKd_len) { 01026 *PSKd_len = cur_ptr->PSKd_len; 01027 } 01028 01029 return cur_ptr; 01030 } 01031 01032 int thread_commissioning_attach(int8_t interface_id, uint8_t *destination_address, uint16_t destination_port) 01033 { 01034 tr_debug("start ethernet commissioner attach"); 01035 commissioner_t *this = commissioner_find(interface_id); 01036 if (!this) { 01037 return -1; 01038 } 01039 memcpy(this->destination_address, destination_address, 16); 01040 this->destination_port = destination_port; 01041 this->native_commissioner = true; 01042 return 0; 01043 01044 } 01045 01046 int thread_commissioning_native_commissioner_start(int8_t interface_id, thread_commissioning_native_select_cb *cb_ptr) 01047 { 01048 protocol_interface_info_entry_t *cur; 01049 cur = protocol_stack_interface_info_get_by_id(interface_id); 01050 tr_debug("start native commissioner scanning"); 01051 if (!cur || !cur->thread_info) { 01052 return -1; 01053 } 01054 cur->thread_info->native_commissioner_link = NULL; 01055 cur->thread_info->native_commissioner_cb = cb_ptr; 01056 //TODO check if bootstrap is connected then we have to drop from old network and trigger scanning 01057 return 0; 01058 01059 } 01060 01061 int thread_commissioning_native_commissioner_stop(int8_t interface_id) 01062 { 01063 protocol_interface_info_entry_t *cur; 01064 cur = protocol_stack_interface_info_get_by_id(interface_id); 01065 tr_debug("stop native commissioner scanning"); 01066 if (!cur || !cur->thread_info) { 01067 return -1; 01068 } 01069 ns_dyn_mem_free(cur->thread_info->native_commissioner_link); 01070 cur->thread_info->native_commissioner_link = NULL; 01071 cur->thread_info->native_commissioner_cb = NULL; 01072 return 0; 01073 } 01074 01075 int thread_commissioning_native_commissioner_connect(int8_t interface_id, thread_commissioning_link_configuration_s *link_ptr) 01076 { 01077 protocol_interface_info_entry_t *cur; 01078 cur = protocol_stack_interface_info_get_by_id(interface_id); 01079 tr_debug("connect native commissioner"); 01080 if (!cur || !cur->thread_info) { 01081 return -1; 01082 } 01083 cur->thread_info->native_commissioner_link = ns_dyn_mem_alloc(sizeof(thread_commissioning_link_configuration_s)); 01084 if (!cur->thread_info->native_commissioner_link) { 01085 return -2; 01086 } 01087 *cur->thread_info->native_commissioner_link = *link_ptr; 01088 01089 commissioner_t *this = commissioner_find(interface_id); 01090 if (!this) { 01091 this = commissioner_create(interface_id); 01092 } 01093 if (!this) { 01094 return -3; 01095 } 01096 01097 this->native_commissioner = true; 01098 memcpy(this->destination_address, link_ptr->destination_address, 16); 01099 this->destination_port = link_ptr->destination_port; 01100 //TODO check that we are scanning for networks and reset backup timers 01101 01102 return 0; 01103 } 01104 01105 int thread_commissioning_native_commissioner_get_connection_info(int8_t interface_id, uint8_t *address_ptr, uint16_t *port) 01106 { 01107 commissioner_t *this = commissioner_find(interface_id); 01108 tr_debug("get native connection info"); 01109 if (!this) { 01110 return -1; 01111 } 01112 01113 memcpy(address_ptr, this->destination_address, 16); 01114 01115 *port = this->destination_port; 01116 return 0; 01117 } 01118 01119 int8_t thread_commissioning_get_management_id(int8_t interface_id) 01120 { 01121 commissioner_t *this = commissioner_find(interface_id); 01122 if (!this) { 01123 return -1; 01124 } 01125 01126 return this->management_instance; 01127 } 01128 01129 01130 #else 01131 int thread_commissioning_register(int8_t interface_id, uint8_t PSKc[static 16]) 01132 { 01133 (void)interface_id; 01134 (void)PSKc; 01135 return -1; 01136 } 01137 01138 int thread_commissioning_unregister(int8_t interface_id) 01139 { 01140 (void)interface_id; 01141 return -1; 01142 } 01143 01144 int thread_commissioning_device_add(int8_t interface_id, bool short_eui64, uint8_t EUI64[static 8], uint8_t *PSKd_ptr, uint8_t PSKd_len, thread_commissioning_joiner_finalisation_cb *joining_device_cb_ptr) 01145 { 01146 (void)interface_id; 01147 (void)short_eui64; 01148 (void)EUI64; 01149 (void)PSKd_ptr; 01150 (void)PSKd_len; 01151 (void)joining_device_cb_ptr; 01152 return -1; 01153 } 01154 01155 int thread_commissioning_device_delete(int8_t interface_id, uint8_t EUI64[8]) 01156 { 01157 (void)interface_id; 01158 (void)EUI64; 01159 return -1; 01160 } 01161 void *thread_commission_device_get_next(void *ptr, int8_t interface_id, bool *short_eui64, uint8_t EUI64[8], uint8_t PSKd[32], uint8_t *PSKd_len) 01162 { 01163 (void)ptr; 01164 (void)interface_id; 01165 (void)short_eui64; 01166 (void)EUI64; 01167 (void)PSKd; 01168 (void)PSKd_len; 01169 return NULL; 01170 } 01171 01172 int thread_commissioning_petition_keep_alive(int8_t interface_id, commissioning_state_e state) 01173 { 01174 (void)interface_id; 01175 (void)state; 01176 return -1; 01177 } 01178 01179 int thread_commissioning_petition_start(int8_t interface_id, char *commissioner_id_ptr, thread_commissioning_status_cb *status_cb_ptr) 01180 { 01181 (void)interface_id; 01182 (void)commissioner_id_ptr; 01183 (void)status_cb_ptr; 01184 return -1; 01185 } 01186 01187 int thread_commissioning_native_commissioner_get_connection_info(int8_t interface_id, uint8_t *address_ptr, uint16_t *port) 01188 { 01189 (void)interface_id; 01190 (void)address_ptr; 01191 (void)port; 01192 return -1; 01193 } 01194 01195 int8_t thread_commissioning_get_management_id(int8_t interface_id) 01196 { 01197 (void)interface_id; 01198 return -1; 01199 } 01200 01201 int thread_commissioning_native_commissioner_start(int8_t interface_id, thread_commissioning_native_select_cb *cb_ptr) 01202 { 01203 (void)interface_id; 01204 (void)cb_ptr; 01205 return -1; 01206 } 01207 01208 int thread_commissioning_native_commissioner_stop(int8_t interface_id) 01209 { 01210 (void)interface_id; 01211 return -1; 01212 } 01213 01214 int thread_commissioning_native_commissioner_connect(int8_t interface_id, thread_commissioning_link_configuration_s *link_ptr) 01215 { 01216 (void)interface_id; 01217 (void)link_ptr; 01218 return -1; 01219 } 01220 01221 int thread_commissioning_attach(int8_t interface_id, uint8_t *destination_address, uint16_t destination_port) 01222 { 01223 (void)interface_id; 01224 (void)destination_address; 01225 (void)destination_port; 01226 return -1; 01227 } 01228 01229 #endif
Generated on Tue Jul 12 2022 13:54:58 by
