| /* |
| * |
| * Copyright (c) 2020 Project CHIP Authors |
| * Copyright (c) 2019 Nest Labs, Inc. |
| * |
| * 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. |
| */ |
| /* this file behaves like a config.h, comes first */ |
| #include <platform/internal/CHIPDeviceLayerInternal.h> |
| |
| #include <platform/ConnectivityManager.h> |
| |
| #include <lib/support/CodeUtils.h> |
| #include <lib/support/logging/CHIPLogging.h> |
| #include <platform/ConnectivityManager.h> |
| #include <platform/internal/BLEManager.h> |
| #include <platform/mt793x/NetworkCommissioningWiFiDriver.h> |
| |
| #include <lwip/dns.h> |
| #include <lwip/ip_addr.h> |
| #include <lwip/nd6.h> |
| #include <lwip/netif.h> |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE |
| #include <platform/internal/GenericConnectivityManagerImpl_BLE.ipp> |
| #endif |
| |
| #include "mt7933_pos.h" |
| #include "wifi_api_ex.h" |
| |
| using namespace ::chip; |
| using namespace ::chip::Inet; |
| using namespace ::chip::System; |
| using namespace ::chip::TLV; |
| using namespace ::chip::DeviceLayer::Internal; |
| |
| namespace chip { |
| namespace DeviceLayer { |
| |
| CHIP_ERROR ConnectivityManagerImpl::WiFiInit(void) |
| { |
| CHIP_ERROR err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; |
| |
| ChipLogProgress(DeviceLayer, "ConnectivityManager Wi-Fi init"); |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION |
| // Queue work items to bootstrap the AP and station state machines once |
| // the Chip event loop is running. |
| mWiFiStationMode = kWiFiStationMode_Disabled; |
| mWiFiStationState = kWiFiStationState_NotConnected; |
| mLastStationConnectFailTime = System::Clock::kZero; |
| mWiFiStationReconnectInterval = System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_WIFI_STATION_RECONNECT_INTERVAL); |
| #endif |
| #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP |
| mWiFiAPMode = kWiFiAPMode_Disabled; |
| mWiFiAPState = kWiFiAPState_NotActive; |
| mWiFiAPIdleTimeout = System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_WIFI_AP_IDLE_TIMEOUT); |
| mLastAPDemandTime = System::Clock::kZero; |
| #endif |
| mFlags.ClearAll(); |
| |
| mFilogicCtx = PlatformMgrImpl().mFilogicCtx; |
| |
| if (!IsWiFiStationProvisioned()) |
| { |
| #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP |
| mWiFiAPMode = kWiFiAPMode_Enabled; |
| mWiFiAPState = kWiFiAPState_NotActive; |
| filogic_wifi_init_async(mFilogicCtx, FILOGIC_WIFI_OPMODE_AP); |
| err = CHIP_NO_ERROR; |
| SuccessOrExit(err); |
| #endif |
| } |
| else |
| { |
| #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION |
| mWiFiStationMode = kWiFiStationMode_Enabled; |
| mWiFiStationState = kWiFiStationState_NotConnected; |
| filogic_wifi_init_async(mFilogicCtx, FILOGIC_WIFI_OPMODE_STA); |
| err = CHIP_NO_ERROR; |
| SuccessOrExit(err); |
| #endif |
| } |
| |
| ChipLogProgress(DeviceLayer, "ConnectivityManager Wi-Fi init done"); |
| |
| exit: |
| return err; |
| } |
| |
| void ConnectivityManagerImpl::ChangeWiFiAPState(WiFiAPState newState) |
| { |
| if (mWiFiAPState != newState) |
| { |
| ChipLogProgress(DeviceLayer, "WiFi AP state change: %s -> %s", WiFiAPStateToStr(mWiFiAPState), WiFiAPStateToStr(newState)); |
| mWiFiAPState = newState; |
| } |
| } |
| |
| void ConnectivityManagerImpl::_OnWiFiPlatformEvent(const ChipDeviceEvent * event) |
| { |
| if (event->Type != DeviceEventType::kMtkWiFiEvent) |
| return; |
| |
| ChipLogProgress(DeviceLayer, "%s WiFi event %s", __func__, filogic_event_to_name(event->Platform.FilogicEvent.event)); |
| |
| const filogic_async_event_data * event_data; |
| bool hadIPv4Conn = mFlags.Has(ConnectivityFlags::kHaveIPv4InternetConnectivity); |
| bool hadIPv6Conn = mFlags.Has(ConnectivityFlags::kHaveIPv6InternetConnectivity); |
| |
| event_data = &event->Platform.MtkWiFiEvent.event_data; |
| |
| if (event_data->event_id == FILOGIC_WIFI_INIT_OK) |
| { |
| if (FILOGIC_WIFI_PORT_STA == event_data->u.wifi_init.port) |
| { |
| mWiFiStationState = kWiFiStationState_NotConnected; |
| DriveStationState(); |
| } |
| else if (FILOGIC_WIFI_PORT_AP == event_data->u.wifi_init.port) |
| { |
| ConfigureWiFiAP(); |
| ChangeWiFiAPState(kWiFiAPState_Activating); |
| } |
| else |
| assert(0); |
| } |
| else if (event_data->event_id == FILOGIC_AP_START_OK) |
| { |
| ChangeWiFiAPState(kWiFiAPState_Active); |
| } |
| else if (event_data->event_id == FILOGIC_SET_OPMODE_OK) |
| { |
| if (event_data->u.wifi_opmode.opmode == WIFI_MODE_STA_ONLY) |
| ChangeWiFiStationState(kWiFiStationState_NotConnected); |
| else if (event_data->u.wifi_opmode.opmode == WIFI_MODE_AP_ONLY) |
| ChangeWiFiAPState(kWiFiAPState_Active); |
| else |
| assert(0); |
| } |
| else if (event_data->event_id == FILOGIC_AP_STATION_CONNECTED) |
| { |
| MaintainOnDemandWiFiAP(); |
| } |
| else if (event_data->event_id == FILOGIC_AP_STATION_DISCONNECTED) |
| { |
| } |
| else if (event_data->event_id == FILOGIC_STA_DISCONNECTED_FROM_AP) |
| { |
| if (mWiFiStationState == kWiFiStationState_Connecting) |
| { |
| ChangeWiFiStationState(kWiFiStationState_Connecting_Failed); |
| } |
| DriveStationState(); |
| } |
| else if (!hadIPv4Conn && event_data->event_id == FILOGIC_STA_IPV4_ADDR_READY) |
| { |
| if (mWiFiStationState == kWiFiStationState_Connecting) |
| { |
| ChangeWiFiStationState(kWiFiStationState_Connecting_Succeeded); |
| } |
| |
| ChipLogProgress(DeviceLayer, "ip addr: %s", event_data->u.ipv4_str.addr); |
| DriveStationState(); |
| UpdateInternetConnectivityState(TRUE, hadIPv6Conn, event_data->u.ipv4_str.addr); |
| } |
| |
| if (!hadIPv6Conn && event_data->event_id == FILOGIC_STA_IPV6_ADDR_READY) |
| { |
| if (mWiFiStationState == kWiFiStationState_Connecting) |
| { |
| ChangeWiFiStationState(kWiFiStationState_Connecting_Succeeded); |
| } |
| |
| const char * addrv6 = (const char *) &event_data->u.ipv6_str.addr[0]; |
| ChipLogProgress(DeviceLayer, "ip addr: %s", addrv6); |
| |
| DriveStationState(); |
| |
| UpdateInternetConnectivityState(hadIPv4Conn, TRUE, event_data->u.ipv6_str.addr); |
| } |
| else if (event->Platform.FilogicEvent.event == FILOGIC_STA_CONNECTED_TO_AP) |
| { |
| ChipLogProgress(DeviceLayer, "WIFI_EVENT_STA_CONNECTED"); |
| if (mWiFiStationState == kWiFiStationState_Connecting) |
| { |
| ChangeWiFiStationState(kWiFiStationState_Connecting_Succeeded); |
| } |
| DriveStationState(); |
| } |
| } |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_WIFI |
| ConnectivityManager::WiFiStationMode ConnectivityManagerImpl::GetFilogicStationMode(void) |
| { |
| #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION |
| filogic_wifi_opmode_t opmode; |
| int32_t ret; |
| |
| filogic_wifi_opmode_get_sync(mFilogicCtx, &opmode); |
| |
| if (opmode == FILOGIC_WIFI_OPMODE_STA || opmode == FILOGIC_WIFI_OPMODE_DUAL) |
| return kWiFiStationMode_Enabled; |
| #endif |
| return kWiFiStationMode_Disabled; |
| } |
| |
| ConnectivityManager::WiFiAPMode ConnectivityManagerImpl::GetFilogicAPMode(void) |
| { |
| #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP |
| filogic_wifi_opmode_t opmode; |
| int32_t ret; |
| |
| filogic_wifi_opmode_get_sync(mFilogicCtx, &opmode); |
| |
| if (opmode == FILOGIC_WIFI_OPMODE_AP || opmode == FILOGIC_WIFI_OPMODE_DUAL) |
| return kWiFiAPMode_Enabled; |
| #endif |
| return kWiFiAPMode_Disabled; |
| } |
| |
| filogic_wifi_opmode_t ConnectivityManagerImpl::GetFilogicNextOpMode(WiFiStationMode staMode, WiFiAPMode apMode) |
| { |
| bool sta, ap; |
| filogic_wifi_opmode_t opmode; |
| |
| ChipLogProgress(DeviceLayer, "%s %d %d", __func__, staMode, apMode); |
| |
| sta = staMode == kWiFiStationMode_Enabled; |
| ap = apMode == kWiFiAPMode_Enabled; |
| |
| if (sta && ap) |
| opmode = FILOGIC_WIFI_OPMODE_DUAL; |
| else if (ap) |
| opmode = FILOGIC_WIFI_OPMODE_AP; |
| else if (sta) |
| opmode = FILOGIC_WIFI_OPMODE_STA; |
| else |
| opmode = FILOGIC_WIFI_OPMODE_NONE; |
| |
| return opmode; |
| } |
| |
| void ConnectivityManagerImpl::SetFlogicNextMode(filogic_wifi_opmode_t nextMode) |
| { |
| ChipLogProgress(DeviceLayer, "WiFi driver mode set %s", filogic_opmode_to_name(nextMode)); |
| filogic_wifi_opmode_set_async(mFilogicCtx, nextMode); |
| } |
| #endif |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION |
| ConnectivityManager::WiFiStationMode ConnectivityManagerImpl::_GetWiFiStationMode(void) |
| { |
| if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled) |
| { |
| filogic_wifi_opmode_t opmode; |
| |
| filogic_wifi_opmode_get_sync(mFilogicCtx, &opmode); |
| |
| if (opmode == FILOGIC_WIFI_OPMODE_AP) |
| mWiFiStationMode = kWiFiStationMode_Disabled; |
| else |
| mWiFiStationMode = kWiFiStationMode_Enabled; |
| } |
| return mWiFiStationMode; |
| } |
| |
| CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationMode(ConnectivityManager::WiFiStationMode val) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| if (mWiFiStationMode != val) |
| { |
| ChipLogProgress(DeviceLayer, "WiFi station mode change: %s -> %s", WiFiStationModeToStr(mWiFiStationMode), |
| WiFiStationModeToStr(val)); |
| DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL); |
| mWiFiStationMode = val; |
| } |
| |
| return CHIP_NO_ERROR; |
| } |
| |
| CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationReconnectInterval(System::Clock::Timeout val) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| mWiFiStationReconnectInterval = val; |
| return CHIP_NO_ERROR; |
| } |
| |
| CHIP_ERROR ConnectivityManagerImpl::_GetAndLogWifiStatsCounters(void) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| return CHIP_ERROR_NOT_IMPLEMENTED; |
| } |
| |
| bool ConnectivityManagerImpl::_IsWiFiStationEnabled(void) |
| { |
| return GetWiFiStationMode() == kWiFiStationMode_Enabled; |
| } |
| |
| bool ConnectivityManagerImpl::_IsWiFiStationProvisioned(void) |
| { |
| filogic_wifi_sta_prov_t prov = {}; |
| |
| /* See if we have SSID */ |
| if (filogic_wifi_sta_prov_get_sync(mFilogicCtx, &prov)) |
| { |
| return prov.ssid[0] != '\0'; |
| } |
| |
| return false; |
| } |
| |
| void ConnectivityManagerImpl::_ClearWiFiStationProvision(void) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled) |
| { |
| #ifdef MT793X_PORTING |
| wfx_clear_wifi_provision(); |
| #endif /* MT793X_PORTING */ |
| |
| DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL); |
| } |
| } |
| |
| void ConnectivityManagerImpl::_OnWiFiScanDone() |
| { |
| // CHIP_ERROR_NOT_IMPLEMENTED |
| } |
| |
| void ConnectivityManagerImpl::_OnWiFiStationProvisionChange() |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| // Schedule a call to the DriveStationState method to adjust the station state as needed. |
| ChipLogProgress(DeviceLayer, "_ON WIFI PROVISION CHANGE"); |
| DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL); |
| } |
| #endif |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP |
| void ConnectivityManagerImpl::DriveAPState(void) |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| WiFiAPMode driverAPMode = GetFilogicAPMode(); |
| filogic_wifi_opmode_t nextMode; |
| |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| if (mWiFiAPMode != driverAPMode) |
| { |
| nextMode = GetFilogicNextOpMode(mWiFiStationMode, driverAPMode); |
| ChipLogProgress(DeviceLayer, "WiFi Driver AP mode set: %d", nextMode); |
| SetFlogicNextMode(nextMode); |
| if (driverAPMode == kWiFiAPMode_Enabled) |
| { |
| } |
| // TODO wait driver event |
| } |
| } |
| |
| CHIP_ERROR ConnectivityManagerImpl::ConfigureWiFiAP(void) |
| { |
| char ssid[32]; |
| int ssid_len; |
| |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| |
| // TODO, generate |
| uint16_t discriminator = 0x8888; |
| |
| ssid_len = snprintf(ssid, sizeof(ssid), "%s%03X-%04X-%04X", CHIP_DEVICE_CONFIG_WIFI_AP_SSID_PREFIX, discriminator, |
| CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID, CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID); |
| int8_t channel = CHIP_DEVICE_CONFIG_WIFI_AP_CHANNEL; |
| |
| filogic_wifi_ap_config_async(mFilogicCtx, channel, ssid, ssid_len); |
| |
| return err; |
| } |
| |
| void ConnectivityManagerImpl::DriveAPState(::chip::System::Layer * aLayer, void * aAppState) |
| { |
| sInstance.DriveAPState(); |
| } |
| |
| CHIP_ERROR ConnectivityManagerImpl::_SetWiFiAPMode(WiFiAPMode val) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| |
| VerifyOrExit(val != kWiFiAPMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT); |
| |
| if (mWiFiAPMode != val) |
| { |
| ChipLogProgress(DeviceLayer, "WiFi AP mode change: %s -> %s", WiFiAPModeToStr(mWiFiAPMode), WiFiAPModeToStr(val)); |
| } |
| |
| mWiFiAPMode = val; |
| |
| exit: |
| return err; |
| } |
| |
| void ConnectivityManagerImpl::_DemandStartWiFiAP(void) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| if (mWiFiAPMode == kWiFiAPMode_OnDemand || mWiFiAPMode == kWiFiAPMode_OnDemand_NoStationProvision) |
| { |
| mLastAPDemandTime = System::SystemClock().GetMonotonicTimestamp(); |
| DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL); |
| } |
| } |
| |
| void ConnectivityManagerImpl::_StopOnDemandWiFiAP(void) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| if (mWiFiAPMode == kWiFiAPMode_OnDemand || mWiFiAPMode == kWiFiAPMode_OnDemand_NoStationProvision) |
| { |
| mLastAPDemandTime = System::Clock::kZero; |
| DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL); |
| } |
| } |
| |
| void ConnectivityManagerImpl::_MaintainOnDemandWiFiAP(void) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| if (mWiFiAPMode == kWiFiAPMode_OnDemand || mWiFiAPMode == kWiFiAPMode_OnDemand_NoStationProvision) |
| { |
| if (mWiFiAPState == kWiFiAPState_Activating || mWiFiAPState == kWiFiAPState_Active) |
| { |
| mLastAPDemandTime = System::SystemClock().GetMonotonicTimestamp(); |
| } |
| } |
| } |
| |
| void ConnectivityManagerImpl::_SetWiFiAPIdleTimeout(System::Clock::Timeout val) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| mWiFiAPIdleTimeout = val; |
| DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL); |
| } |
| #endif /* CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP */ |
| |
| /**************************************************************************** |
| * ConnectivityManager Private Methods |
| ****************************************************************************/ |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION |
| void ConnectivityManagerImpl::DriveStationState() |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| int32_t status; |
| bool stationConnected; |
| |
| // Refresh the current station mode. |
| GetWiFiStationMode(); |
| |
| // If the station interface is NOT under application control... |
| if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled) |
| { |
| if (mWiFiStationMode != kWiFiStationMode_Enabled) |
| { |
| ChipLogProgress(DeviceLayer, "WiFi station mode set"); |
| mWiFiStationState = kWiFiStationState_NotConnected; |
| SetFlogicNextMode(FILOGIC_WIFI_OPMODE_STA); |
| return; |
| } |
| } |
| |
| stationConnected = filogic_wifi_sta_get_link_status_sync(mFilogicCtx); |
| |
| // If the station interface is currently connected ... |
| if (stationConnected) |
| { |
| // Advance the station state to Connected if it was previously NotConnected or |
| // a previously initiated connect attempt succeeded. |
| if (mWiFiStationState == kWiFiStationState_NotConnected || mWiFiStationState == kWiFiStationState_Connecting_Succeeded) |
| { |
| ChangeWiFiStationState(kWiFiStationState_Connected); |
| ChipLogProgress(DeviceLayer, "WiFi station interface connected"); |
| mLastStationConnectFailTime = System::Clock::kZero; |
| OnStationConnected(); |
| } |
| |
| // If the WiFi station interface is no longer enabled, or no longer provisioned, |
| // disconnect the station from the AP, unless the WiFi station mode is currently |
| // under application control. |
| if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled && |
| (mWiFiStationMode != kWiFiStationMode_Enabled || !IsWiFiStationProvisioned())) |
| { |
| ChipLogProgress(DeviceLayer, "Disconnecting WiFi station interface"); |
| |
| status = wifi_connection_disconnect_ap(); |
| if (status < 0) |
| { |
| ChipLogError(DeviceLayer, "WiFi disconnect : FAIL: %ld", status); |
| } |
| |
| ChangeWiFiStationState(kWiFiStationState_Disconnecting); |
| } |
| } |
| // Otherwise the station interface is NOT connected to an AP, so... |
| else |
| { |
| System::Clock::Timestamp now = System::SystemClock().GetMonotonicTimestamp(); |
| |
| // Advance the station state to NotConnected if it was previously Connected or Disconnecting, |
| // or if a previous initiated connect attempt failed. |
| if (mWiFiStationState == kWiFiStationState_Connected || mWiFiStationState == kWiFiStationState_Disconnecting || |
| mWiFiStationState == kWiFiStationState_Connecting_Failed) |
| { |
| WiFiStationState prevState = mWiFiStationState; |
| ChangeWiFiStationState(kWiFiStationState_NotConnected); |
| if (prevState != kWiFiStationState_Connecting_Failed) |
| { |
| ChipLogProgress(DeviceLayer, "WiFi station interface disconnected"); |
| mLastStationConnectFailTime = System::Clock::kZero; |
| OnStationDisconnected(); |
| } |
| else |
| { |
| mLastStationConnectFailTime = now; |
| } |
| } |
| |
| // If the WiFi station interface is now enabled and provisioned (and by implication, |
| // not presently under application control), AND the system is not in the process of |
| // scanning, then... |
| if (mWiFiStationMode == kWiFiStationMode_Enabled && IsWiFiStationProvisioned()) |
| { |
| // Initiate a connection to the AP if we haven't done so before, or if enough |
| // time has passed since the last attempt. |
| if (mLastStationConnectFailTime == System::Clock::kZero || |
| now >= mLastStationConnectFailTime + mWiFiStationReconnectInterval) |
| { |
| if (mWiFiStationState != kWiFiStationState_Connecting) |
| { |
| ChipLogProgress(DeviceLayer, "Attempting to connect WiFi"); |
| |
| status = wifi_config_reload_setting(); |
| |
| if (status < 0) |
| { |
| ChipLogError(DeviceLayer, "WiFi start connect : FAIL %ld", status); |
| goto exit; |
| } |
| |
| ChangeWiFiStationState(kWiFiStationState_Connecting); |
| } |
| } |
| // Otherwise arrange another connection attempt at a suitable point in the future. |
| else |
| { |
| System::Clock::Timestamp timeToNextConnect = (mLastStationConnectFailTime + mWiFiStationReconnectInterval) - now; |
| |
| ChipLogProgress(DeviceLayer, "Next WiFi station reconnect in %" PRIu32 " ms", |
| System::Clock::Milliseconds32(timeToNextConnect).count()); |
| |
| ReturnOnFailure(DeviceLayer::SystemLayer().StartTimer(timeToNextConnect, DriveStationState, NULL)); |
| } |
| } |
| } |
| |
| exit: |
| |
| ChipLogProgress(DeviceLayer, "Done driving station state, nothing else to do..."); |
| } |
| |
| void ConnectivityManagerImpl::OnStationConnected() |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| ChipDeviceEvent event; |
| |
| NetworkCommissioning::GenioWiFiDriver::GetInstance().OnConnectWiFiNetwork(); |
| |
| // Alert other components of the new state. |
| event.Type = DeviceEventType::kWiFiConnectivityChange; |
| event.WiFiConnectivityChange.Result = kConnectivity_Established; |
| (void) PlatformMgr().PostEvent(&event); |
| |
| UpdateInternetConnectivityState(FALSE, FALSE, NULL); |
| } |
| |
| void ConnectivityManagerImpl::OnStationDisconnected() |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| // TODO Invoke WARM to perform actions that occur when the WiFi station interface goes down. |
| |
| // Alert other components of the new state. |
| ChipDeviceEvent event; |
| event.Type = DeviceEventType::kWiFiConnectivityChange; |
| event.WiFiConnectivityChange.Result = kConnectivity_Lost; |
| (void) PlatformMgr().PostEvent(&event); |
| |
| UpdateInternetConnectivityState(FALSE, FALSE, NULL); |
| } |
| |
| void ConnectivityManagerImpl::DriveStationState(::chip::System::Layer * aLayer, void * aAppState) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| sInstance.DriveStationState(); |
| } |
| |
| void ConnectivityManagerImpl::ChangeWiFiStationState(WiFiStationState newState) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| if (mWiFiStationState != newState) |
| { |
| ChipLogProgress(DeviceLayer, "WiFi station state change: %s -> %s", WiFiStationStateToStr(mWiFiStationState), |
| WiFiStationStateToStr(newState)); |
| mWiFiStationState = newState; |
| } |
| } |
| |
| void ConnectivityManagerImpl::UpdateInternetConnectivityState(bool haveIPv4Conn, bool haveIPv6Conn, const uint8_t * ipAddr) |
| { |
| ChipLogProgress(DeviceLayer, "%s", __func__); |
| |
| bool hadIPv4Conn = mFlags.Has(ConnectivityFlags::kHaveIPv4InternetConnectivity); |
| bool hadIPv6Conn = mFlags.Has(ConnectivityFlags::kHaveIPv6InternetConnectivity); |
| |
| ConnectivityChange connV4Change = GetConnectivityChange(hadIPv4Conn, haveIPv4Conn); |
| ConnectivityChange connV6Change = GetConnectivityChange(hadIPv6Conn, haveIPv6Conn); |
| |
| IPAddress addr; |
| |
| // If the WiFi station is currently in the connected state... |
| if (mWiFiStationState == kWiFiStationState_Connected) |
| { |
| IPAddress::FromString((char *) ipAddr, addr); |
| } |
| |
| // If the internet connectivity state has changed... |
| if (connV4Change != kConnectivity_NoChange) |
| { |
| // Update the current state. |
| mFlags.Set(ConnectivityFlags::kHaveIPv4InternetConnectivity, haveIPv4Conn); |
| |
| // Alert other components of the state change. |
| ChipDeviceEvent event; |
| event.Type = DeviceEventType::kInternetConnectivityChange; |
| event.InternetConnectivityChange.IPv4 = connV4Change; |
| event.InternetConnectivityChange.IPv6 = kConnectivity_NoChange; |
| event.InternetConnectivityChange.ipAddress = addr; |
| |
| (void) PlatformMgr().PostEvent(&event); |
| |
| ChipLogProgress(DeviceLayer, "%s Internet connectivity %s", "IPv4", (haveIPv4Conn) ? "ESTABLISHED" : "LOST"); |
| } |
| |
| // If the internet connectivity state has changed... |
| if (connV6Change != kConnectivity_NoChange) |
| { |
| // Update the current state. |
| mFlags.Set(ConnectivityFlags::kHaveIPv6InternetConnectivity, haveIPv6Conn); |
| |
| // Alert other components of the state change. |
| ChipDeviceEvent event; |
| event.Type = DeviceEventType::kInternetConnectivityChange; |
| event.InternetConnectivityChange.IPv4 = kConnectivity_NoChange; |
| event.InternetConnectivityChange.IPv6 = connV6Change; |
| event.InternetConnectivityChange.ipAddress = addr; |
| |
| (void) PlatformMgr().PostEvent(&event); |
| |
| ChipLogProgress(DeviceLayer, "%s Internet connectivity %s", "IPv6", (haveIPv6Conn) ? "ESTABLISHED" : "LOST"); |
| } |
| } |
| #endif |
| |
| } // namespace DeviceLayer |
| } // namespace chip |