Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2134bf71 authored by Ahmed ElArabawy's avatar Ahmed ElArabawy
Browse files

Wifi: Handle subsystem restart notification

This commit adds the logic to handle a notification of a wifi subsystem
restart to trigger the callback to the framework for self recovery.

Bug: 159367026
Test: force a firmware restart and make sure Wifi is recovered.
Change-Id: If6b5863d1d7473917088ec5be1910fa0db5dd6ae
parent 218396c1
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -263,6 +263,8 @@ class WifiChipTest : public Test {
        return success;
    }

    static void subsystemRestartHandler(const std::string& /*error*/) {}

    sp<WifiChip> chip_;
    ChipId chip_id_ = kFakeChipId;
    std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
@@ -278,8 +280,9 @@ class WifiChipTest : public Test {

   public:
    void SetUp() override {
        chip_ = new WifiChip(chip_id_, legacy_hal_, mode_controller_,
                             iface_util_, feature_flags_);
        chip_ =
            new WifiChip(chip_id_, legacy_hal_, mode_controller_, iface_util_,
                         feature_flags_, subsystemRestartHandler);

        EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_))
            .WillRepeatedly(testing::Return(true));
+16 −2
Original line number Diff line number Diff line
@@ -107,9 +107,23 @@ WifiStatus Wifi::startInternal() {
    }
    WifiStatus wifi_status = initializeModeControllerAndLegacyHal();
    if (wifi_status.code == WifiStatusCode::SUCCESS) {
        // Register the callback for subsystem restart
        const auto& on_subsystem_restart_callback =
            [this](const std::string& error) {
                WifiStatus wifi_status =
                    createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
                for (const auto& callback : event_cb_handler_.getCallbacks()) {
                    if (!callback->onFailure(wifi_status).isOk()) {
                        LOG(ERROR) << "Failed to invoke onFailure callback";
                    }
                }
            };

        // Create the chip instance once the HAL is started.
        chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_,
                             iface_util_, feature_flags_);
        // Need to consider the case of multiple chips TODO(156998862)
        chip_ =
            new WifiChip(kChipId, legacy_hal_, mode_controller_, iface_util_,
                         feature_flags_, on_subsystem_restart_callback);
        run_state_ = RunState::STARTED;
        for (const auto& callback : event_cb_handler_.getCallbacks()) {
            if (!callback->onStart().isOk()) {
+8 −2
Original line number Diff line number Diff line
@@ -335,7 +335,8 @@ WifiChip::WifiChip(
    ChipId chip_id, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
    const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
    const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util,
    const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags)
    const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
    const std::function<void(const std::string&)>& handler)
    : chip_id_(chip_id),
      legacy_hal_(legacy_hal),
      mode_controller_(mode_controller),
@@ -343,7 +344,8 @@ WifiChip::WifiChip(
      is_valid_(true),
      current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
      modes_(feature_flags.lock()->getChipModes()),
      debug_ring_buffer_cb_registered_(false) {
      debug_ring_buffer_cb_registered_(false),
      subsystemCallbackHandler_(handler) {
    setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
}

@@ -737,6 +739,10 @@ WifiStatus WifiChip::configureChipInternal(
    current_mode_id_ = mode_id;
    LOG(INFO) << "Configured chip in mode " << mode_id;
    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());

    legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(
        subsystemCallbackHandler_);

    return status;
}

+10 −7
Original line number Diff line number Diff line
@@ -50,13 +50,14 @@ using namespace android::hardware::wifi::V1_0;
 */
class WifiChip : public V1_4::IWifiChip {
   public:
    WifiChip(
        ChipId chip_id,
    WifiChip(ChipId chip_id,
             const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
             const std::weak_ptr<mode_controller::WifiModeController>
                 mode_controller,
             const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util,
        const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags);
             const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
             const std::function<void(const std::string&)>&
                 subsystemCallbackHandler);
    // HIDL does not provide a built-in mechanism to let the server invalidate
    // a HIDL interface object after creation. If any client process holds onto
    // a reference to the object in their context, any method calls on that
@@ -282,6 +283,8 @@ class WifiChip : public V1_4::IWifiChip {
    hidl_callback_util::HidlCallbackHandler<IWifiChipEventCallback>
        event_cb_handler_;

    const std::function<void(const std::string&)> subsystemCallbackHandler_;

    DISALLOW_COPY_AND_ASSIGN(WifiChip);
};

+27 −0
Original line number Diff line number Diff line
@@ -162,6 +162,15 @@ void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs,
    }
}

// Callback to be invoked to report subsystem restart
std::function<void(const char*)> on_subsystem_restart_internal_callback;
void onAsyncSubsystemRestart(const char* error) {
    const auto lock = hidl_sync_util::acquireGlobalLock();
    if (on_subsystem_restart_internal_callback) {
        on_subsystem_restart_internal_callback(error);
    }
}

// Callback to be invoked for rtt results results.
std::function<void(wifi_request_id, unsigned num_results,
                   wifi_rtt_result* rtt_results[])>
@@ -1049,6 +1058,23 @@ wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler(
    return status;
}

wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler(
    const on_subsystem_restart_callback& on_restart_callback) {
    if (on_subsystem_restart_internal_callback) {
        return WIFI_ERROR_NOT_AVAILABLE;
    }
    on_subsystem_restart_internal_callback =
        [on_restart_callback](const char* error) {
            on_restart_callback(error);
        };
    wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler(
        global_handle_, {onAsyncSubsystemRestart});
    if (status != WIFI_SUCCESS) {
        on_subsystem_restart_internal_callback = nullptr;
    }
    return status;
}

wifi_error WifiLegacyHal::startRttRangeRequest(
    const std::string& iface_name, wifi_request_id id,
    const std::vector<wifi_rtt_config>& rtt_configs,
@@ -1471,6 +1497,7 @@ void WifiLegacyHal::invalidate() {
    on_ring_buffer_data_internal_callback = nullptr;
    on_error_alert_internal_callback = nullptr;
    on_radio_mode_change_internal_callback = nullptr;
    on_subsystem_restart_internal_callback = nullptr;
    on_rtt_results_internal_callback = nullptr;
    on_nan_notify_response_user_callback = nullptr;
    on_nan_event_publish_terminated_user_callback = nullptr;
Loading