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
ethernet_tasklet.c
00001 /* 00002 * Copyright (c) 2015 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 "net_interface.h" 00021 #include "ip6string.h" //ip6tos 00022 #include "nsdynmemLIB.h" 00023 #include "include/mesh_system.h" 00024 #include "ns_event_loop.h" 00025 #include "mesh_interface_types.h" 00026 #include "eventOS_event.h" 00027 00028 // For tracing we need to define flag, have include and define group 00029 #include "ns_trace.h" 00030 #define TRACE_GROUP "IPV6" 00031 00032 #include "ethernet_mac_api.h" 00033 00034 #define INTERFACE_NAME "eth0" 00035 00036 // Tasklet timer events 00037 #define TIMER_EVENT_START_BOOTSTRAP 1 00038 00039 #define INVALID_INTERFACE_ID (-1) 00040 00041 #define STR_HELPER(x) #x 00042 #define STR(x) STR_HELPER(x) 00043 00044 /* 00045 * Mesh tasklet states. 00046 */ 00047 typedef enum { 00048 TASKLET_STATE_CREATED = 0, 00049 TASKLET_STATE_INITIALIZED, 00050 TASKLET_STATE_BOOTSTRAP_STARTED, 00051 TASKLET_STATE_BOOTSTRAP_FAILED, 00052 TASKLET_STATE_BOOTSTRAP_READY 00053 } tasklet_state_t; 00054 00055 /* 00056 * Mesh tasklet data structure. 00057 */ 00058 typedef struct { 00059 void (*mesh_api_cb)(mesh_connection_status_t nwk_status); 00060 tasklet_state_t tasklet_state; 00061 mesh_connection_status_t connection_status; 00062 timeout_t *poll_network_status_timeout; 00063 int8_t node_main_tasklet_id; 00064 int8_t network_interface_id; 00065 int8_t tasklet; 00066 uint8_t ip[16]; 00067 } tasklet_data_str_t; 00068 00069 /* Tasklet data */ 00070 static tasklet_data_str_t *tasklet_data_ptr = NULL; 00071 static eth_mac_api_t *eth_mac_api = NULL; 00072 typedef void (*mesh_interface_cb)(mesh_connection_status_t mesh_status); 00073 00074 00075 /* private function prototypes */ 00076 static void enet_tasklet_main(arm_event_s *event); 00077 static void enet_tasklet_network_state_changed(mesh_connection_status_t status); 00078 static void enet_tasklet_parse_network_event(arm_event_s *event); 00079 static void enet_tasklet_configure_and_connect_to_network(void); 00080 static void enet_tasklet_poll_network_status(void *param); 00081 /* 00082 * \brief A function which will be eventually called by NanoStack OS when ever the OS has an event to deliver. 00083 * @param event, describes the sender, receiver and event type. 00084 * 00085 * NOTE: Interrupts requested by HW are possible during this function! 00086 */ 00087 void enet_tasklet_main(arm_event_s *event) 00088 { 00089 arm_library_event_type_e event_type; 00090 event_type = (arm_library_event_type_e) event->event_type; 00091 00092 switch (event_type) { 00093 case ARM_LIB_NWK_INTERFACE_EVENT: 00094 /* This event is delivered every and each time when there is new 00095 * information of network connectivity. 00096 */ 00097 enet_tasklet_parse_network_event(event); 00098 break; 00099 00100 case ARM_LIB_TASKLET_INIT_EVENT: 00101 /* Event with type EV_INIT is an initializer event of NanoStack OS. 00102 * The event is delivered when the NanoStack OS is running fine. 00103 * This event should be delivered ONLY ONCE. 00104 */ 00105 tasklet_data_ptr->node_main_tasklet_id = event->receiver; 00106 mesh_system_send_connect_event(tasklet_data_ptr->tasklet); 00107 break; 00108 00109 case ARM_LIB_SYSTEM_TIMER_EVENT: 00110 eventOS_event_timer_cancel(event->event_id, 00111 tasklet_data_ptr->node_main_tasklet_id); 00112 00113 if (event->event_id == TIMER_EVENT_START_BOOTSTRAP) { 00114 tr_debug("Restart bootstrap"); 00115 enet_tasklet_configure_and_connect_to_network(); 00116 } 00117 break; 00118 00119 case APPLICATION_EVENT: 00120 if (event->event_id == APPL_EVENT_CONNECT) { 00121 enet_tasklet_configure_and_connect_to_network(); 00122 } 00123 break; 00124 00125 default: 00126 break; 00127 } // switch(event_type) 00128 } 00129 00130 /** 00131 * \brief Network state event handler. 00132 * \param event show network start response or current network state. 00133 * 00134 * - ARM_NWK_BOOTSTRAP_READY: Save NVK persistent data to NVM and Net role 00135 * - ARM_NWK_NWK_SCAN_FAIL: Link Layer Active Scan Fail, Stack is Already at Idle state 00136 * - ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL: No ND Router at current Channel Stack is Already at Idle state 00137 * - ARM_NWK_NWK_CONNECTION_DOWN: Connection to Access point is lost wait for Scan Result 00138 * - ARM_NWK_NWK_PARENT_POLL_FAIL: Host should run net start without any PAN-id filter and all channels 00139 * - ARM_NWK_AUHTENTICATION_FAIL: Pana Authentication fail, Stack is Already at Idle state 00140 */ 00141 void enet_tasklet_parse_network_event(arm_event_s *event) 00142 { 00143 arm_nwk_interface_status_type_e status = (arm_nwk_interface_status_type_e) event->event_data; 00144 tr_debug("app_parse_network_event() %d", status); 00145 switch (status) { 00146 case ARM_NWK_BOOTSTRAP_READY: 00147 /* Network is ready and node is connected to Access Point */ 00148 if (tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_READY) { 00149 tr_info("IPv6 bootstrap ready"); 00150 tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_READY; 00151 enet_tasklet_poll_network_status(NULL); 00152 } 00153 break; 00154 case ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL: 00155 /* No ND Router at current Channel Stack is Already at Idle state */ 00156 tr_info("Bootstrap fail"); 00157 tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; 00158 enet_tasklet_network_state_changed(MESH_DISCONNECTED); 00159 break; 00160 case ARM_NWK_NWK_CONNECTION_DOWN: 00161 /* Connection to Access point is lost wait for Scan Result */ 00162 tr_info("Connection lost"); 00163 tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; 00164 enet_tasklet_network_state_changed(MESH_DISCONNECTED); 00165 break; 00166 default: 00167 tr_warn("Unknown event %d", status); 00168 break; 00169 } 00170 00171 if (tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_READY) { 00172 // Set 5s timer for new network scan 00173 eventOS_event_timer_request(TIMER_EVENT_START_BOOTSTRAP, 00174 ARM_LIB_SYSTEM_TIMER_EVENT, 00175 tasklet_data_ptr->node_main_tasklet_id, 00176 5000); 00177 } 00178 } 00179 00180 static void enet_tasklet_poll_network_status(void *param) 00181 { 00182 /* Check if we do have an IP */ 00183 uint8_t temp_ipv6[16]; 00184 if (arm_net_address_get(tasklet_data_ptr->network_interface_id, ADDR_IPV6_GP, temp_ipv6) == 0) { 00185 /* Check if this is link local address or not */ 00186 if (memcmp(temp_ipv6, tasklet_data_ptr->ip, 16) == 0) { 00187 return; 00188 } else { 00189 memcpy(tasklet_data_ptr->ip, temp_ipv6, 16); 00190 uint8_t temp_ipv6_local[16]; 00191 if (arm_net_address_get(tasklet_data_ptr->network_interface_id, ADDR_IPV6_LL, temp_ipv6_local) == 0 00192 && (memcmp(temp_ipv6, temp_ipv6_local, 16) != 0)) { 00193 enet_tasklet_network_state_changed(MESH_CONNECTED_GLOBAL); 00194 } else { 00195 enet_tasklet_network_state_changed(MESH_CONNECTED_LOCAL);; 00196 } 00197 } 00198 } else { 00199 if (tasklet_data_ptr->connection_status != MESH_DISCONNECTED && 00200 tasklet_data_ptr->connection_status != MESH_BOOTSTRAP_STARTED) 00201 enet_tasklet_network_state_changed(MESH_DISCONNECTED); 00202 } 00203 } 00204 00205 /* 00206 * \brief Configure and establish network connection 00207 * 00208 */ 00209 void enet_tasklet_configure_and_connect_to_network(void) 00210 { 00211 arm_nwk_interface_up(tasklet_data_ptr->network_interface_id); 00212 enet_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED); 00213 } 00214 00215 /* 00216 * Inform application about network state change 00217 */ 00218 void enet_tasklet_network_state_changed(mesh_connection_status_t status) 00219 { 00220 tasklet_data_ptr->connection_status = status; 00221 if (tasklet_data_ptr->mesh_api_cb) { 00222 (tasklet_data_ptr->mesh_api_cb)(status); 00223 } 00224 } 00225 00226 /* Public functions */ 00227 int8_t enet_tasklet_get_ip_address(char *address, int8_t len) 00228 { 00229 uint8_t binary_ipv6[16]; 00230 00231 if ((len >= 40) && (0 == arm_net_address_get( 00232 tasklet_data_ptr->network_interface_id, ADDR_IPV6_GP, binary_ipv6))) { 00233 ip6tos(binary_ipv6, address); 00234 //tr_debug("IP address: %s", address); 00235 return 0; 00236 } else { 00237 return -1; 00238 } 00239 } 00240 00241 int8_t enet_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_id) 00242 { 00243 int8_t re_connecting = true; 00244 int8_t tasklet_id = tasklet_data_ptr->tasklet; 00245 00246 if (tasklet_data_ptr->tasklet_state == TASKLET_STATE_CREATED) { 00247 re_connecting = false; 00248 } 00249 00250 memset(tasklet_data_ptr, 0, sizeof(tasklet_data_str_t)); 00251 tasklet_data_ptr->mesh_api_cb = callback; 00252 tasklet_data_ptr->network_interface_id = nwk_interface_id; 00253 tasklet_data_ptr->tasklet_state = TASKLET_STATE_INITIALIZED; 00254 tasklet_data_ptr->poll_network_status_timeout = 00255 eventOS_timeout_every_ms(enet_tasklet_poll_network_status, 2000, NULL); 00256 00257 if (re_connecting == false) { 00258 tasklet_data_ptr->tasklet = eventOS_event_handler_create(&enet_tasklet_main, 00259 ARM_LIB_TASKLET_INIT_EVENT); 00260 if (tasklet_data_ptr->tasklet < 0) { 00261 // -1 handler already used by other tasklet 00262 // -2 memory allocation failure 00263 return tasklet_data_ptr->tasklet; 00264 } 00265 } else { 00266 tasklet_data_ptr->tasklet = tasklet_id; 00267 mesh_system_send_connect_event(tasklet_data_ptr->tasklet); 00268 } 00269 00270 return 0; 00271 } 00272 00273 int8_t enet_tasklet_disconnect(bool send_cb) 00274 { 00275 int8_t status = -1; 00276 if (tasklet_data_ptr != NULL) { 00277 if (tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID) { 00278 status = arm_nwk_interface_down(tasklet_data_ptr->network_interface_id); 00279 tasklet_data_ptr->network_interface_id = INVALID_INTERFACE_ID; 00280 if (send_cb == true) { 00281 enet_tasklet_network_state_changed(MESH_DISCONNECTED); 00282 } 00283 } 00284 tasklet_data_ptr->mesh_api_cb = NULL; 00285 eventOS_timeout_cancel(tasklet_data_ptr->poll_network_status_timeout); 00286 } 00287 return status; 00288 } 00289 00290 void enet_tasklet_init(void) 00291 { 00292 if (tasklet_data_ptr == NULL) { 00293 tasklet_data_ptr = ns_dyn_mem_alloc(sizeof(tasklet_data_str_t)); 00294 tasklet_data_ptr->tasklet_state = TASKLET_STATE_CREATED; 00295 tasklet_data_ptr->network_interface_id = INVALID_INTERFACE_ID; 00296 } 00297 } 00298 00299 int8_t enet_tasklet_network_init(int8_t device_id) 00300 { 00301 if (tasklet_data_ptr->network_interface_id != -1) { 00302 tr_debug("Interface already at active state\n"); 00303 return tasklet_data_ptr->network_interface_id; 00304 } 00305 if (!eth_mac_api) { 00306 eth_mac_api = ethernet_mac_create(device_id); 00307 } 00308 00309 tasklet_data_ptr->network_interface_id = arm_nwk_interface_ethernet_init(eth_mac_api, "eth0"); 00310 00311 tr_debug("interface ID: %d", tasklet_data_ptr->network_interface_id); 00312 arm_nwk_interface_configure_ipv6_bootstrap_set( 00313 tasklet_data_ptr->network_interface_id, NET_IPV6_BOOTSTRAP_AUTONOMOUS, NULL); 00314 return tasklet_data_ptr->network_interface_id; 00315 }
Generated on Fri Jul 22 2022 04:53:48 by
 1.7.2
 1.7.2 
    