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