/* * Copyright (c) 2021, Pelion and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "nsconfig.h" #if defined(HAVE_WS) && defined(HAVE_WS_HOST) #include "ns_types.h" #include "ns_trace.h" #include "nsdynmemLIB.h" #include "net_interface.h" #include "eventOS_event.h" #include "randLIB.h" #include "common_functions.h" #include "mac_common_defines.h" #include "sw_mac.h" #include "ccmLIB.h" #include "Core/include/ns_monitor.h" #include "NWK_INTERFACE/Include/protocol.h" #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" #include "6LoWPAN/Bootstraps/protocol_6lowpan_interface.h" #include "ipv6_stack/protocol_ipv6.h" #include "ipv6_stack/ipv6_routing_table.h" #include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mpx_api.h" #include "6LoWPAN/MAC/mac_ie_lib.h" #include "MPL/mpl.h" #include "RPL/rpl_protocol.h" #include "RPL/rpl_control.h" #include "RPL/rpl_data.h" #include "RPL/rpl_policy.h" #include "Common_Protocols/icmpv6.h" #include "Common_Protocols/icmpv6_radv.h" #include "Common_Protocols/ipv6_constants.h" #include "Common_Protocols/ip.h" #include "Service_Libs/Trickle/trickle.h" #include "Service_Libs/fhss/channel_list.h" #include "Service_Libs/utils/ns_time.h" #include "6LoWPAN/ws/ws_common_defines.h" #include "6LoWPAN/ws/ws_common_defines.h" #include "6LoWPAN/ws/ws_config.h" #include "6LoWPAN/ws/ws_common.h" #include "6LoWPAN/ws/ws_bootstrap.h" #include "6LoWPAN/ws/ws_bbr_api_internal.h" #include "6LoWPAN/ws/ws_common_defines.h" #include "6LoWPAN/ws/ws_llc.h" #include "6LoWPAN/ws/ws_neighbor_class.h" #include "6LoWPAN/ws/ws_ie_lib.h" #include "6LoWPAN/ws/ws_stats.h" #include "6LoWPAN/ws/ws_cfg_settings.h" #include "6LoWPAN/lowpan_adaptation_interface.h" #include "Service_Libs/etx/etx.h" #include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "Service_Libs/nd_proxy/nd_proxy.h" #include "Service_Libs/blacklist/blacklist.h" #include "platform/topo_trace.h" #include "dhcp_service_api.h" #include "libDHCPv6/libDHCPv6.h" #include "libDHCPv6/libDHCPv6_vendordata.h" #include "DHCPv6_client/dhcpv6_client_api.h" #include "ws_management_api.h" #include "net_rpl.h" #include "mac_api.h" #include "6LoWPAN/ws/ws_pae_controller.h" #include "6LoWPAN/ws/ws_eapol_pdu.h" #include "6LoWPAN/ws/ws_eapol_auth_relay.h" #include "6LoWPAN/ws/ws_eapol_relay.h" #include "libNET/src/net_dns_internal.h" #include "Service_Libs/random_early_detection/random_early_detection_api.h" #define TRACE_GROUP "wsbs" void ws_bootstrap_6ln_asynch_ind(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, const struct mcps_data_ie_list *ie_ext, uint8_t message_type) { (void)ie_ext; // Store weakest heard packet RSSI if (cur->ws_info->weakest_received_rssi > data->signal_dbm) { cur->ws_info->weakest_received_rssi = data->signal_dbm; } if (data->SrcAddrMode != MAC_ADDR_MODE_64_BIT) { // Not from long address return; } ws_stats_update(cur, STATS_WS_ASYNCH_RX, 1); tr_warn("Wi-SUN LFN Mode received message id: %x", message_type); } void ws_bootstrap_6ln_asynch_confirm(struct protocol_interface_info_entry *interface, uint8_t asynch_message) { (void)asynch_message; ws_stats_update(interface, STATS_WS_ASYNCH_TX, 1); } bool ws_bootstrap_6ln_eapol_relay_state_active(protocol_interface_info_entry_t *cur) { (void) cur; return false; } void ws_bootstrap_6ln_event_handler(protocol_interface_info_entry_t *cur, arm_event_s *event) { (void)cur; ws_bootsrap_event_type_e event_type; event_type = (ws_bootsrap_event_type_e)event->event_type; switch (event_type) { case WS_INIT_EVENT: tr_debug("tasklet init"); break; /* case WS_DISCOVERY_START: case WS_CONFIGURATION_START: case WS_OPERATION_START: case WS_ROUTING_READY: case WS_FAST_DISCONNECT: case WS_NORMAL_DISCONNECT: */ default: tr_err("Invalid event received"); break; } } void ws_bootstrap_6ln_state_machine(protocol_interface_info_entry_t *cur) { switch (cur->nwk_bootstrap_state) { case ER_WAIT_RESTART: tr_debug("WS SM:Wait for startup"); break; case ER_ACTIVE_SCAN: tr_debug("WS SM:Active Scan"); break; case ER_SCAN: tr_debug("WS SM:configuration Scan"); break; case ER_PANA_AUTH: tr_info("authentication start"); // Advertisements stopped during the EAPOL break; case ER_RPL_SCAN: tr_debug("WS SM:Wait RPL to contact DODAG root"); break; case ER_BOOTSRAP_DONE: tr_info("WS SM:Bootstrap Done"); // Bootstrap_done event to application break; case ER_RPL_NETWORK_LEAVING: tr_debug("WS SM:RPL Leaving ready trigger discovery"); break; default: tr_warn("WS SM:Invalid state %d", cur->nwk_bootstrap_state); } } void ws_bootstrap_6ln_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds) { (void)cur; (void)seconds; } int8_t ws_bootstrap_6ln_up(protocol_interface_info_entry_t *cur) { int8_t ret_val = -1; if (!cur) { return -1; } if ((cur->configure_flags & INTERFACE_SETUP_MASK) != INTERFACE_SETUP_READY) { tr_error("Interface not yet fully configured"); return -2; } if (ws_bootstrap_fhss_initialize(cur) != 0) { tr_error("fhss initialization failed"); return -3; } if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { //BBR init like NVM read ws_bbr_init(cur); } // Save FHSS api cur->ws_info->fhss_api = ns_sw_mac_get_fhss_api(cur->mac_api); ws_bootstrap_ll_address_validate(cur); addr_interface_set_ll64(cur, NULL); cur->nwk_nd_re_scan_count = 0; // Trigger discovery for bootstrap ret_val = nwk_6lowpan_up(cur); if (ret_val) { goto cleanup; } /* Wi-sun will trig event for stamechine this timer must be zero on init */ cur->bootsrap_state_machine_cnt = 0; /* Disable SLLAO send/mandatory receive with the ARO */ cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro = true; /* Omit sending of NA if ARO SUCCESS */ cur->ipv6_neighbour_cache.omit_na_aro_success = true; /* Omit sending of NA and consider ACK to be success */ cur->ipv6_neighbour_cache.omit_na = true; // do not process AROs from NA. This is overriden by Wi-SUN specific failure handling cur->ipv6_neighbour_cache.recv_na_aro = false; /* Disable NUD Probes */ cur->ipv6_neighbour_cache.send_nud_probes = false; cur->ipv6_neighbour_cache.probe_avoided_routers = true; /*Replace NS handler to disable multicast address queries */ cur->if_ns_transmit = ws_bootstrap_nd_ns_transmit; // Configure memory limits and garbage collection values; ws_bootstrap_memory_configuration(); ws_nud_table_reset(cur); ws_bootstrap_candidate_table_reset(cur); // Zero uptime counters cur->ws_info->uptime = 0; cur->ws_info->authentication_time = 0; cur->ws_info->connected_time = 0; blacklist_params_set( WS_BLACKLIST_ENTRY_LIFETIME, WS_BLACKLIST_TIMER_MAX_TIMEOUT, WS_BLACKLIST_TIMER_TIMEOUT, WS_BLACKLIST_ENTRY_MAX_NBR, WS_BLACKLIST_PURGE_NBR, WS_BLACKLIST_PURGE_TIMER_TIMEOUT); ws_bootstrap_event_discovery_start(cur); return 0; cleanup: return ret_val; } int8_t ws_bootstrap_6ln_down(protocol_interface_info_entry_t *cur) { if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { return -1; } tr_info("Wi-SUN ifdown"); // Reset MAC for safe upper layer memory free protocol_mac_reset(cur); ns_sw_mac_fhss_unregister(cur->mac_api); ns_fhss_delete(cur->ws_info->fhss_api); cur->ws_info->fhss_api = NULL; // Reset WS information ws_bootstrap_asynch_trickle_stop(cur); ws_llc_reset(cur); if (nd_proxy_downstream_interface_unregister(cur->id) != 0) { tr_warn("nd proxy unregister failed"); } ws_nud_table_reset(cur); ws_pae_controller_stop(cur); ws_bootstrap_candidate_table_reset(cur); blacklist_clear(); cur->if_common_forwarding_out_cb = NULL; return nwk_6lowpan_down(cur); } #endif //HAVE_WS_BORDER_ROUTER && HAVE_WS