/* * \brief Configure mesh network * */ void thread_tasklet_configure_and_connect_to_network(void) { int8_t status; link_configuration_s* temp_link_config=NULL; if (MBED_CONF_MBED_MESH_API_THREAD_DEVICE_TYPE == MESH_DEVICE_TYPE_THREAD_MINIMAL_END_DEVICE) { thread_tasklet_data_ptr->operating_mode = NET_6LOWPAN_HOST; } else if (MBED_CONF_MBED_MESH_API_THREAD_DEVICE_TYPE == MESH_DEVICE_TYPE_THREAD_SLEEPY_END_DEVICE) { thread_tasklet_data_ptr->operating_mode = NET_6LOWPAN_SLEEPY_HOST; } else { thread_tasklet_data_ptr->operating_mode = NET_6LOWPAN_ROUTER; } arm_nwk_interface_configure_6lowpan_bootstrap_set( thread_tasklet_data_ptr->nwk_if_id, thread_tasklet_data_ptr->operating_mode, NET_6LOWPAN_THREAD); thread_tasklet_data_ptr->channel_list.channel_page = (channel_page_e)MBED_CONF_MBED_MESH_API_THREAD_CONFIG_CHANNEL_PAGE; thread_tasklet_data_ptr->channel_list.channel_mask[0] = MBED_CONF_MBED_MESH_API_THREAD_CONFIG_CHANNEL_MASK; TRACE_DETAIL("channel page: %d", thread_tasklet_data_ptr->channel_list.channel_page); TRACE_DETAIL("channel mask: 0x%.8lx", thread_tasklet_data_ptr->channel_list.channel_mask[0]); // PSKd const char PSKd[] = MBED_CONF_MBED_MESH_API_THREAD_PSKD; if(device_configuration.PSKd_len==0) { int ret = thread_tasklet_device_pskd_set(PSKd); MBED_ASSERT(!ret); } if (true == MBED_CONF_MBED_MESH_API_THREAD_USE_STATIC_LINK_CONFIG) { read_link_configuration(); temp_link_config = &thread_tasklet_data_ptr->link_config; } thread_management_node_init(thread_tasklet_data_ptr->nwk_if_id, &thread_tasklet_data_ptr->channel_list, &device_configuration, temp_link_config); status = arm_nwk_interface_up(thread_tasklet_data_ptr->nwk_if_id); if (status >= 0) { thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED; tr_info("Start Thread bootstrap (%s mode)", thread_tasklet_data_ptr->operating_mode == NET_6LOWPAN_SLEEPY_HOST ? "SED" : "Router"); thread_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED); } else { thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; tr_err("Bootstrap start failed, %d", status); thread_tasklet_network_state_changed(MESH_BOOTSTRAP_START_FAILED); } }
/** * \brief Network state event handler. * \param event show network start response or current network state. * * - ARM_NWK_BOOTSTRAP_READY: Save NVK persistent data to NVM and Net role * - ARM_NWK_NWK_SCAN_FAIL: Link Layer Active Scan Fail, Stack is Already at Idle state * - ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL: No ND Router at current Channel Stack is Already at Idle state * - ARM_NWK_NWK_CONNECTION_DOWN: Connection to Access point is lost wait for Scan Result * - ARM_NWK_NWK_PARENT_POLL_FAIL: Host should run net start without any PAN-id filter and all channels * - ARM_NWK_AUHTENTICATION_FAIL: Pana Authentication fail, Stack is Already at Idle state */ void thread_tasklet_parse_network_event(arm_event_s *event) { arm_nwk_interface_status_type_e status = (arm_nwk_interface_status_type_e) event->event_data; tr_debug("app_parse_network_event() %d", status); switch (status) { case ARM_NWK_BOOTSTRAP_READY: /* Network is ready and node is connected to Access Point */ if (thread_tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_READY) { tr_info("Thread bootstrap ready"); thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_READY; thread_tasklet_trace_bootstrap_info(); /* We are connected, for Local or Global IP */ thread_tasklet_poll_network_status(NULL); } break; case ARM_NWK_NWK_SCAN_FAIL: /* Link Layer Active Scan Fail, Stack is Already at Idle state */ tr_debug("Link Layer Scan Fail: No Beacons"); thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; thread_tasklet_network_state_changed(MESH_DISCONNECTED); break; case ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL: /* No ND Router at current Channel Stack is Already at Idle state */ tr_debug("ND Scan/ GP REG fail"); thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; thread_tasklet_network_state_changed(MESH_DISCONNECTED); break; case ARM_NWK_NWK_CONNECTION_DOWN: /* Connection to Access point is lost wait for Scan Result */ tr_debug("ND/RPL scan new network"); thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; thread_tasklet_network_state_changed(MESH_DISCONNECTED); break; case ARM_NWK_NWK_PARENT_POLL_FAIL: thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; thread_tasklet_network_state_changed(MESH_DISCONNECTED); break; case ARM_NWK_AUHTENTICATION_FAIL: tr_debug("Network authentication fail"); thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; thread_tasklet_network_state_changed(MESH_DISCONNECTED); break; default: tr_warn("Unknown event %d", status); break; } if (thread_tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_READY) { // Set 5s timer for a new network scan eventOS_event_timer_request(TIMER_EVENT_START_BOOTSTRAP, ARM_LIB_SYSTEM_TIMER_EVENT, thread_tasklet_data_ptr->tasklet, 5000); } }
/* * \brief A function which will be eventually called by NanoStack OS when ever the OS has an event to deliver. * @param event, describes the sender, receiver and event type. * * NOTE: Interrupts requested by HW are possible during this function! */ void thread_tasklet_main(arm_event_s *event) { arm_library_event_type_e event_type; event_type = (arm_library_event_type_e) event->event_type; switch (event_type) { case ARM_LIB_NWK_INTERFACE_EVENT: /* This event is delivered every and each time when there is new * information of network connectivity. */ thread_tasklet_parse_network_event(event); break; case ARM_LIB_TASKLET_INIT_EVENT: /* Event with type EV_INIT is an initializer event of NanoStack OS. * The event is delivered when the NanoStack OS is running fine. * This event should be delivered ONLY ONCE. */ mesh_system_send_connect_event(thread_tasklet_data_ptr->tasklet); break; case ARM_LIB_SYSTEM_TIMER_EVENT: eventOS_event_timer_cancel(event->event_id, thread_tasklet_data_ptr->tasklet); if (event->event_id == TIMER_EVENT_START_BOOTSTRAP) { int8_t status; tr_debug("Restart bootstrap"); status = arm_nwk_interface_up(thread_tasklet_data_ptr->nwk_if_id); if (status >= 0) { thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED; tr_info("Start Thread bootstrap (%s mode)", thread_tasklet_data_ptr->operating_mode == NET_6LOWPAN_SLEEPY_HOST ? "SED" : "Router"); thread_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED); } else { thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; tr_err("Bootstrap start failed, %d", status); thread_tasklet_network_state_changed(MESH_BOOTSTRAP_START_FAILED); } } break; case APPLICATION_EVENT: if (event->event_id == APPL_EVENT_CONNECT) { thread_tasklet_configure_and_connect_to_network(); } break; default: break; } // switch(event_type) }
void thread_tasklet_poll_network_status(void *param) { /* Check if we do have an IP */ uint8_t temp_ipv6[16]; if (arm_net_address_get(thread_tasklet_data_ptr->nwk_if_id, ADDR_IPV6_GP, temp_ipv6) == 0) { /* Check if this is the same IP than previously */ if (memcmp(temp_ipv6, thread_tasklet_data_ptr->ip, 16) == 0) { return; } else { memcpy(thread_tasklet_data_ptr->ip, temp_ipv6, 16); link_configuration_s *link_cfg = thread_management_configuration_get(thread_tasklet_data_ptr->nwk_if_id); if (memcmp(thread_tasklet_data_ptr->ip, link_cfg->mesh_local_ula_prefix, 8) == 0) { thread_tasklet_network_state_changed(MESH_CONNECTED_LOCAL); } else { thread_tasklet_network_state_changed(MESH_CONNECTED_GLOBAL); } } } else { if (thread_tasklet_data_ptr->connection_status != MESH_DISCONNECTED && thread_tasklet_data_ptr->connection_status != MESH_BOOTSTRAP_STARTED) thread_tasklet_network_state_changed(MESH_DISCONNECTED); } }
int8_t thread_tasklet_disconnect(bool send_cb) { int8_t status = -1; // check that module is initialized if (thread_tasklet_data_ptr != NULL) { if (thread_tasklet_data_ptr->nwk_if_id != INVALID_INTERFACE_ID) { status = arm_nwk_interface_down(thread_tasklet_data_ptr->nwk_if_id); thread_tasklet_data_ptr->nwk_if_id = INVALID_INTERFACE_ID; if (send_cb == true) { thread_tasklet_network_state_changed(MESH_DISCONNECTED); } } // Clear callback, it will be set again in next connect thread_tasklet_data_ptr->mesh_api_cb = NULL; } return status; }