From b690fb822e12e249ca98b9c4f73130c20c764c8f Mon Sep 17 00:00:00 2001 From: chenpaul Date: Tue, 16 Mar 2021 22:49:18 +0800 Subject: [PATCH 1/2] Uprev IWifiEventCallback.hal to 1.5 Bug: 178126071 Test: atest VtsHalWifiV1_5TargetTest wifi basic function is workable Change-Id: I5f1897b6d4190d80eaf25eccea04ccfdbe4884c7 --- wifi/1.5/Android.bp | 1 + wifi/1.5/IWifi.hal | 21 ++++++++++++++++++++- wifi/1.5/IWifiEventCallback.hal | 21 +++++++++++++++++++++ wifi/1.5/default/wifi.cpp | 18 ++++++++++++++++-- wifi/1.5/default/wifi.h | 11 ++++++++--- 5 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 wifi/1.5/IWifiEventCallback.hal diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp index 7c04c6967a..0887c6b5c1 100644 --- a/wifi/1.5/Android.bp +++ b/wifi/1.5/Android.bp @@ -20,6 +20,7 @@ hidl_interface { "IWifiNanIface.hal", "IWifiNanIfaceEventCallback.hal", "IWifiStaIface.hal", + "IWifiEventCallback.hal", ], interfaces: [ "android.hardware.wifi@1.0", diff --git a/wifi/1.5/IWifi.hal b/wifi/1.5/IWifi.hal index 66d0a9c2f9..28b808ed32 100644 --- a/wifi/1.5/IWifi.hal +++ b/wifi/1.5/IWifi.hal @@ -17,6 +17,8 @@ package android.hardware.wifi@1.5; import @1.4::IWifi; +import IWifiEventCallback; +import @1.0::WifiStatus; /** * This is the root of the HAL module and is the interface returned when @@ -24,4 +26,21 @@ import @1.4::IWifi; * module loaded in the system. * IWifi.getChip() must return @1.5::IWifiChip */ -interface IWifi extends @1.4::IWifi {}; +interface IWifi extends @1.4::IWifi { + /** + * Requests notifications of significant events for the HAL. Multiple calls to + * this must register multiple callbacks each of which must receive all + * events. |IWifiEventCallback| object registration must be independent of the + * state of the rest of the HAL and must persist though stops/starts. These + * objects must be deleted when the corresponding client process is dead. + * + * @param callback An instance of the |IWifiEventCallback| HIDL interface + * object. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.UNKNOWN| + */ + registerEventCallback_1_5(IWifiEventCallback callback) + generates (WifiStatus status); +}; diff --git a/wifi/1.5/IWifiEventCallback.hal b/wifi/1.5/IWifiEventCallback.hal new file mode 100644 index 0000000000..17dce39950 --- /dev/null +++ b/wifi/1.5/IWifiEventCallback.hal @@ -0,0 +1,21 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * 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. + */ + +package android.hardware.wifi@1.5; + +import @1.0::IWifiEventCallback; + +interface IWifiEventCallback extends @1.0::IWifiEventCallback {}; diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.5/default/wifi.cpp index da98db8296..b4037e9907 100644 --- a/wifi/1.5/default/wifi.cpp +++ b/wifi/1.5/default/wifi.cpp @@ -50,13 +50,21 @@ bool Wifi::isValid() { } Return Wifi::registerEventCallback( - const sp& event_callback, + const sp& event_callback, registerEventCallback_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::registerEventCallbackInternal, hidl_status_cb, event_callback); } +Return Wifi::registerEventCallback_1_5( + const sp& event_callback, + registerEventCallback_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, + &Wifi::registerEventCallbackInternal_1_5, + hidl_status_cb, event_callback); +} + Return Wifi::isStarted() { return run_state_ != RunState::STOPPED; } Return Wifi::start(start_cb hidl_status_cb) { @@ -95,7 +103,13 @@ Return Wifi::debug(const hidl_handle& handle, } WifiStatus Wifi::registerEventCallbackInternal( - const sp& event_callback) { + const sp& event_callback __unused) { + // Deprecated support for this callback. + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus Wifi::registerEventCallbackInternal_1_5( + const sp& event_callback) { if (!event_cb_handler_.addCallback(event_callback)) { return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } diff --git a/wifi/1.5/default/wifi.h b/wifi/1.5/default/wifi.h index 825c0bc182..840bdfd927 100644 --- a/wifi/1.5/default/wifi.h +++ b/wifi/1.5/default/wifi.h @@ -52,8 +52,11 @@ class Wifi : public V1_5::IWifi { // HIDL methods exposed. Return registerEventCallback( - const sp& event_callback, + const sp& event_callback, registerEventCallback_cb hidl_status_cb) override; + Return registerEventCallback_1_5( + const sp& event_callback, + registerEventCallback_1_5_cb hidl_status_cb) override; Return isStarted() override; Return start(start_cb hidl_status_cb) override; Return stop(stop_cb hidl_status_cb) override; @@ -67,7 +70,9 @@ class Wifi : public V1_5::IWifi { // Corresponding worker functions for the HIDL methods. WifiStatus registerEventCallbackInternal( - const sp& event_callback); + const sp& event_callback __unused); + WifiStatus registerEventCallbackInternal_1_5( + const sp& event_callback); WifiStatus startInternal(); WifiStatus stopInternal(std::unique_lock* lock); std::pair> getChipIdsInternal(); @@ -87,7 +92,7 @@ class Wifi : public V1_5::IWifi { std::shared_ptr feature_flags_; RunState run_state_; std::vector> chips_; - hidl_callback_util::HidlCallbackHandler + hidl_callback_util::HidlCallbackHandler event_cb_handler_; DISALLOW_COPY_AND_ASSIGN(Wifi); From c6f570378bd657db956366f406ce7291b06164e2 Mon Sep 17 00:00:00 2001 From: chenpaul Date: Fri, 5 Mar 2021 17:06:50 +0800 Subject: [PATCH 2/2] Add API "startSubsystemRestart" and callback function In order to trigger subsystem restart to reload wlan firmware, this change adds an API for framework and vendor HAL. Meanwhile, create new callback function for subsystem restart instead of general callback "onFailure()". Bug: 178126071 Test: vendor HAL can received API call subsystem restart will callback "onSubsystemRestart()" Change-Id: If3dc84049a9171677ad281c9bcc67a44dc722bdb --- wifi/1.5/IWifiChip.hal | 21 +++++++++++++++++++++ wifi/1.5/IWifiEventCallback.hal | 9 ++++++++- wifi/1.5/default/wifi.cpp | 2 +- wifi/1.5/default/wifi_chip.cpp | 12 ++++++++++++ wifi/1.5/default/wifi_chip.h | 3 +++ wifi/1.5/default/wifi_legacy_hal.cpp | 4 ++++ wifi/1.5/default/wifi_legacy_hal.h | 2 ++ wifi/1.5/default/wifi_legacy_hal_stubs.cpp | 1 + 8 files changed, 52 insertions(+), 2 deletions(-) diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index 5a3e2883d5..e199850c1a 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -303,4 +303,25 @@ interface IWifiChip extends @1.4::IWifiChip { getUsableChannels(WifiBand band, bitfield ifaceModeMask, bitfield filterMask) generates (WifiStatus status, vec channels); + + /** + * Trigger subsystem restart + * + * If the framework detects a problem (e.g. connection failure), + * it must call this function to attempt recovery. + * + * When the wifi HAL receiveds triggerSubsystemRestart(), it must restart + * the wlan subsystem, especially the wlan firmware. + * + * Regarding the callback function for subsystem restart, refer to documentation of + * |IWifiEventCallback.onSubsystemRestart| for details. + * + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, + * |WifiStatusCode.ERROR_NOT_AVAILABLE|, + * |WifiStatusCode.ERROR_UNKNOWN| + */ + triggerSubsystemRestart() generates (WifiStatus status); }; diff --git a/wifi/1.5/IWifiEventCallback.hal b/wifi/1.5/IWifiEventCallback.hal index 17dce39950..ff276306fd 100644 --- a/wifi/1.5/IWifiEventCallback.hal +++ b/wifi/1.5/IWifiEventCallback.hal @@ -17,5 +17,12 @@ package android.hardware.wifi@1.5; import @1.0::IWifiEventCallback; +import @1.0::WifiStatus; -interface IWifiEventCallback extends @1.0::IWifiEventCallback {}; +interface IWifiEventCallback extends @1.0::IWifiEventCallback { + /** + * Must be called when the Wi-Fi subsystem restart completes. + * Once this event is received, framework must fully reset the Wi-Fi stack state. + */ + oneway onSubsystemRestart(WifiStatus status); +}; diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.5/default/wifi.cpp index b4037e9907..b9f20a4615 100644 --- a/wifi/1.5/default/wifi.cpp +++ b/wifi/1.5/default/wifi.cpp @@ -131,7 +131,7 @@ WifiStatus Wifi::startInternal() { WifiStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error); for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onFailure(wifi_status).isOk()) { + if (!callback->onSubsystemRestart(wifi_status).isOk()) { LOG(ERROR) << "Failed to invoke onFailure callback"; } } diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 0499f456c1..961f9da4c2 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -747,6 +747,13 @@ Return WifiChip::getUsableChannels( ifaceModeMask, filterMask); } +Return WifiChip::triggerSubsystemRestart( + triggerSubsystemRestart_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::triggerSubsystemRestartInternal, + hidl_status_cb); +} + void WifiChip::invalidateAndRemoveAllIfaces() { invalidateAndClearBridgedApAll(); invalidateAndClearAll(ap_ifaces_); @@ -1522,6 +1529,11 @@ WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask, return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels}; } +WifiStatus WifiChip::triggerSubsystemRestartInternal() { + auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart(); + return createWifiStatusFromLegacyError(legacy_status); +} + WifiStatus WifiChip::handleChipConfiguration( /* NONNULL */ std::unique_lock* lock, ChipModeId mode_id) { diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index 92d639f8b5..bd40ead35a 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -184,6 +184,8 @@ class WifiChip : public V1_5::IWifiChip { WifiBand band, hidl_bitfield ifaceModeMask, hidl_bitfield filterMask, getUsableChannels_cb _hidl_cb) override; + Return triggerSubsystemRestart( + triggerSubsystemRestart_cb hidl_status_cb) override; private: void invalidateAndRemoveAllIfaces(); @@ -303,6 +305,7 @@ class WifiChip : public V1_5::IWifiChip { void invalidateAndClearBridgedApAll(); void invalidateAndClearBridgedAp(const std::string& br_name); bool findUsingNameFromBridgedApInstances(const std::string& name); + WifiStatus triggerSubsystemRestartInternal(); ChipId chip_id_; std::weak_ptr legacy_hal_; diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 45ad84b8c1..848fbd6114 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -1676,6 +1676,10 @@ WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask, return {status, std::move(channels)}; } +wifi_error WifiLegacyHal::triggerSubsystemRestart() { + return global_func_table_.wifi_trigger_subsystem_restart(); +} + void WifiLegacyHal::invalidate() { global_handle_ = nullptr; iface_name_to_handle_.clear(); diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 8ebc66aaa6..2bb7631efa 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -716,6 +716,8 @@ class WifiLegacyHal { std::pair> getUsableChannels( uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask); + wifi_error triggerSubsystemRestart(); + private: // Retrieve interface handles for all the available interfaces. wifi_error retrieveIfaceHandles(); diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp index 6212960d7a..dd860d6920 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp @@ -160,6 +160,7 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_twt_clear_stats); populateStubFor(&hal_fn->wifi_set_dtim_config); populateStubFor(&hal_fn->wifi_get_usable_channels); + populateStubFor(&hal_fn->wifi_trigger_subsystem_restart); return true; } } // namespace legacy_hal