1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <android-base/logging.h>
18
19 #include "hidl_return_util.h"
20 #include "wifi.h"
21 #include "wifi_status_util.h"
22
23 namespace {
24 // Chip ID to use for the only supported chip.
25 static constexpr android::hardware::wifi::V1_0::ChipId kChipId = 0;
26 } // namespace
27
28 namespace android {
29 namespace hardware {
30 namespace wifi {
31 namespace V1_3 {
32 namespace implementation {
33 using hidl_return_util::validateAndCall;
34 using hidl_return_util::validateAndCallWithLock;
35
Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,const std::shared_ptr<mode_controller::WifiModeController> mode_controller,const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)36 Wifi::Wifi(
37 const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
38 const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
39 const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
40 const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
41 const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
42 : iface_tool_(iface_tool),
43 legacy_hal_(legacy_hal),
44 mode_controller_(mode_controller),
45 iface_util_(iface_util),
46 feature_flags_(feature_flags),
47 run_state_(RunState::STOPPED) {}
48
isValid()49 bool Wifi::isValid() {
50 // This object is always valid.
51 return true;
52 }
53
registerEventCallback(const sp<IWifiEventCallback> & event_callback,registerEventCallback_cb hidl_status_cb)54 Return<void> Wifi::registerEventCallback(
55 const sp<IWifiEventCallback>& event_callback,
56 registerEventCallback_cb hidl_status_cb) {
57 return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
58 &Wifi::registerEventCallbackInternal, hidl_status_cb,
59 event_callback);
60 }
61
isStarted()62 Return<bool> Wifi::isStarted() { return run_state_ != RunState::STOPPED; }
63
start(start_cb hidl_status_cb)64 Return<void> Wifi::start(start_cb hidl_status_cb) {
65 return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
66 &Wifi::startInternal, hidl_status_cb);
67 }
68
stop(stop_cb hidl_status_cb)69 Return<void> Wifi::stop(stop_cb hidl_status_cb) {
70 return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN,
71 &Wifi::stopInternal, hidl_status_cb);
72 }
73
getChipIds(getChipIds_cb hidl_status_cb)74 Return<void> Wifi::getChipIds(getChipIds_cb hidl_status_cb) {
75 return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
76 &Wifi::getChipIdsInternal, hidl_status_cb);
77 }
78
getChip(ChipId chip_id,getChip_cb hidl_status_cb)79 Return<void> Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) {
80 return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
81 &Wifi::getChipInternal, hidl_status_cb, chip_id);
82 }
83
debug(const hidl_handle & handle,const hidl_vec<hidl_string> &)84 Return<void> Wifi::debug(const hidl_handle& handle,
85 const hidl_vec<hidl_string>&) {
86 LOG(INFO) << "-----------Debug is called----------------";
87 if (!chip_.get()) {
88 return Void();
89 }
90 return chip_->debug(handle, {});
91 }
92
registerEventCallbackInternal(const sp<IWifiEventCallback> & event_callback)93 WifiStatus Wifi::registerEventCallbackInternal(
94 const sp<IWifiEventCallback>& event_callback) {
95 if (!event_cb_handler_.addCallback(event_callback)) {
96 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
97 }
98 return createWifiStatus(WifiStatusCode::SUCCESS);
99 }
100
startInternal()101 WifiStatus Wifi::startInternal() {
102 if (run_state_ == RunState::STARTED) {
103 return createWifiStatus(WifiStatusCode::SUCCESS);
104 } else if (run_state_ == RunState::STOPPING) {
105 return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
106 "HAL is stopping");
107 }
108 WifiStatus wifi_status = initializeModeControllerAndLegacyHal();
109 if (wifi_status.code == WifiStatusCode::SUCCESS) {
110 // Create the chip instance once the HAL is started.
111 chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_,
112 iface_util_, feature_flags_);
113 run_state_ = RunState::STARTED;
114 for (const auto& callback : event_cb_handler_.getCallbacks()) {
115 if (!callback->onStart().isOk()) {
116 LOG(ERROR) << "Failed to invoke onStart callback";
117 };
118 }
119 LOG(INFO) << "Wifi HAL started";
120 } else {
121 for (const auto& callback : event_cb_handler_.getCallbacks()) {
122 if (!callback->onFailure(wifi_status).isOk()) {
123 LOG(ERROR) << "Failed to invoke onFailure callback";
124 }
125 }
126 LOG(ERROR) << "Wifi HAL start failed";
127 }
128 return wifi_status;
129 }
130
stopInternal(std::unique_lock<std::recursive_mutex> * lock)131 WifiStatus Wifi::stopInternal(
132 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
133 if (run_state_ == RunState::STOPPED) {
134 return createWifiStatus(WifiStatusCode::SUCCESS);
135 } else if (run_state_ == RunState::STOPPING) {
136 return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
137 "HAL is stopping");
138 }
139 // Clear the chip object and its child objects since the HAL is now
140 // stopped.
141 if (chip_.get()) {
142 chip_->invalidate();
143 chip_.clear();
144 }
145 WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController(lock);
146 if (wifi_status.code == WifiStatusCode::SUCCESS) {
147 for (const auto& callback : event_cb_handler_.getCallbacks()) {
148 if (!callback->onStop().isOk()) {
149 LOG(ERROR) << "Failed to invoke onStop callback";
150 };
151 }
152 LOG(INFO) << "Wifi HAL stopped";
153 } else {
154 for (const auto& callback : event_cb_handler_.getCallbacks()) {
155 if (!callback->onFailure(wifi_status).isOk()) {
156 LOG(ERROR) << "Failed to invoke onFailure callback";
157 }
158 }
159 LOG(ERROR) << "Wifi HAL stop failed";
160 }
161 return wifi_status;
162 }
163
getChipIdsInternal()164 std::pair<WifiStatus, std::vector<ChipId>> Wifi::getChipIdsInternal() {
165 std::vector<ChipId> chip_ids;
166 if (chip_.get()) {
167 chip_ids.emplace_back(kChipId);
168 }
169 return {createWifiStatus(WifiStatusCode::SUCCESS), std::move(chip_ids)};
170 }
171
getChipInternal(ChipId chip_id)172 std::pair<WifiStatus, sp<IWifiChip>> Wifi::getChipInternal(ChipId chip_id) {
173 if (!chip_.get()) {
174 return {createWifiStatus(WifiStatusCode::ERROR_NOT_STARTED), nullptr};
175 }
176 if (chip_id != kChipId) {
177 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
178 }
179 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_};
180 }
181
initializeModeControllerAndLegacyHal()182 WifiStatus Wifi::initializeModeControllerAndLegacyHal() {
183 if (!mode_controller_->initialize()) {
184 LOG(ERROR) << "Failed to initialize firmware mode controller";
185 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
186 }
187 legacy_hal::wifi_error legacy_status = legacy_hal_->initialize();
188 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
189 LOG(ERROR) << "Failed to initialize legacy HAL: "
190 << legacyErrorToString(legacy_status);
191 return createWifiStatusFromLegacyError(legacy_status);
192 }
193 return createWifiStatus(WifiStatusCode::SUCCESS);
194 }
195
stopLegacyHalAndDeinitializeModeController(std::unique_lock<std::recursive_mutex> * lock)196 WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController(
197 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
198 run_state_ = RunState::STOPPING;
199 legacy_hal::wifi_error legacy_status =
200 legacy_hal_->stop(lock, [&]() { run_state_ = RunState::STOPPED; });
201 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
202 LOG(ERROR) << "Failed to stop legacy HAL: "
203 << legacyErrorToString(legacy_status);
204 return createWifiStatusFromLegacyError(legacy_status);
205 }
206 if (!mode_controller_->deinitialize()) {
207 LOG(ERROR) << "Failed to deinitialize firmware mode controller";
208 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
209 }
210 return createWifiStatus(WifiStatusCode::SUCCESS);
211 }
212 } // namespace implementation
213 } // namespace V1_3
214 } // namespace wifi
215 } // namespace hardware
216 } // namespace android
217