1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "wifi.h" 17#include <hdf_base.h> 18#include <hdf_log.h> 19#include "wifi_hal.h" 20#include "hdi_sync_util.h" 21#include "iproxy_broker.h" 22 23namespace OHOS { 24namespace HDI { 25namespace Wlan { 26namespace Chip { 27namespace V1_0 { 28#ifdef FEATURE_ANCO_WIFI 29const int CHIP_ID_STA = 1; 30const int CHIP_ID_P2P = 2; 31const int CHIP_ID_AP = 3; 32#endif 33 34static constexpr int32_t K_PRIMARY_CHIP_ID = 0; 35static std::mutex g_chipMutex; 36 37extern "C" IChipController *ChipControllerImplGetInstance(void) 38{ 39 static IChipController *gWifiService = NULL; 40 std::unique_lock<std::mutex> lock(g_chipMutex); 41 if (gWifiService == NULL) { 42 gWifiService = new (std::nothrow) Wifi(); 43 } 44 return gWifiService; 45} 46 47Wifi::Wifi() 48 :ifaceTool_(std::make_shared<IfaceTool>()), 49 vendorHalList_(std::make_shared<WifiVendorHalList>(ifaceTool_)), 50 runState_(RunState::STOPPED) { 51 remoteDeathRecipient_ = 52 new RemoteDeathRecipient(std::bind(&Wifi::OnRemoteDied, this, std::placeholders::_1)); 53} 54 55Wifi::~Wifi() 56{ 57 for (const auto& callback : cbHandler_.GetCallbacks()) { 58 if (callback != nullptr) { 59 RemoveWifiDeathRecipient(callback); 60 } 61 } 62 cbHandler_.Invalidate(); 63} 64 65int32_t Wifi::RegisterWifiEventCallback(const sptr<IChipControllerCallback>& eventCallback) 66{ 67 if (AddWifiDeathRecipient(eventCallback) != HDF_SUCCESS) { 68 return HDF_FAILURE; 69 } 70 71 if (!cbHandler_.AddCallback(eventCallback)) { 72 return HDF_FAILURE; 73 } 74 return HDF_SUCCESS; 75} 76 77int32_t Wifi::IsInit(bool& inited) 78{ 79 inited = runState_ != RunState::STOPPED; 80 return HDF_SUCCESS; 81} 82 83int32_t Wifi::Init() 84{ 85 HDF_LOGI("Wifi HAL start enter"); 86 if (runState_ == RunState::STARTED) { 87 return HDF_SUCCESS; 88 } else if (runState_ == RunState::STOPPING) { 89 return HDF_FAILURE; 90 } 91 ErrorCode res = InitializVendorHal(); 92 if (res == ErrorCode::SUCCESS) { 93 const auto& onVendorHalRestartCallback = 94 [this](const std::string& error) { 95 ErrorCode res = ErrorCode::UNKNOWN; 96 for (const auto& callback : cbHandler_.GetCallbacks()) { 97 callback->OnVendorHalRestart(res); 98 } 99 }; 100 101 int32_t chipId = K_PRIMARY_CHIP_ID; 102 for (auto& hal : vendorHals_) { 103 chips_.push_back(new WifiChip( 104 chipId, chipId == K_PRIMARY_CHIP_ID, hal, 105 std::make_shared<IfaceUtil>(ifaceTool_), 106 onVendorHalRestartCallback)); 107 chipId++; 108 } 109 runState_ = RunState::STARTED; 110 HDF_LOGI("Wifi HAL started"); 111 return HDF_SUCCESS; 112 } else { 113 HDF_LOGE("Wifi HAL start failed"); 114 return HDF_FAILURE; 115 } 116} 117 118int32_t Wifi::Release() 119{ 120 if (runState_ == RunState::STOPPED) { 121 return HDF_SUCCESS; 122 } else if (runState_ == RunState::STOPPING) { 123 return HDF_SUCCESS; 124 } 125 for (auto& chip : chips_) { 126 if (chip) { 127 chip->Invalidate(); 128 } 129 } 130 chips_.clear(); 131 auto lock = AcquireGlobalLock(); 132 ErrorCode res = StopVendorHal(&lock); 133 if (res == ErrorCode::SUCCESS) { 134 return HDF_SUCCESS; 135 HDF_LOGI("Wifi HAL stopped"); 136 } else { 137 return HDF_FAILURE; 138 HDF_LOGE("Wifi HAL stop failed"); 139 } 140} 141 142int32_t Wifi::GetAvailableChips(std::vector<uint32_t>& chipIds) 143{ 144 for (auto& chip : chips_) { 145 uint32_t chipId = GetChipIdFromWifiChip(chip); 146 if (chipId != UINT32_MAX) chipIds.emplace_back(chipId); 147 } 148#ifdef FEATURE_ANCO_WIFI 149 if (chipIds.empty()) { 150 chipIds.emplace_back(CHIP_ID_STA); 151 chipIds.emplace_back(CHIP_ID_P2P); 152 chipIds.emplace_back(CHIP_ID_AP); 153 } 154#endif 155 return HDF_SUCCESS; 156} 157 158int32_t Wifi::GetChipService(uint32_t chipId, sptr<IConcreteChip>& chip) 159{ 160 for (auto& ch : chips_) { 161 uint32_t cand_id = GetChipIdFromWifiChip(ch); 162 if ((cand_id != UINT32_MAX) && (cand_id == chipId)) { 163 chip = ch; 164 return HDF_SUCCESS; 165 } 166 } 167 chip = nullptr; 168 return HDF_FAILURE; 169} 170 171ErrorCode Wifi::StopVendorHal(std::unique_lock<std::recursive_mutex>* lock) 172{ 173 WifiError legacyStatus = HAL_SUCCESS; 174 int index = 0; 175 ErrorCode res; 176 177 runState_ = RunState::STOPPING; 178 for (auto& hal : vendorHals_) { 179 WifiError tmp = hal->Stop(lock, [&]() {}); 180 if (tmp != HAL_SUCCESS) { 181 HDF_LOGE("Failed to stop vendor hal index: %{public}d, error %{public}d", index, tmp); 182 legacyStatus = tmp; 183 } 184 index++; 185 } 186 runState_ = RunState::STOPPED; 187 188 if (legacyStatus != HAL_SUCCESS) { 189 HDF_LOGE("One or more vendor hals failed to stop error is %{public}d", legacyStatus); 190 res = ErrorCode::UNKNOWN; 191 return res; 192 } 193 res = ErrorCode::SUCCESS; 194 return res; 195} 196 197ErrorCode Wifi::InitializVendorHal() 198{ 199 ErrorCode res; 200 201 vendorHals_ = vendorHalList_->GetHals(); 202 if (vendorHals_.empty()) { 203 res = ErrorCode::UNKNOWN; 204 return res; 205 } 206 int index = 0; 207 for (auto& hal : vendorHals_) { 208 WifiError legacyStatus = hal->Initialize(); 209 if (legacyStatus != HAL_SUCCESS) { 210 res = ErrorCode::UNKNOWN; 211 return res; 212 } 213 index++; 214 } 215 216 res = ErrorCode::SUCCESS; 217 return res; 218} 219 220uint32_t Wifi::GetChipIdFromWifiChip(sptr <WifiChip>& chip) 221{ 222 uint32_t chipId = UINT32_MAX; 223 int32_t id; 224 225 if (chip) { 226 chip->GetChipId(id); 227 chipId = static_cast<uint32_t>(id); 228 } 229 return chipId; 230} 231 232void Wifi::OnRemoteDied(const wptr<IRemoteObject> &object) 233{ 234 HDF_LOGI("chip service OnRemoteDied"); 235 runState_ = RunState::STOPPING; 236 for (auto& chip : chips_) { 237 if (chip) { 238 chip->Invalidate(); 239 } 240 } 241 chips_.clear(); 242 auto lock = AcquireGlobalLock(); 243 StopVendorHal(&lock); 244 runState_ = RunState::STOPPED; 245} 246 247int32_t Wifi::AddWifiDeathRecipient(const sptr<IChipControllerCallback>& eventCallback) 248{ 249 HDF_LOGI("AddWifiDeathRecipient"); 250 const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IChipControllerCallback>(eventCallback); 251 bool result = remote->AddDeathRecipient(remoteDeathRecipient_); 252 if (!result) { 253 HDF_LOGE("Wifi AddDeathRecipient fail"); 254 return HDF_FAILURE; 255 } 256 return HDF_SUCCESS; 257} 258 259int32_t Wifi::RemoveWifiDeathRecipient(const sptr<IChipControllerCallback>& eventCallback) 260{ 261 HDF_LOGI("RemoveWifiDeathRecipient"); 262 const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IChipControllerCallback>(eventCallback); 263 bool result = remote->RemoveDeathRecipient(remoteDeathRecipient_); 264 if (!result) { 265 HDF_LOGE("Wifi RemoveDeathRecipient fail"); 266 return HDF_FAILURE; 267 } 268 return HDF_SUCCESS; 269} 270 271} // namespace V1_0 272} // namespace Chip 273} // namespace Wlan 274} // namespace HDI 275} // namespace OHOS