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: mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510
features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/thread_tasklet.c@0:098463de4c5d, 2017-01-25 (annotated)
- Committer:
- group-onsemi
- Date:
- Wed Jan 25 20:34:15 2017 +0000
- Revision:
- 0:098463de4c5d
Initial commit
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| group-onsemi | 0:098463de4c5d | 1 | /* |
| group-onsemi | 0:098463de4c5d | 2 | * Copyright (c) 2015 ARM Limited. All rights reserved. |
| group-onsemi | 0:098463de4c5d | 3 | * SPDX-License-Identifier: Apache-2.0 |
| group-onsemi | 0:098463de4c5d | 4 | * Licensed under the Apache License, Version 2.0 (the License); you may |
| group-onsemi | 0:098463de4c5d | 5 | * not use this file except in compliance with the License. |
| group-onsemi | 0:098463de4c5d | 6 | * You may obtain a copy of the License at |
| group-onsemi | 0:098463de4c5d | 7 | * |
| group-onsemi | 0:098463de4c5d | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| group-onsemi | 0:098463de4c5d | 9 | * |
| group-onsemi | 0:098463de4c5d | 10 | * Unless required by applicable law or agreed to in writing, software |
| group-onsemi | 0:098463de4c5d | 11 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT |
| group-onsemi | 0:098463de4c5d | 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| group-onsemi | 0:098463de4c5d | 13 | * See the License for the specific language governing permissions and |
| group-onsemi | 0:098463de4c5d | 14 | * limitations under the License. |
| group-onsemi | 0:098463de4c5d | 15 | */ |
| group-onsemi | 0:098463de4c5d | 16 | |
| group-onsemi | 0:098463de4c5d | 17 | #include <string.h> //memset |
| group-onsemi | 0:098463de4c5d | 18 | #include "eventOS_event_timer.h" |
| group-onsemi | 0:098463de4c5d | 19 | #include "common_functions.h" |
| group-onsemi | 0:098463de4c5d | 20 | #include "net_interface.h" |
| group-onsemi | 0:098463de4c5d | 21 | #include "ip6string.h" //ip6tos |
| group-onsemi | 0:098463de4c5d | 22 | #include "nsdynmemLIB.h" |
| group-onsemi | 0:098463de4c5d | 23 | #include "thread_management_if.h" |
| group-onsemi | 0:098463de4c5d | 24 | #include "net_polling_api.h" |
| group-onsemi | 0:098463de4c5d | 25 | #include "include/thread_tasklet.h" |
| group-onsemi | 0:098463de4c5d | 26 | #include "include/static_config.h" |
| group-onsemi | 0:098463de4c5d | 27 | #include "include/mesh_system.h" |
| group-onsemi | 0:098463de4c5d | 28 | #include "ns_event_loop.h" |
| group-onsemi | 0:098463de4c5d | 29 | |
| group-onsemi | 0:098463de4c5d | 30 | // For tracing we need to define flag, have include and define group |
| group-onsemi | 0:098463de4c5d | 31 | #define HAVE_DEBUG 1 |
| group-onsemi | 0:098463de4c5d | 32 | #include "ns_trace.h" |
| group-onsemi | 0:098463de4c5d | 33 | #define TRACE_GROUP "m6Thread" |
| group-onsemi | 0:098463de4c5d | 34 | |
| group-onsemi | 0:098463de4c5d | 35 | #include "mac_api.h" |
| group-onsemi | 0:098463de4c5d | 36 | #include "sw_mac.h" |
| group-onsemi | 0:098463de4c5d | 37 | |
| group-onsemi | 0:098463de4c5d | 38 | #define DETAILED_TRACES |
| group-onsemi | 0:098463de4c5d | 39 | #ifdef DETAILED_TRACES |
| group-onsemi | 0:098463de4c5d | 40 | #define TRACE_DETAIL tr_debug |
| group-onsemi | 0:098463de4c5d | 41 | #else |
| group-onsemi | 0:098463de4c5d | 42 | #define TRACE_DETAIL(...) |
| group-onsemi | 0:098463de4c5d | 43 | #endif |
| group-onsemi | 0:098463de4c5d | 44 | |
| group-onsemi | 0:098463de4c5d | 45 | #define INTERFACE_NAME "6L-THREAD" |
| group-onsemi | 0:098463de4c5d | 46 | |
| group-onsemi | 0:098463de4c5d | 47 | // Tasklet timer events |
| group-onsemi | 0:098463de4c5d | 48 | #define TIMER_EVENT_START_BOOTSTRAP 1 |
| group-onsemi | 0:098463de4c5d | 49 | |
| group-onsemi | 0:098463de4c5d | 50 | #define INVALID_INTERFACE_ID (-1) |
| group-onsemi | 0:098463de4c5d | 51 | |
| group-onsemi | 0:098463de4c5d | 52 | /* |
| group-onsemi | 0:098463de4c5d | 53 | * Thread tasklet states. |
| group-onsemi | 0:098463de4c5d | 54 | */ |
| group-onsemi | 0:098463de4c5d | 55 | typedef enum { |
| group-onsemi | 0:098463de4c5d | 56 | TASKLET_STATE_CREATED = 0, |
| group-onsemi | 0:098463de4c5d | 57 | TASKLET_STATE_INITIALIZED, |
| group-onsemi | 0:098463de4c5d | 58 | TASKLET_STATE_BOOTSTRAP_STARTED, |
| group-onsemi | 0:098463de4c5d | 59 | TASKLET_STATE_BOOTSTRAP_FAILED, |
| group-onsemi | 0:098463de4c5d | 60 | TASKLET_STATE_BOOTSTRAP_READY |
| group-onsemi | 0:098463de4c5d | 61 | } tasklet_state_t; |
| group-onsemi | 0:098463de4c5d | 62 | |
| group-onsemi | 0:098463de4c5d | 63 | /* |
| group-onsemi | 0:098463de4c5d | 64 | * Mesh tasklet data structure. |
| group-onsemi | 0:098463de4c5d | 65 | */ |
| group-onsemi | 0:098463de4c5d | 66 | typedef struct { |
| group-onsemi | 0:098463de4c5d | 67 | void (*mesh_api_cb)(mesh_connection_status_t nwk_status); |
| group-onsemi | 0:098463de4c5d | 68 | channel_list_s channel_list; |
| group-onsemi | 0:098463de4c5d | 69 | tasklet_state_t tasklet_state; |
| group-onsemi | 0:098463de4c5d | 70 | int8_t tasklet; |
| group-onsemi | 0:098463de4c5d | 71 | |
| group-onsemi | 0:098463de4c5d | 72 | net_6lowpan_mode_e operating_mode; |
| group-onsemi | 0:098463de4c5d | 73 | int8_t nwk_if_id; |
| group-onsemi | 0:098463de4c5d | 74 | link_configuration_s link_config; |
| group-onsemi | 0:098463de4c5d | 75 | |
| group-onsemi | 0:098463de4c5d | 76 | /** Default network ID*/ |
| group-onsemi | 0:098463de4c5d | 77 | uint8_t networkid[16]; |
| group-onsemi | 0:098463de4c5d | 78 | uint8_t extented_panid[8]; |
| group-onsemi | 0:098463de4c5d | 79 | uint32_t pan_id; |
| group-onsemi | 0:098463de4c5d | 80 | uint32_t rfChannel; |
| group-onsemi | 0:098463de4c5d | 81 | uint8_t scan_time; |
| group-onsemi | 0:098463de4c5d | 82 | net_6lowpan_gp_address_mode_e address_mode; |
| group-onsemi | 0:098463de4c5d | 83 | } thread_tasklet_data_str_t; |
| group-onsemi | 0:098463de4c5d | 84 | |
| group-onsemi | 0:098463de4c5d | 85 | |
| group-onsemi | 0:098463de4c5d | 86 | /* Tasklet data */ |
| group-onsemi | 0:098463de4c5d | 87 | static thread_tasklet_data_str_t *thread_tasklet_data_ptr = NULL; |
| group-onsemi | 0:098463de4c5d | 88 | static device_configuration_s device_configuration; |
| group-onsemi | 0:098463de4c5d | 89 | |
| group-onsemi | 0:098463de4c5d | 90 | /* private function prototypes */ |
| group-onsemi | 0:098463de4c5d | 91 | void thread_tasklet_main(arm_event_s *event); |
| group-onsemi | 0:098463de4c5d | 92 | void thread_tasklet_network_state_changed(mesh_connection_status_t status); |
| group-onsemi | 0:098463de4c5d | 93 | void thread_tasklet_parse_network_event(arm_event_s *event); |
| group-onsemi | 0:098463de4c5d | 94 | void thread_tasklet_configure_and_connect_to_network(void); |
| group-onsemi | 0:098463de4c5d | 95 | #define TRACE_THREAD_TASKLET |
| group-onsemi | 0:098463de4c5d | 96 | #ifndef TRACE_THREAD_TASKLET |
| group-onsemi | 0:098463de4c5d | 97 | #define thread_tasklet_trace_bootstrap_info() ((void) 0) |
| group-onsemi | 0:098463de4c5d | 98 | #else |
| group-onsemi | 0:098463de4c5d | 99 | void thread_tasklet_trace_bootstrap_info(void); |
| group-onsemi | 0:098463de4c5d | 100 | #endif |
| group-onsemi | 0:098463de4c5d | 101 | |
| group-onsemi | 0:098463de4c5d | 102 | /* |
| group-onsemi | 0:098463de4c5d | 103 | * \brief A function which will be eventually called by NanoStack OS when ever the OS has an event to deliver. |
| group-onsemi | 0:098463de4c5d | 104 | * @param event, describes the sender, receiver and event type. |
| group-onsemi | 0:098463de4c5d | 105 | * |
| group-onsemi | 0:098463de4c5d | 106 | * NOTE: Interrupts requested by HW are possible during this function! |
| group-onsemi | 0:098463de4c5d | 107 | */ |
| group-onsemi | 0:098463de4c5d | 108 | void thread_tasklet_main(arm_event_s *event) |
| group-onsemi | 0:098463de4c5d | 109 | { |
| group-onsemi | 0:098463de4c5d | 110 | arm_library_event_type_e event_type; |
| group-onsemi | 0:098463de4c5d | 111 | event_type = (arm_library_event_type_e) event->event_type; |
| group-onsemi | 0:098463de4c5d | 112 | |
| group-onsemi | 0:098463de4c5d | 113 | switch (event_type) { |
| group-onsemi | 0:098463de4c5d | 114 | case ARM_LIB_NWK_INTERFACE_EVENT: |
| group-onsemi | 0:098463de4c5d | 115 | /* This event is delivered every and each time when there is new |
| group-onsemi | 0:098463de4c5d | 116 | * information of network connectivity. |
| group-onsemi | 0:098463de4c5d | 117 | */ |
| group-onsemi | 0:098463de4c5d | 118 | thread_tasklet_parse_network_event(event); |
| group-onsemi | 0:098463de4c5d | 119 | break; |
| group-onsemi | 0:098463de4c5d | 120 | |
| group-onsemi | 0:098463de4c5d | 121 | case ARM_LIB_TASKLET_INIT_EVENT: |
| group-onsemi | 0:098463de4c5d | 122 | /* Event with type EV_INIT is an initializer event of NanoStack OS. |
| group-onsemi | 0:098463de4c5d | 123 | * The event is delivered when the NanoStack OS is running fine. |
| group-onsemi | 0:098463de4c5d | 124 | * This event should be delivered ONLY ONCE. |
| group-onsemi | 0:098463de4c5d | 125 | */ |
| group-onsemi | 0:098463de4c5d | 126 | mesh_system_send_connect_event(thread_tasklet_data_ptr->tasklet); |
| group-onsemi | 0:098463de4c5d | 127 | break; |
| group-onsemi | 0:098463de4c5d | 128 | |
| group-onsemi | 0:098463de4c5d | 129 | case ARM_LIB_SYSTEM_TIMER_EVENT: |
| group-onsemi | 0:098463de4c5d | 130 | eventOS_event_timer_cancel(event->event_id, |
| group-onsemi | 0:098463de4c5d | 131 | thread_tasklet_data_ptr->tasklet); |
| group-onsemi | 0:098463de4c5d | 132 | |
| group-onsemi | 0:098463de4c5d | 133 | if (event->event_id == TIMER_EVENT_START_BOOTSTRAP) { |
| group-onsemi | 0:098463de4c5d | 134 | tr_debug("Restart bootstrap"); |
| group-onsemi | 0:098463de4c5d | 135 | arm_nwk_interface_up(thread_tasklet_data_ptr->nwk_if_id); |
| group-onsemi | 0:098463de4c5d | 136 | } |
| group-onsemi | 0:098463de4c5d | 137 | break; |
| group-onsemi | 0:098463de4c5d | 138 | |
| group-onsemi | 0:098463de4c5d | 139 | case APPLICATION_EVENT: |
| group-onsemi | 0:098463de4c5d | 140 | if (event->event_id == APPL_EVENT_CONNECT) { |
| group-onsemi | 0:098463de4c5d | 141 | thread_tasklet_configure_and_connect_to_network(); |
| group-onsemi | 0:098463de4c5d | 142 | } |
| group-onsemi | 0:098463de4c5d | 143 | break; |
| group-onsemi | 0:098463de4c5d | 144 | |
| group-onsemi | 0:098463de4c5d | 145 | default: |
| group-onsemi | 0:098463de4c5d | 146 | break; |
| group-onsemi | 0:098463de4c5d | 147 | } // switch(event_type) |
| group-onsemi | 0:098463de4c5d | 148 | } |
| group-onsemi | 0:098463de4c5d | 149 | |
| group-onsemi | 0:098463de4c5d | 150 | /** |
| group-onsemi | 0:098463de4c5d | 151 | * \brief Network state event handler. |
| group-onsemi | 0:098463de4c5d | 152 | * \param event show network start response or current network state. |
| group-onsemi | 0:098463de4c5d | 153 | * |
| group-onsemi | 0:098463de4c5d | 154 | * - ARM_NWK_BOOTSTRAP_READY: Save NVK persistent data to NVM and Net role |
| group-onsemi | 0:098463de4c5d | 155 | * - ARM_NWK_NWK_SCAN_FAIL: Link Layer Active Scan Fail, Stack is Already at Idle state |
| group-onsemi | 0:098463de4c5d | 156 | * - ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL: No ND Router at current Channel Stack is Already at Idle state |
| group-onsemi | 0:098463de4c5d | 157 | * - ARM_NWK_NWK_CONNECTION_DOWN: Connection to Access point is lost wait for Scan Result |
| group-onsemi | 0:098463de4c5d | 158 | * - ARM_NWK_NWK_PARENT_POLL_FAIL: Host should run net start without any PAN-id filter and all channels |
| group-onsemi | 0:098463de4c5d | 159 | * - ARM_NWK_AUHTENTICATION_FAIL: Pana Authentication fail, Stack is Already at Idle state |
| group-onsemi | 0:098463de4c5d | 160 | */ |
| group-onsemi | 0:098463de4c5d | 161 | void thread_tasklet_parse_network_event(arm_event_s *event) |
| group-onsemi | 0:098463de4c5d | 162 | { |
| group-onsemi | 0:098463de4c5d | 163 | arm_nwk_interface_status_type_e status = (arm_nwk_interface_status_type_e) event->event_data; |
| group-onsemi | 0:098463de4c5d | 164 | tr_debug("app_parse_network_event() %d", status); |
| group-onsemi | 0:098463de4c5d | 165 | switch (status) { |
| group-onsemi | 0:098463de4c5d | 166 | case ARM_NWK_BOOTSTRAP_READY: |
| group-onsemi | 0:098463de4c5d | 167 | /* Network is ready and node is connected to Access Point */ |
| group-onsemi | 0:098463de4c5d | 168 | if (thread_tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_READY) { |
| group-onsemi | 0:098463de4c5d | 169 | tr_info("Thread bootstrap ready"); |
| group-onsemi | 0:098463de4c5d | 170 | thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_READY; |
| group-onsemi | 0:098463de4c5d | 171 | thread_tasklet_trace_bootstrap_info(); |
| group-onsemi | 0:098463de4c5d | 172 | thread_tasklet_network_state_changed(MESH_CONNECTED); |
| group-onsemi | 0:098463de4c5d | 173 | } |
| group-onsemi | 0:098463de4c5d | 174 | break; |
| group-onsemi | 0:098463de4c5d | 175 | case ARM_NWK_NWK_SCAN_FAIL: |
| group-onsemi | 0:098463de4c5d | 176 | /* Link Layer Active Scan Fail, Stack is Already at Idle state */ |
| group-onsemi | 0:098463de4c5d | 177 | tr_debug("Link Layer Scan Fail: No Beacons"); |
| group-onsemi | 0:098463de4c5d | 178 | thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; |
| group-onsemi | 0:098463de4c5d | 179 | break; |
| group-onsemi | 0:098463de4c5d | 180 | case ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL: |
| group-onsemi | 0:098463de4c5d | 181 | /* No ND Router at current Channel Stack is Already at Idle state */ |
| group-onsemi | 0:098463de4c5d | 182 | tr_debug("ND Scan/ GP REG fail"); |
| group-onsemi | 0:098463de4c5d | 183 | thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; |
| group-onsemi | 0:098463de4c5d | 184 | break; |
| group-onsemi | 0:098463de4c5d | 185 | case ARM_NWK_NWK_CONNECTION_DOWN: |
| group-onsemi | 0:098463de4c5d | 186 | /* Connection to Access point is lost wait for Scan Result */ |
| group-onsemi | 0:098463de4c5d | 187 | tr_debug("ND/RPL scan new network"); |
| group-onsemi | 0:098463de4c5d | 188 | thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; |
| group-onsemi | 0:098463de4c5d | 189 | break; |
| group-onsemi | 0:098463de4c5d | 190 | case ARM_NWK_NWK_PARENT_POLL_FAIL: |
| group-onsemi | 0:098463de4c5d | 191 | thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; |
| group-onsemi | 0:098463de4c5d | 192 | break; |
| group-onsemi | 0:098463de4c5d | 193 | case ARM_NWK_AUHTENTICATION_FAIL: |
| group-onsemi | 0:098463de4c5d | 194 | tr_debug("Network authentication fail"); |
| group-onsemi | 0:098463de4c5d | 195 | thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; |
| group-onsemi | 0:098463de4c5d | 196 | break; |
| group-onsemi | 0:098463de4c5d | 197 | default: |
| group-onsemi | 0:098463de4c5d | 198 | tr_warn("Unknown event %d", status); |
| group-onsemi | 0:098463de4c5d | 199 | break; |
| group-onsemi | 0:098463de4c5d | 200 | } |
| group-onsemi | 0:098463de4c5d | 201 | |
| group-onsemi | 0:098463de4c5d | 202 | if (thread_tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_READY) { |
| group-onsemi | 0:098463de4c5d | 203 | // Set 5s timer for a new network scan |
| group-onsemi | 0:098463de4c5d | 204 | eventOS_event_timer_request(TIMER_EVENT_START_BOOTSTRAP, |
| group-onsemi | 0:098463de4c5d | 205 | ARM_LIB_SYSTEM_TIMER_EVENT, |
| group-onsemi | 0:098463de4c5d | 206 | thread_tasklet_data_ptr->tasklet, |
| group-onsemi | 0:098463de4c5d | 207 | 5000); |
| group-onsemi | 0:098463de4c5d | 208 | } |
| group-onsemi | 0:098463de4c5d | 209 | } |
| group-onsemi | 0:098463de4c5d | 210 | |
| group-onsemi | 0:098463de4c5d | 211 | /* |
| group-onsemi | 0:098463de4c5d | 212 | * \brief Configure mesh network |
| group-onsemi | 0:098463de4c5d | 213 | * |
| group-onsemi | 0:098463de4c5d | 214 | */ |
| group-onsemi | 0:098463de4c5d | 215 | void thread_tasklet_configure_and_connect_to_network(void) |
| group-onsemi | 0:098463de4c5d | 216 | { |
| group-onsemi | 0:098463de4c5d | 217 | int8_t status; |
| group-onsemi | 0:098463de4c5d | 218 | |
| group-onsemi | 0:098463de4c5d | 219 | if (MBED_MESH_API_THREAD_DEVICE_TYPE == MESH_DEVICE_TYPE_THREAD_SLEEPY_END_DEVICE) { |
| group-onsemi | 0:098463de4c5d | 220 | thread_tasklet_data_ptr->operating_mode = NET_6LOWPAN_SLEEPY_HOST; |
| group-onsemi | 0:098463de4c5d | 221 | } else { |
| group-onsemi | 0:098463de4c5d | 222 | thread_tasklet_data_ptr->operating_mode = NET_6LOWPAN_ROUTER; |
| group-onsemi | 0:098463de4c5d | 223 | } |
| group-onsemi | 0:098463de4c5d | 224 | |
| group-onsemi | 0:098463de4c5d | 225 | arm_nwk_interface_configure_6lowpan_bootstrap_set( |
| group-onsemi | 0:098463de4c5d | 226 | thread_tasklet_data_ptr->nwk_if_id, |
| group-onsemi | 0:098463de4c5d | 227 | thread_tasklet_data_ptr->operating_mode, |
| group-onsemi | 0:098463de4c5d | 228 | NET_6LOWPAN_THREAD); |
| group-onsemi | 0:098463de4c5d | 229 | |
| group-onsemi | 0:098463de4c5d | 230 | // Link configuration |
| group-onsemi | 0:098463de4c5d | 231 | memcpy(thread_tasklet_data_ptr->link_config.name, "Arm Powered Core", 16); |
| group-onsemi | 0:098463de4c5d | 232 | |
| group-onsemi | 0:098463de4c5d | 233 | thread_tasklet_data_ptr->link_config.panId = MBED_MESH_API_THREAD_CONFIG_PANID; |
| group-onsemi | 0:098463de4c5d | 234 | TRACE_DETAIL("PANID %x", thread_tasklet_data_ptr->link_config.panId); |
| group-onsemi | 0:098463de4c5d | 235 | |
| group-onsemi | 0:098463de4c5d | 236 | // channel |
| group-onsemi | 0:098463de4c5d | 237 | if (MBED_MESH_API_THREAD_CONFIG_CHANNEL > 27) { |
| group-onsemi | 0:098463de4c5d | 238 | tr_error("Bad channel %d", MBED_MESH_API_THREAD_CONFIG_CHANNEL); |
| group-onsemi | 0:098463de4c5d | 239 | return; |
| group-onsemi | 0:098463de4c5d | 240 | } |
| group-onsemi | 0:098463de4c5d | 241 | |
| group-onsemi | 0:098463de4c5d | 242 | thread_tasklet_data_ptr->link_config.rfChannel = MBED_MESH_API_THREAD_CONFIG_CHANNEL; |
| group-onsemi | 0:098463de4c5d | 243 | thread_tasklet_data_ptr->channel_list.channel_page = (channel_page_e)MBED_MESH_API_THREAD_CONFIG_CHANNEL_PAGE; |
| group-onsemi | 0:098463de4c5d | 244 | thread_tasklet_data_ptr->channel_list.channel_mask[0] = MBED_MESH_API_THREAD_CONFIG_CHANNEL_MASK; |
| group-onsemi | 0:098463de4c5d | 245 | TRACE_DETAIL("channel: %d", thread_tasklet_data_ptr->link_config.rfChannel); |
| group-onsemi | 0:098463de4c5d | 246 | TRACE_DETAIL("channel page: %d", thread_tasklet_data_ptr->channel_list.channel_page); |
| group-onsemi | 0:098463de4c5d | 247 | TRACE_DETAIL("channel mask: %d", (int)thread_tasklet_data_ptr->channel_list.channel_mask[0]); |
| group-onsemi | 0:098463de4c5d | 248 | |
| group-onsemi | 0:098463de4c5d | 249 | |
| group-onsemi | 0:098463de4c5d | 250 | // Beacon data setting |
| group-onsemi | 0:098463de4c5d | 251 | thread_tasklet_data_ptr->link_config.Protocol_id = 0x03; |
| group-onsemi | 0:098463de4c5d | 252 | thread_tasklet_data_ptr->link_config.version = 1; |
| group-onsemi | 0:098463de4c5d | 253 | memcpy(thread_tasklet_data_ptr->link_config.extended_random_mac, device_configuration.eui64, 8); |
| group-onsemi | 0:098463de4c5d | 254 | thread_tasklet_data_ptr->link_config.extended_random_mac[0] |= 0x02; |
| group-onsemi | 0:098463de4c5d | 255 | |
| group-onsemi | 0:098463de4c5d | 256 | // Mesh prefix |
| group-onsemi | 0:098463de4c5d | 257 | const uint8_t mesh_local_prefix[] = MBED_MESH_API_THREAD_CONFIG_ML_PREFIX; |
| group-onsemi | 0:098463de4c5d | 258 | if (sizeof(mesh_local_prefix) == 8) { |
| group-onsemi | 0:098463de4c5d | 259 | memcpy(thread_tasklet_data_ptr->link_config.mesh_local_ula_prefix, mesh_local_prefix, 8); |
| group-onsemi | 0:098463de4c5d | 260 | TRACE_DETAIL("Mesh prefix: %s", trace_array(mesh_local_prefix, 8)); |
| group-onsemi | 0:098463de4c5d | 261 | } else { |
| group-onsemi | 0:098463de4c5d | 262 | tr_error("Mesh prefix, must be 8 hex chars: %s", mesh_local_prefix); |
| group-onsemi | 0:098463de4c5d | 263 | return; |
| group-onsemi | 0:098463de4c5d | 264 | } |
| group-onsemi | 0:098463de4c5d | 265 | |
| group-onsemi | 0:098463de4c5d | 266 | // Master Key |
| group-onsemi | 0:098463de4c5d | 267 | const uint8_t master_key[] = MBED_MESH_API_THREAD_MASTER_KEY; |
| group-onsemi | 0:098463de4c5d | 268 | if (sizeof(master_key) == 16) { |
| group-onsemi | 0:098463de4c5d | 269 | memcpy(thread_tasklet_data_ptr->link_config.master_key, master_key, 16); |
| group-onsemi | 0:098463de4c5d | 270 | TRACE_DETAIL("Master key: %s", trace_array(master_key, 16)); |
| group-onsemi | 0:098463de4c5d | 271 | } else { |
| group-onsemi | 0:098463de4c5d | 272 | tr_error("Master key must be 16 hex chars: %s", master_key); |
| group-onsemi | 0:098463de4c5d | 273 | return; |
| group-onsemi | 0:098463de4c5d | 274 | } |
| group-onsemi | 0:098463de4c5d | 275 | |
| group-onsemi | 0:098463de4c5d | 276 | // PSKc |
| group-onsemi | 0:098463de4c5d | 277 | const uint8_t PSKc[] = MBED_MESH_API_THREAD_CONFIG_PSKC; |
| group-onsemi | 0:098463de4c5d | 278 | if (sizeof(PSKc) == 16) { |
| group-onsemi | 0:098463de4c5d | 279 | memcpy(thread_tasklet_data_ptr->link_config.PSKc, PSKc, 16); |
| group-onsemi | 0:098463de4c5d | 280 | TRACE_DETAIL("PSKc: %s", trace_array(PSKc, 16)); |
| group-onsemi | 0:098463de4c5d | 281 | } else { |
| group-onsemi | 0:098463de4c5d | 282 | tr_error("PSKc must be 16 hex chars: %s", PSKc); |
| group-onsemi | 0:098463de4c5d | 283 | return; |
| group-onsemi | 0:098463de4c5d | 284 | } |
| group-onsemi | 0:098463de4c5d | 285 | |
| group-onsemi | 0:098463de4c5d | 286 | // PSKd |
| group-onsemi | 0:098463de4c5d | 287 | const char PSKd[] = MBED_MESH_API_THREAD_PSKD; |
| group-onsemi | 0:098463de4c5d | 288 | if (sizeof(PSKd) < 7) { |
| group-onsemi | 0:098463de4c5d | 289 | tr_error("PSKd length must be > 6: %s", PSKd); |
| group-onsemi | 0:098463de4c5d | 290 | return; |
| group-onsemi | 0:098463de4c5d | 291 | } |
| group-onsemi | 0:098463de4c5d | 292 | |
| group-onsemi | 0:098463de4c5d | 293 | char *dyn_buf = ns_dyn_mem_alloc(sizeof(PSKd)); |
| group-onsemi | 0:098463de4c5d | 294 | strcpy(dyn_buf, PSKd); |
| group-onsemi | 0:098463de4c5d | 295 | ns_dyn_mem_free(device_configuration.PSKd_ptr); |
| group-onsemi | 0:098463de4c5d | 296 | device_configuration.PSKd_ptr = (uint8_t*)dyn_buf; |
| group-onsemi | 0:098463de4c5d | 297 | device_configuration.PSKd_len = sizeof(PSKd) - 1; |
| group-onsemi | 0:098463de4c5d | 298 | TRACE_DETAIL("PSKd: %s", device_configuration.PSKd_ptr); |
| group-onsemi | 0:098463de4c5d | 299 | |
| group-onsemi | 0:098463de4c5d | 300 | thread_tasklet_data_ptr->link_config.key_rotation = 3600; |
| group-onsemi | 0:098463de4c5d | 301 | thread_tasklet_data_ptr->link_config.key_sequence = 0; |
| group-onsemi | 0:098463de4c5d | 302 | |
| group-onsemi | 0:098463de4c5d | 303 | thread_management_node_init(thread_tasklet_data_ptr->nwk_if_id, |
| group-onsemi | 0:098463de4c5d | 304 | &thread_tasklet_data_ptr->channel_list, |
| group-onsemi | 0:098463de4c5d | 305 | &device_configuration, |
| group-onsemi | 0:098463de4c5d | 306 | &thread_tasklet_data_ptr->link_config); |
| group-onsemi | 0:098463de4c5d | 307 | |
| group-onsemi | 0:098463de4c5d | 308 | status = arm_nwk_interface_up(thread_tasklet_data_ptr->nwk_if_id); |
| group-onsemi | 0:098463de4c5d | 309 | |
| group-onsemi | 0:098463de4c5d | 310 | if (status >= 0) { |
| group-onsemi | 0:098463de4c5d | 311 | thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED; |
| group-onsemi | 0:098463de4c5d | 312 | tr_info("Start Thread bootstrap (%s mode)", thread_tasklet_data_ptr->operating_mode == NET_6LOWPAN_SLEEPY_HOST ? "SED" : "Router"); |
| group-onsemi | 0:098463de4c5d | 313 | } else { |
| group-onsemi | 0:098463de4c5d | 314 | thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; |
| group-onsemi | 0:098463de4c5d | 315 | tr_err("Bootstrap start failed, %d", status); |
| group-onsemi | 0:098463de4c5d | 316 | thread_tasklet_network_state_changed(MESH_BOOTSTRAP_START_FAILED); |
| group-onsemi | 0:098463de4c5d | 317 | } |
| group-onsemi | 0:098463de4c5d | 318 | } |
| group-onsemi | 0:098463de4c5d | 319 | |
| group-onsemi | 0:098463de4c5d | 320 | /* |
| group-onsemi | 0:098463de4c5d | 321 | * Inform application about network state change |
| group-onsemi | 0:098463de4c5d | 322 | */ |
| group-onsemi | 0:098463de4c5d | 323 | void thread_tasklet_network_state_changed(mesh_connection_status_t status) |
| group-onsemi | 0:098463de4c5d | 324 | { |
| group-onsemi | 0:098463de4c5d | 325 | if (thread_tasklet_data_ptr->mesh_api_cb) { |
| group-onsemi | 0:098463de4c5d | 326 | (thread_tasklet_data_ptr->mesh_api_cb)(status); |
| group-onsemi | 0:098463de4c5d | 327 | } |
| group-onsemi | 0:098463de4c5d | 328 | } |
| group-onsemi | 0:098463de4c5d | 329 | |
| group-onsemi | 0:098463de4c5d | 330 | /* |
| group-onsemi | 0:098463de4c5d | 331 | * Trace bootstrap information. |
| group-onsemi | 0:098463de4c5d | 332 | */ |
| group-onsemi | 0:098463de4c5d | 333 | #ifdef TRACE_THREAD_TASKLET |
| group-onsemi | 0:098463de4c5d | 334 | void thread_tasklet_trace_bootstrap_info() |
| group-onsemi | 0:098463de4c5d | 335 | { |
| group-onsemi | 0:098463de4c5d | 336 | link_layer_address_s app_link_address_info; |
| group-onsemi | 0:098463de4c5d | 337 | uint8_t temp_ipv6[16]; |
| group-onsemi | 0:098463de4c5d | 338 | if (arm_net_address_get(thread_tasklet_data_ptr->nwk_if_id, |
| group-onsemi | 0:098463de4c5d | 339 | ADDR_IPV6_GP, temp_ipv6) == 0) { |
| group-onsemi | 0:098463de4c5d | 340 | tr_debug("GP IPv6: %s", trace_ipv6(temp_ipv6)); |
| group-onsemi | 0:098463de4c5d | 341 | } |
| group-onsemi | 0:098463de4c5d | 342 | |
| group-onsemi | 0:098463de4c5d | 343 | if (arm_nwk_mac_address_read(thread_tasklet_data_ptr->nwk_if_id, |
| group-onsemi | 0:098463de4c5d | 344 | &app_link_address_info) != 0) { |
| group-onsemi | 0:098463de4c5d | 345 | tr_error("MAC Address read fail\n"); |
| group-onsemi | 0:098463de4c5d | 346 | } else { |
| group-onsemi | 0:098463de4c5d | 347 | uint8_t temp[2]; |
| group-onsemi | 0:098463de4c5d | 348 | common_write_16_bit(app_link_address_info.mac_short,temp); |
| group-onsemi | 0:098463de4c5d | 349 | tr_debug("MAC 16-bit: %s", trace_array(temp, 2)); |
| group-onsemi | 0:098463de4c5d | 350 | common_write_16_bit(app_link_address_info.PANId, temp); |
| group-onsemi | 0:098463de4c5d | 351 | tr_debug("PAN ID: %s", trace_array(temp, 2)); |
| group-onsemi | 0:098463de4c5d | 352 | tr_debug("MAC 64-bit: %s", trace_array(app_link_address_info.mac_long, 8)); |
| group-onsemi | 0:098463de4c5d | 353 | tr_debug("IID (Based on MAC 64-bit address): %s", trace_array(app_link_address_info.iid_eui64, 8)); |
| group-onsemi | 0:098463de4c5d | 354 | } |
| group-onsemi | 0:098463de4c5d | 355 | } |
| group-onsemi | 0:098463de4c5d | 356 | #endif /* #define TRACE_THREAD_TASKLET */ |
| group-onsemi | 0:098463de4c5d | 357 | |
| group-onsemi | 0:098463de4c5d | 358 | int8_t thread_tasklet_get_ip_address(char *address, int8_t len) |
| group-onsemi | 0:098463de4c5d | 359 | { |
| group-onsemi | 0:098463de4c5d | 360 | uint8_t binary_ipv6[16]; |
| group-onsemi | 0:098463de4c5d | 361 | |
| group-onsemi | 0:098463de4c5d | 362 | if ((len >= 40) && (0 == arm_net_address_get( |
| group-onsemi | 0:098463de4c5d | 363 | thread_tasklet_data_ptr->nwk_if_id, ADDR_IPV6_GP, binary_ipv6))) { |
| group-onsemi | 0:098463de4c5d | 364 | ip6tos(binary_ipv6, address); |
| group-onsemi | 0:098463de4c5d | 365 | //tr_debug("IP address: %s", address); |
| group-onsemi | 0:098463de4c5d | 366 | return 0; |
| group-onsemi | 0:098463de4c5d | 367 | } else { |
| group-onsemi | 0:098463de4c5d | 368 | return -1; |
| group-onsemi | 0:098463de4c5d | 369 | } |
| group-onsemi | 0:098463de4c5d | 370 | } |
| group-onsemi | 0:098463de4c5d | 371 | |
| group-onsemi | 0:098463de4c5d | 372 | int8_t thread_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_id) |
| group-onsemi | 0:098463de4c5d | 373 | { |
| group-onsemi | 0:098463de4c5d | 374 | int8_t re_connecting = true; |
| group-onsemi | 0:098463de4c5d | 375 | int8_t tasklet = thread_tasklet_data_ptr->tasklet; |
| group-onsemi | 0:098463de4c5d | 376 | |
| group-onsemi | 0:098463de4c5d | 377 | if (thread_tasklet_data_ptr->nwk_if_id != INVALID_INTERFACE_ID) { |
| group-onsemi | 0:098463de4c5d | 378 | return -3; // already connected to network |
| group-onsemi | 0:098463de4c5d | 379 | } |
| group-onsemi | 0:098463de4c5d | 380 | |
| group-onsemi | 0:098463de4c5d | 381 | if (thread_tasklet_data_ptr->tasklet_state == TASKLET_STATE_CREATED) { |
| group-onsemi | 0:098463de4c5d | 382 | re_connecting = false; |
| group-onsemi | 0:098463de4c5d | 383 | } |
| group-onsemi | 0:098463de4c5d | 384 | |
| group-onsemi | 0:098463de4c5d | 385 | memset(thread_tasklet_data_ptr, 0, sizeof(thread_tasklet_data_str_t)); |
| group-onsemi | 0:098463de4c5d | 386 | thread_tasklet_data_ptr->mesh_api_cb = callback; |
| group-onsemi | 0:098463de4c5d | 387 | thread_tasklet_data_ptr->nwk_if_id = nwk_interface_id; |
| group-onsemi | 0:098463de4c5d | 388 | thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_INITIALIZED; |
| group-onsemi | 0:098463de4c5d | 389 | |
| group-onsemi | 0:098463de4c5d | 390 | if (re_connecting == false) { |
| group-onsemi | 0:098463de4c5d | 391 | thread_tasklet_data_ptr->tasklet = eventOS_event_handler_create(&thread_tasklet_main, |
| group-onsemi | 0:098463de4c5d | 392 | ARM_LIB_TASKLET_INIT_EVENT); |
| group-onsemi | 0:098463de4c5d | 393 | if (thread_tasklet_data_ptr->tasklet < 0) { |
| group-onsemi | 0:098463de4c5d | 394 | // -1 handler already used by other tasklet |
| group-onsemi | 0:098463de4c5d | 395 | // -2 memory allocation failure |
| group-onsemi | 0:098463de4c5d | 396 | return thread_tasklet_data_ptr->tasklet; |
| group-onsemi | 0:098463de4c5d | 397 | } |
| group-onsemi | 0:098463de4c5d | 398 | ns_event_loop_thread_start(); |
| group-onsemi | 0:098463de4c5d | 399 | } else { |
| group-onsemi | 0:098463de4c5d | 400 | thread_tasklet_data_ptr->tasklet = tasklet; |
| group-onsemi | 0:098463de4c5d | 401 | mesh_system_send_connect_event(thread_tasklet_data_ptr->tasklet); |
| group-onsemi | 0:098463de4c5d | 402 | } |
| group-onsemi | 0:098463de4c5d | 403 | |
| group-onsemi | 0:098463de4c5d | 404 | return thread_tasklet_data_ptr->tasklet; |
| group-onsemi | 0:098463de4c5d | 405 | } |
| group-onsemi | 0:098463de4c5d | 406 | |
| group-onsemi | 0:098463de4c5d | 407 | int8_t thread_tasklet_disconnect(bool send_cb) |
| group-onsemi | 0:098463de4c5d | 408 | { |
| group-onsemi | 0:098463de4c5d | 409 | int8_t status = -1; |
| group-onsemi | 0:098463de4c5d | 410 | // check that module is initialized |
| group-onsemi | 0:098463de4c5d | 411 | if (thread_tasklet_data_ptr != NULL) { |
| group-onsemi | 0:098463de4c5d | 412 | if (thread_tasklet_data_ptr->nwk_if_id != INVALID_INTERFACE_ID) { |
| group-onsemi | 0:098463de4c5d | 413 | status = arm_nwk_interface_down(thread_tasklet_data_ptr->nwk_if_id); |
| group-onsemi | 0:098463de4c5d | 414 | thread_tasklet_data_ptr->nwk_if_id = INVALID_INTERFACE_ID; |
| group-onsemi | 0:098463de4c5d | 415 | if (send_cb == true) { |
| group-onsemi | 0:098463de4c5d | 416 | thread_tasklet_network_state_changed(MESH_DISCONNECTED); |
| group-onsemi | 0:098463de4c5d | 417 | } |
| group-onsemi | 0:098463de4c5d | 418 | } |
| group-onsemi | 0:098463de4c5d | 419 | |
| group-onsemi | 0:098463de4c5d | 420 | // Clear callback, it will be set again in next connect |
| group-onsemi | 0:098463de4c5d | 421 | thread_tasklet_data_ptr->mesh_api_cb = NULL; |
| group-onsemi | 0:098463de4c5d | 422 | } |
| group-onsemi | 0:098463de4c5d | 423 | return status; |
| group-onsemi | 0:098463de4c5d | 424 | } |
| group-onsemi | 0:098463de4c5d | 425 | |
| group-onsemi | 0:098463de4c5d | 426 | void thread_tasklet_init(void) |
| group-onsemi | 0:098463de4c5d | 427 | { |
| group-onsemi | 0:098463de4c5d | 428 | if (thread_tasklet_data_ptr == NULL) { |
| group-onsemi | 0:098463de4c5d | 429 | thread_tasklet_data_ptr = ns_dyn_mem_alloc(sizeof(thread_tasklet_data_str_t)); |
| group-onsemi | 0:098463de4c5d | 430 | thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_CREATED; |
| group-onsemi | 0:098463de4c5d | 431 | thread_tasklet_data_ptr->nwk_if_id = INVALID_INTERFACE_ID; |
| group-onsemi | 0:098463de4c5d | 432 | } |
| group-onsemi | 0:098463de4c5d | 433 | } |
| group-onsemi | 0:098463de4c5d | 434 | |
| group-onsemi | 0:098463de4c5d | 435 | int8_t thread_tasklet_network_init(int8_t device_id) |
| group-onsemi | 0:098463de4c5d | 436 | { |
| group-onsemi | 0:098463de4c5d | 437 | // TODO, read interface name from configuration |
| group-onsemi | 0:098463de4c5d | 438 | mac_description_storage_size_t storage_sizes; |
| group-onsemi | 0:098463de4c5d | 439 | storage_sizes.device_decription_table_size = 32; |
| group-onsemi | 0:098463de4c5d | 440 | storage_sizes.key_description_table_size = 6; |
| group-onsemi | 0:098463de4c5d | 441 | storage_sizes.key_lookup_size = 1; |
| group-onsemi | 0:098463de4c5d | 442 | storage_sizes.key_usage_size = 3; |
| group-onsemi | 0:098463de4c5d | 443 | mac_api_t *api = ns_sw_mac_create(device_id, &storage_sizes); |
| group-onsemi | 0:098463de4c5d | 444 | return arm_nwk_interface_lowpan_init(api, INTERFACE_NAME); |
| group-onsemi | 0:098463de4c5d | 445 | } |
| group-onsemi | 0:098463de4c5d | 446 | |
| group-onsemi | 0:098463de4c5d | 447 | void thread_tasklet_device_config_set(uint8_t *eui64, char *pskd) |
| group-onsemi | 0:098463de4c5d | 448 | { |
| group-onsemi | 0:098463de4c5d | 449 | (void) pskd; // this parameter is delivered via mbed configuration |
| group-onsemi | 0:098463de4c5d | 450 | memcpy(device_configuration.eui64, eui64, 8); |
| group-onsemi | 0:098463de4c5d | 451 | } |
| group-onsemi | 0:098463de4c5d | 452 | |
| group-onsemi | 0:098463de4c5d | 453 | int8_t thread_tasklet_data_poll_rate_set(uint32_t timeout) |
| group-onsemi | 0:098463de4c5d | 454 | { |
| group-onsemi | 0:098463de4c5d | 455 | int8_t status = -1; |
| group-onsemi | 0:098463de4c5d | 456 | if (thread_tasklet_data_ptr) { |
| group-onsemi | 0:098463de4c5d | 457 | if (timeout != 0) { |
| group-onsemi | 0:098463de4c5d | 458 | status = arm_nwk_host_mode_set(thread_tasklet_data_ptr->nwk_if_id, NET_HOST_SLOW_POLL_MODE, timeout); |
| group-onsemi | 0:098463de4c5d | 459 | } else { |
| group-onsemi | 0:098463de4c5d | 460 | status = arm_nwk_host_mode_set(thread_tasklet_data_ptr->nwk_if_id, NET_HOST_RX_ON_IDLE, timeout); |
| group-onsemi | 0:098463de4c5d | 461 | } |
| group-onsemi | 0:098463de4c5d | 462 | } |
| group-onsemi | 0:098463de4c5d | 463 | |
| group-onsemi | 0:098463de4c5d | 464 | return status; |
| group-onsemi | 0:098463de4c5d | 465 | } |
| group-onsemi | 0:098463de4c5d | 466 |