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
This commit is contained in:
chenpaul
2021-03-05 17:06:50 +08:00
parent b690fb822e
commit c6f570378b
8 changed files with 52 additions and 2 deletions

View File

@@ -303,4 +303,25 @@ interface IWifiChip extends @1.4::IWifiChip {
getUsableChannels(WifiBand band, bitfield<WifiIfaceMode> ifaceModeMask,
bitfield<UsableChannelFilter> filterMask)
generates (WifiStatus status, vec<WifiUsableChannel> 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);
};

View File

@@ -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);
};

View File

@@ -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";
}
}

View File

@@ -747,6 +747,13 @@ Return<void> WifiChip::getUsableChannels(
ifaceModeMask, filterMask);
}
Return<void> 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<std::recursive_mutex>* lock,
ChipModeId mode_id) {

View File

@@ -184,6 +184,8 @@ class WifiChip : public V1_5::IWifiChip {
WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask,
hidl_bitfield<UsableChannelFilter> filterMask,
getUsableChannels_cb _hidl_cb) override;
Return<void> 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::WifiLegacyHal> legacy_hal_;

View File

@@ -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();

View File

@@ -716,6 +716,8 @@ class WifiLegacyHal {
std::pair<wifi_error, std::vector<wifi_usable_channel>> 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();

View File

@@ -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