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 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 49 bool Wifi::isValid() { 50 // This object is always valid. 51 return true; 52 } 53 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 62 Return<bool> Wifi::isStarted() { return run_state_ != RunState::STOPPED; } 63 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 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 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 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 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 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 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 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 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 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 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 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