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
wisun_tasklet.c
00001 /* 00002 * Copyright (c) 2018-2019 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include <string.h> //memset 00018 #include "eventOS_event_timer.h" 00019 #include "common_functions.h" 00020 #include "ip6string.h" //ip6tos 00021 #include "nsdynmemLIB.h" 00022 #include "include/wisun_tasklet.h" 00023 #include "include/mesh_system.h" 00024 #include "ns_event_loop.h" 00025 #include "fhss_api.h " 00026 #include "fhss_config.h " 00027 #include "multicast_api.h" 00028 #include "mac_api.h" 00029 #include "sw_mac.h" 00030 #include "ns_list.h" 00031 #include "net_interface.h" 00032 #include "ws_management_api.h" //ws_management_node_init 00033 #ifdef MBED_CONF_MBED_MESH_API_CERTIFICATE_HEADER 00034 #if !defined(MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE) || !defined(MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE) || \ 00035 !defined(MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY) 00036 #error Invalid Wi-SUN certificate configuration 00037 #endif 00038 #include MBED_CONF_MBED_MESH_API_CERTIFICATE_HEADER 00039 #endif 00040 00041 // For tracing we need to define flag, have include and define group 00042 //#define HAVE_DEBUG 00043 #define TRACE_GROUP "WSND" 00044 #include "ns_trace.h" 00045 00046 // Tasklet timer events 00047 #define TIMER_EVENT_START_BOOTSTRAP 1 00048 #define INVALID_INTERFACE_ID (-1) 00049 #define INTERFACE_NAME "WiSunInterface" 00050 /* 00051 * Mesh tasklet states. 00052 */ 00053 typedef enum { 00054 TASKLET_STATE_CREATED = 0, 00055 TASKLET_STATE_INITIALIZED, 00056 TASKLET_STATE_BOOTSTRAP_STARTED, 00057 TASKLET_STATE_BOOTSTRAP_FAILED, 00058 TASKLET_STATE_BOOTSTRAP_READY 00059 } tasklet_state_t; 00060 00061 /* 00062 * Mesh tasklet data structure. 00063 */ 00064 typedef struct { 00065 void (*mesh_api_cb)(mesh_connection_status_t nwk_status); 00066 tasklet_state_t tasklet_state; 00067 int8_t tasklet; 00068 net_6lowpan_mode_e operating_mode; 00069 net_6lowpan_mode_extension_e operating_mode_extension; 00070 int8_t network_interface_id; 00071 } wisun_tasklet_data_str_t; 00072 00073 typedef struct { 00074 char *network_name; 00075 uint8_t regulatory_domain; 00076 uint8_t rd_operating_class; 00077 uint8_t rd_operating_mode; 00078 uint8_t uc_channel_function; 00079 uint8_t bc_channel_function; 00080 uint8_t uc_dwell_interval; 00081 uint32_t bc_interval; 00082 uint8_t bc_dwell_interval; 00083 uint16_t uc_fixed_channel; 00084 uint16_t bc_fixed_channel; 00085 } wisun_network_settings_t; 00086 00087 typedef struct { 00088 arm_certificate_entry_s arm_cert_entry; 00089 ns_list_link_t link; /*!< List link entry */ 00090 } wisun_certificate_entry_t; 00091 00092 typedef NS_LIST_HEAD (wisun_certificate_entry_t, link) cert_list_t; 00093 typedef struct { 00094 cert_list_t own_certificates_list; 00095 cert_list_t trusted_certificates_list; 00096 bool remove_own_certificates: 1; 00097 bool remove_trusted_certificates: 1; 00098 } wisun_certificates_t; 00099 00100 #define WS_NA 0xff // Not applicable value 00101 #define WS_DEFAULT 0x00 // Use default value 00102 00103 /* Tasklet data */ 00104 static wisun_tasklet_data_str_t *wisun_tasklet_data_ptr = NULL; 00105 static wisun_certificates_t *wisun_certificates_ptr = NULL; 00106 static wisun_network_settings_t wisun_settings_str = { 00107 .network_name = NULL, 00108 .regulatory_domain = MBED_CONF_MBED_MESH_API_WISUN_REGULATORY_DOMAIN, 00109 .rd_operating_class = MBED_CONF_MBED_MESH_API_WISUN_OPERATING_CLASS, 00110 .rd_operating_mode = MBED_CONF_MBED_MESH_API_WISUN_OPERATING_MODE, 00111 .uc_channel_function = MBED_CONF_MBED_MESH_API_WISUN_UC_CHANNEL_FUNCTION, 00112 .bc_channel_function = MBED_CONF_MBED_MESH_API_WISUN_BC_CHANNEL_FUNCTION, 00113 .uc_dwell_interval = MBED_CONF_MBED_MESH_API_WISUN_UC_DWELL_INTERVAL, 00114 .bc_interval = MBED_CONF_MBED_MESH_API_WISUN_BC_INTERVAL, 00115 .bc_dwell_interval = MBED_CONF_MBED_MESH_API_WISUN_BC_DWELL_INTERVAL, 00116 .uc_fixed_channel = MBED_CONF_MBED_MESH_API_WISUN_UC_FIXED_CHANNEL, 00117 .bc_fixed_channel = MBED_CONF_MBED_MESH_API_WISUN_BC_FIXED_CHANNEL 00118 }; 00119 static mac_api_t *mac_api = NULL; 00120 00121 extern fhss_timer_t fhss_functions; 00122 00123 /* private function prototypes */ 00124 static void wisun_tasklet_main(arm_event_s *event); 00125 static void wisun_tasklet_network_state_changed(mesh_connection_status_t status); 00126 static void wisun_tasklet_parse_network_event(arm_event_s *event); 00127 static void wisun_tasklet_configure_and_connect_to_network(void); 00128 static void wisun_tasklet_clear_stored_certificates(void) ; 00129 static int wisun_tasklet_store_certificate_data(const uint8_t *cert, uint16_t cert_len, const uint8_t *cert_key, uint16_t cert_key_len, bool remove_own, bool remove_trusted, bool trusted_cert); 00130 static int wisun_tasklet_add_stored_certificates(void) ; 00131 00132 /* 00133 * \brief A function which will be eventually called by NanoStack OS when ever the OS has an event to deliver. 00134 * @param event, describes the sender, receiver and event type. 00135 * 00136 * NOTE: Interrupts requested by HW are possible during this function! 00137 */ 00138 static void wisun_tasklet_main(arm_event_s *event) 00139 { 00140 arm_library_event_type_e event_type; 00141 event_type = (arm_library_event_type_e) event->event_type; 00142 00143 switch (event_type) { 00144 case ARM_LIB_NWK_INTERFACE_EVENT: 00145 /* This event is delivered every and each time when there is new 00146 * information of network connectivity. 00147 */ 00148 wisun_tasklet_parse_network_event(event); 00149 break; 00150 00151 case ARM_LIB_TASKLET_INIT_EVENT: 00152 /* Event with type EV_INIT is an initializer event of NanoStack OS. 00153 * The event is delivered when the NanoStack OS is running fine. 00154 * This event should be delivered ONLY ONCE. 00155 */ 00156 mesh_system_send_connect_event(wisun_tasklet_data_ptr->tasklet); 00157 break; 00158 00159 case ARM_LIB_SYSTEM_TIMER_EVENT: 00160 eventOS_event_timer_cancel(event->event_id, wisun_tasklet_data_ptr->tasklet); 00161 00162 if (event->event_id == TIMER_EVENT_START_BOOTSTRAP) { 00163 tr_debug("Restart bootstrap"); 00164 wisun_tasklet_configure_and_connect_to_network(); 00165 } 00166 break; 00167 00168 case APPLICATION_EVENT: 00169 if (event->event_id == APPL_EVENT_CONNECT) { 00170 wisun_tasklet_configure_and_connect_to_network(); 00171 } 00172 break; 00173 00174 default: 00175 break; 00176 } // switch(event_type) 00177 } 00178 00179 /** 00180 * \brief Network state event handler. 00181 * \param event show network start response or current network state. 00182 * 00183 * - ARM_NWK_BOOTSTRAP_READY: Save NVK persistent data to NVM and Net role 00184 * - ARM_NWK_NWK_SCAN_FAIL: Link Layer Active Scan Fail, Stack is Already at Idle state 00185 * - ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL: No WS Router at current Channel Stack is Already at Idle state 00186 * - ARM_NWK_NWK_CONNECTION_DOWN: Connection to Access point is lost wait for Scan Result 00187 * - ARM_NWK_NWK_PARENT_POLL_FAIL: Host should run net start without any PAN-id filter and all channels 00188 * - ARM_NWK_AUHTENTICATION_FAIL: Pana Authentication fail, Stack is Already at Idle state 00189 */ 00190 static void wisun_tasklet_parse_network_event(arm_event_s *event) 00191 { 00192 arm_nwk_interface_status_type_e status = (arm_nwk_interface_status_type_e) event->event_data; 00193 tr_debug("app_parse_network_event() %d", status); 00194 switch (status) { 00195 case ARM_NWK_BOOTSTRAP_READY: 00196 /* Network is ready and node is connected to Access Point */ 00197 if (wisun_tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_READY) { 00198 tr_info("Wi-SUN bootstrap ready"); 00199 wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_READY; 00200 wisun_tasklet_network_state_changed(MESH_CONNECTED); 00201 } 00202 break; 00203 case ARM_NWK_NWK_SCAN_FAIL: 00204 /* Link Layer Active Scan Fail, Stack is Already at Idle state */ 00205 tr_debug("Link Layer Scan Fail: No Beacons"); 00206 wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; 00207 wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_FAILED); 00208 break; 00209 case ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL: 00210 /* No WS Router at current Channel Stack is Already at Idle state */ 00211 tr_debug("WS Scan/ GP REG fail"); 00212 wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; 00213 wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_FAILED); 00214 break; 00215 case ARM_NWK_NWK_CONNECTION_DOWN: 00216 /* Connection to Access point is lost wait for Scan Result */ 00217 tr_debug("WS/RPL scan new network"); 00218 wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED; 00219 wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED); 00220 break; 00221 case ARM_NWK_NWK_PARENT_POLL_FAIL: 00222 wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; 00223 wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_FAILED); 00224 break; 00225 case ARM_NWK_AUHTENTICATION_FAIL: 00226 tr_debug("Network authentication fail"); 00227 wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; 00228 wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_FAILED); 00229 break; 00230 default: 00231 tr_warn("Unknown event %d", status); 00232 break; 00233 } 00234 00235 if ((wisun_tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_READY && 00236 wisun_tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_STARTED) && 00237 wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID) { 00238 // Set 5s timer for new network scan 00239 eventOS_event_timer_request(TIMER_EVENT_START_BOOTSTRAP, 00240 ARM_LIB_SYSTEM_TIMER_EVENT, 00241 wisun_tasklet_data_ptr->tasklet, 00242 5000); 00243 00244 } 00245 } 00246 00247 /* 00248 * \brief Configure and establish network connection 00249 * 00250 */ 00251 static void wisun_tasklet_configure_and_connect_to_network(void) 00252 { 00253 int status; 00254 fhss_timer_t *fhss_timer_ptr = &fhss_functions; 00255 00256 wisun_tasklet_data_ptr->operating_mode = NET_6LOWPAN_ROUTER; 00257 wisun_tasklet_data_ptr->operating_mode_extension = NET_6LOWPAN_WS; 00258 00259 arm_nwk_interface_configure_6lowpan_bootstrap_set( 00260 wisun_tasklet_data_ptr->network_interface_id, 00261 wisun_tasklet_data_ptr->operating_mode, 00262 wisun_tasklet_data_ptr->operating_mode_extension); 00263 00264 if (wisun_tasklet_add_stored_certificates() != 0) { 00265 tr_error("Can't set Wi-SUN certificates"); 00266 return; 00267 } 00268 00269 status = ws_management_node_init(wisun_tasklet_data_ptr->network_interface_id, 00270 MBED_CONF_MBED_MESH_API_WISUN_REGULATORY_DOMAIN, 00271 wisun_settings_str.network_name, 00272 fhss_timer_ptr); 00273 if (status < 0) { 00274 tr_error("Failed to initialize WS"); 00275 return; 00276 } 00277 00278 if (wisun_settings_str.uc_channel_function != WS_NA) { 00279 status = ws_management_fhss_unicast_channel_function_configure(wisun_tasklet_data_ptr->network_interface_id, 00280 wisun_settings_str.uc_channel_function, 00281 wisun_settings_str.uc_fixed_channel, 00282 wisun_settings_str.uc_dwell_interval); 00283 00284 if (status < 0) { 00285 tr_error("Failed to set unicast channel function configuration"); 00286 return; 00287 } 00288 } 00289 00290 if (wisun_settings_str.bc_channel_function != WS_NA || 00291 wisun_settings_str.bc_dwell_interval != WS_DEFAULT || 00292 wisun_settings_str.bc_interval != WS_DEFAULT) { 00293 status = ws_management_fhss_broadcast_channel_function_configure(wisun_tasklet_data_ptr->network_interface_id, 00294 wisun_settings_str.bc_channel_function, 00295 wisun_settings_str.bc_fixed_channel, 00296 wisun_settings_str.bc_dwell_interval, 00297 wisun_settings_str.bc_interval); 00298 00299 if (status < 0) { 00300 tr_error("Failed to set broadcast channel function configuration"); 00301 return; 00302 } 00303 } 00304 00305 if (wisun_settings_str.uc_dwell_interval != WS_DEFAULT || 00306 wisun_settings_str.bc_dwell_interval != WS_DEFAULT || 00307 wisun_settings_str.bc_interval != WS_DEFAULT) { 00308 status = ws_management_fhss_timing_configure(wisun_tasklet_data_ptr->network_interface_id, 00309 wisun_settings_str.uc_dwell_interval, 00310 wisun_settings_str.bc_interval, 00311 wisun_settings_str.bc_dwell_interval); 00312 00313 if (status < 0) { 00314 tr_error("Failed to set fhss configuration"); 00315 return; 00316 } 00317 } 00318 00319 if (wisun_settings_str.regulatory_domain != WS_NA || 00320 wisun_settings_str.rd_operating_class != WS_NA || 00321 wisun_settings_str.rd_operating_mode != WS_NA) { 00322 status = ws_management_regulatory_domain_set(wisun_tasklet_data_ptr->network_interface_id, 00323 wisun_settings_str.regulatory_domain, 00324 wisun_settings_str.rd_operating_class, 00325 wisun_settings_str.rd_operating_mode); 00326 00327 if (status < 0) { 00328 tr_error("Failed to set regulatory domain!"); 00329 return; 00330 } 00331 } 00332 00333 #if defined(MBED_CONF_MBED_MESH_API_CERTIFICATE_HEADER) 00334 arm_certificate_entry_s trusted_cert = { 00335 .cert = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE, 00336 .key = NULL, 00337 .cert_len = 0, 00338 .key_len = 0 00339 }; 00340 #ifdef MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE_LEN 00341 trusted_cert.cert_len = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE_LEN; 00342 #else 00343 trusted_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE) + 1; 00344 #endif 00345 arm_network_trusted_certificate_add((const arm_certificate_entry_s *)&trusted_cert); 00346 00347 arm_certificate_entry_s own_cert = { 00348 .cert = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE, 00349 .key = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY, 00350 .cert_len = 0, 00351 .key_len = 0 00352 }; 00353 #ifdef MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_LEN 00354 own_cert.cert_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_LEN; 00355 #else 00356 own_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE) + 1; 00357 #endif 00358 #ifdef MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY_LEN 00359 own_cert.key_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY_LEN; 00360 #else 00361 own_cert.key_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY) + 1; 00362 #endif 00363 arm_network_own_certificate_add((const arm_certificate_entry_s *)&own_cert); 00364 #endif 00365 00366 status = arm_nwk_interface_up(wisun_tasklet_data_ptr->network_interface_id); 00367 if (status >= 0) { 00368 wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED; 00369 tr_info("Start Wi-SUN Bootstrap"); 00370 wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED); 00371 } else { 00372 wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; 00373 tr_err("Bootstrap start failed, %d", status); 00374 wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_START_FAILED); 00375 } 00376 } 00377 00378 /* 00379 * Inform application about network state change 00380 */ 00381 static void wisun_tasklet_network_state_changed(mesh_connection_status_t status) 00382 { 00383 if (wisun_tasklet_data_ptr->mesh_api_cb) { 00384 (wisun_tasklet_data_ptr->mesh_api_cb)(status); 00385 } 00386 } 00387 00388 static int wisun_tasklet_store_certificate_data(const uint8_t *cert, uint16_t cert_len, const uint8_t *cert_key, uint16_t cert_key_len, bool remove_own, bool remove_trusted, bool trusted_cert) 00389 { 00390 if (wisun_certificates_ptr == NULL) { 00391 wisun_certificates_ptr = (wisun_certificates_t *)ns_dyn_mem_alloc(sizeof(wisun_certificates_t)); 00392 if (!wisun_certificates_ptr) { 00393 return -1; 00394 } 00395 ns_list_init(&wisun_certificates_ptr->own_certificates_list); 00396 ns_list_init(&wisun_certificates_ptr->trusted_certificates_list); 00397 wisun_certificates_ptr->remove_own_certificates = false; 00398 wisun_certificates_ptr->remove_trusted_certificates = false; 00399 } 00400 00401 if (remove_own) { 00402 wisun_certificates_ptr->remove_own_certificates = true; 00403 return 0; 00404 } 00405 00406 if (remove_trusted) { 00407 wisun_certificates_ptr->remove_trusted_certificates = true; 00408 return 0; 00409 } 00410 00411 wisun_certificate_entry_t *ws_cert_entry_store = (wisun_certificate_entry_t *)ns_dyn_mem_alloc(sizeof(wisun_certificate_entry_t)); 00412 if (!ws_cert_entry_store) { 00413 wisun_tasklet_clear_stored_certificates(); 00414 return -1; 00415 } 00416 00417 ws_cert_entry_store->arm_cert_entry.cert = cert; 00418 ws_cert_entry_store->arm_cert_entry.cert_len = cert_len; 00419 00420 if (cert_key) { 00421 ws_cert_entry_store->arm_cert_entry.key = cert_key; 00422 ws_cert_entry_store->arm_cert_entry.key_len = cert_key_len; 00423 } else { 00424 ws_cert_entry_store->arm_cert_entry.key = NULL; 00425 ws_cert_entry_store->arm_cert_entry.key_len = 0; 00426 } 00427 00428 if (trusted_cert) { 00429 ns_list_add_to_end(&wisun_certificates_ptr->trusted_certificates_list, ws_cert_entry_store); 00430 } else { 00431 ns_list_add_to_end(&wisun_certificates_ptr->own_certificates_list, ws_cert_entry_store); 00432 } 00433 00434 return 0; 00435 } 00436 00437 static void wisun_tasklet_clear_stored_certificates(void) 00438 { 00439 if (!wisun_certificates_ptr) { 00440 return; 00441 } 00442 00443 ns_list_foreach_safe(wisun_certificate_entry_t, trusted_cert_entry, &wisun_certificates_ptr->trusted_certificates_list) { 00444 ns_list_remove(&wisun_certificates_ptr->trusted_certificates_list, trusted_cert_entry); 00445 ns_dyn_mem_free(trusted_cert_entry); 00446 } 00447 00448 ns_list_foreach_safe(wisun_certificate_entry_t, own_cert_entry, &wisun_certificates_ptr->own_certificates_list) { 00449 ns_list_remove(&wisun_certificates_ptr->own_certificates_list, own_cert_entry); 00450 ns_dyn_mem_free(own_cert_entry); 00451 } 00452 00453 ns_dyn_mem_free(wisun_certificates_ptr); 00454 wisun_certificates_ptr = NULL; 00455 } 00456 00457 static int wisun_tasklet_add_stored_certificates(void) 00458 { 00459 int8_t status = 0; 00460 00461 if (wisun_certificates_ptr == NULL) { 00462 // certificates not updated 00463 return 0; 00464 } 00465 00466 if (wisun_certificates_ptr->remove_own_certificates) { 00467 status = arm_network_own_certificates_remove(); 00468 if (status != 0) { 00469 goto CERTIFICATE_SET_END; 00470 } 00471 } 00472 00473 if (wisun_certificates_ptr->remove_trusted_certificates) { 00474 status = arm_network_trusted_certificates_remove(); 00475 if (status != 0) { 00476 goto CERTIFICATE_SET_END; 00477 } 00478 } 00479 00480 ns_list_foreach(wisun_certificate_entry_t, cert_entry, &wisun_certificates_ptr->trusted_certificates_list) { 00481 status = arm_network_trusted_certificate_add(&cert_entry->arm_cert_entry); 00482 if (status != 0) { 00483 goto CERTIFICATE_SET_END; 00484 } 00485 } 00486 00487 ns_list_foreach(wisun_certificate_entry_t, cert_entry, &wisun_certificates_ptr->own_certificates_list) { 00488 status = arm_network_own_certificate_add(&cert_entry->arm_cert_entry); 00489 if (status != 0) { 00490 goto CERTIFICATE_SET_END; 00491 } 00492 } 00493 00494 CERTIFICATE_SET_END: 00495 wisun_tasklet_clear_stored_certificates(); 00496 00497 return status; 00498 } 00499 00500 /* Public functions */ 00501 int8_t wisun_tasklet_get_router_ip_address(char *address, int8_t len) 00502 { 00503 network_layer_address_s nd_address; 00504 00505 if ((len >= 40) && (0 == arm_nwk_nd_address_read(wisun_tasklet_data_ptr->network_interface_id, &nd_address))) { 00506 ip6tos(nd_address.border_router, address); 00507 tr_debug("Router IP address: %s", address); 00508 return 0; 00509 } else { 00510 return -1; 00511 } 00512 } 00513 00514 int8_t wisun_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_id) 00515 { 00516 bool re_connecting = true; 00517 int8_t tasklet_id = wisun_tasklet_data_ptr->tasklet; 00518 00519 if (wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID) { 00520 return -3; // already connected to network 00521 } 00522 00523 if (wisun_tasklet_data_ptr->tasklet_state == TASKLET_STATE_CREATED) { 00524 re_connecting = false; 00525 } 00526 00527 memset(wisun_tasklet_data_ptr, 0, sizeof(wisun_tasklet_data_str_t)); 00528 wisun_tasklet_data_ptr->mesh_api_cb = callback; 00529 wisun_tasklet_data_ptr->network_interface_id = nwk_interface_id; 00530 wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_INITIALIZED; 00531 00532 if (re_connecting == false) { 00533 wisun_tasklet_data_ptr->tasklet = eventOS_event_handler_create(&wisun_tasklet_main, 00534 ARM_LIB_TASKLET_INIT_EVENT); 00535 if (wisun_tasklet_data_ptr->tasklet < 0) { 00536 // -1 handler already used by other tasklet 00537 // -2 memory allocation failure 00538 return wisun_tasklet_data_ptr->tasklet; 00539 } 00540 } else { 00541 wisun_tasklet_data_ptr->tasklet = tasklet_id; 00542 mesh_system_send_connect_event(wisun_tasklet_data_ptr->tasklet); 00543 } 00544 00545 return wisun_tasklet_data_ptr->tasklet; 00546 } 00547 00548 int8_t wisun_tasklet_disconnect(bool send_cb) 00549 { 00550 int8_t status = -1; 00551 if (wisun_tasklet_data_ptr != NULL) { 00552 if (wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID) { 00553 status = arm_nwk_interface_down(wisun_tasklet_data_ptr->network_interface_id); 00554 wisun_tasklet_data_ptr->network_interface_id = INVALID_INTERFACE_ID; 00555 if (send_cb == true) { 00556 wisun_tasklet_network_state_changed(MESH_DISCONNECTED); 00557 } 00558 } 00559 wisun_tasklet_data_ptr->mesh_api_cb = NULL; 00560 } 00561 return status; 00562 } 00563 00564 void wisun_tasklet_init(void) 00565 { 00566 if (wisun_tasklet_data_ptr == NULL) { 00567 wisun_tasklet_data_ptr = (wisun_tasklet_data_str_t *)ns_dyn_mem_alloc(sizeof(wisun_tasklet_data_str_t)); 00568 // allocation not validated, in case of failure execution stops here 00569 memset(wisun_tasklet_data_ptr, 0, sizeof(wisun_tasklet_data_str_t)); 00570 wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_CREATED; 00571 wisun_tasklet_data_ptr->network_interface_id = INVALID_INTERFACE_ID; 00572 } 00573 } 00574 00575 int8_t wisun_tasklet_network_init(int8_t device_id) 00576 { 00577 // TODO, read interface name from configuration 00578 mac_description_storage_size_t storage_sizes; 00579 storage_sizes.device_decription_table_size = 32; 00580 storage_sizes.key_description_table_size = 4; 00581 storage_sizes.key_lookup_size = 1; 00582 storage_sizes.key_usage_size = 3; 00583 if (!mac_api) { 00584 mac_api = ns_sw_mac_create(device_id, &storage_sizes); 00585 } 00586 00587 if (!wisun_settings_str.network_name) { 00588 // No network name set by API, use network name from configuration 00589 int wisun_network_name_len = sizeof(MBED_CONF_MBED_MESH_API_WISUN_NETWORK_NAME); 00590 wisun_settings_str.network_name = (char *)ns_dyn_mem_alloc(wisun_network_name_len); 00591 if (!wisun_settings_str.network_name) { 00592 return -3; 00593 } 00594 strncpy(wisun_settings_str.network_name, MBED_CONF_MBED_MESH_API_WISUN_NETWORK_NAME, wisun_network_name_len); 00595 } 00596 00597 return arm_nwk_interface_lowpan_init(mac_api, INTERFACE_NAME); 00598 } 00599 00600 int wisun_tasklet_set_network_name(int8_t nwk_interface_id, char *network_name_ptr) 00601 { 00602 if (!network_name_ptr || strlen(network_name_ptr) > 32) { 00603 return -1; 00604 } 00605 00606 // save the network name to have support for disconnect/connect 00607 ns_dyn_mem_free(wisun_settings_str.network_name); 00608 wisun_settings_str.network_name = (char *)ns_dyn_mem_alloc(strlen(network_name_ptr) + 1); 00609 if (!wisun_settings_str.network_name) { 00610 return -2; 00611 } 00612 00613 strcpy(wisun_settings_str.network_name, network_name_ptr); 00614 00615 if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->tasklet_state == TASKLET_STATE_BOOTSTRAP_READY) { 00616 // interface is up, try to change name dynamically 00617 return ws_management_network_name_set(nwk_interface_id, wisun_settings_str.network_name); 00618 } 00619 00620 return 0; 00621 } 00622 00623 int wisun_tasklet_set_regulatory_domain(int8_t nwk_interface_id, uint8_t regulatory_domain, uint8_t operating_class, uint8_t operating_mode) 00624 { 00625 int status = 0; 00626 00627 wisun_settings_str.regulatory_domain = regulatory_domain; 00628 wisun_settings_str.rd_operating_class = operating_class; 00629 wisun_settings_str.rd_operating_mode = operating_mode; 00630 00631 if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->tasklet_state == TASKLET_STATE_BOOTSTRAP_READY) { 00632 status = ws_management_regulatory_domain_set(nwk_interface_id, regulatory_domain, operating_class, operating_mode); 00633 } 00634 00635 return status; 00636 } 00637 00638 int wisun_tasklet_set_own_certificate(uint8_t *cert, uint16_t cert_len, uint8_t *cert_key, uint16_t cert_key_len) 00639 { 00640 if (wisun_tasklet_data_ptr) { 00641 // this API can be only used before first connect() 00642 tr_err("Already connected"); 00643 return -2; 00644 } 00645 00646 return wisun_tasklet_store_certificate_data(cert, cert_len, cert_key, cert_key_len, false, false, false); 00647 } 00648 00649 int wisun_tasklet_remove_own_certificates(void) 00650 { 00651 if (wisun_tasklet_data_ptr) { 00652 // this API can be only used before first connect() 00653 tr_err("Already connected"); 00654 return -2; 00655 } 00656 00657 return wisun_tasklet_store_certificate_data(NULL, 0, NULL, 0, true, false, false); 00658 } 00659 00660 int wisun_tasklet_remove_trusted_certificates(void) 00661 { 00662 if (wisun_tasklet_data_ptr) { 00663 // this API can be only used before first connect() 00664 tr_err("Already connected"); 00665 return -2; 00666 } 00667 00668 return wisun_tasklet_store_certificate_data(NULL, 0, NULL, 0, false, true, false); 00669 } 00670 00671 int wisun_tasklet_set_trusted_certificate(uint8_t *cert, uint16_t cert_len) 00672 { 00673 if (wisun_tasklet_data_ptr) { 00674 // this API can be only used before first connect() 00675 tr_err("Already connected"); 00676 return -2; 00677 } 00678 return wisun_tasklet_store_certificate_data(cert, cert_len, NULL, 0, false, false, true); 00679 }
Generated on Tue Jul 12 2022 13:55:03 by
