1 /*
2 * Copyright (c) 2023 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 #ifdef FEATURE_P2P_SUPPORT
17 #include "wifi_p2p_manager.h"
18 #include "wifi_manager.h"
19 #include "wifi_service_manager.h"
20 #include "wifi_config_center.h"
21 #include "wifi_logger.h"
22 #include "wifi_common_event_helper.h"
23 #include "wifi_system_timer.h"
24 #include "wifi_hisysevent.h"
25 #include "p2p_define.h"
26 #ifdef OHOS_ARCH_LITE
27 #include "wifi_internal_event_dispatcher_lite.h"
28 #else
29 #include "wifi_internal_event_dispatcher.h"
30 #include "wifi_sa_manager.h"
31 #endif
32 #ifdef HDI_CHIP_INTERFACE_SUPPORT
33 #include "hal_device_manage.h"
34 #endif
35
36 DEFINE_WIFILOG_LABEL("WifiP2pManager");
37
38 namespace OHOS {
39 namespace Wifi {
40 constexpr int32_t P2P_ENABLE_WAIT_MS = 500;
WifiP2pManager()41 WifiP2pManager::WifiP2pManager()
42 {
43 WIFI_LOGI("create WifiP2pManager");
44 InitP2pCallback();
45 }
46
GetP2pCallback(void)47 IP2pServiceCallbacks& WifiP2pManager::GetP2pCallback(void)
48 {
49 return mP2pCallback;
50 }
51
AutoStartP2pService()52 ErrCode WifiP2pManager::AutoStartP2pService()
53 {
54 WifiOprMidState p2pState = WifiConfigCenter::GetInstance().GetP2pMidState();
55 WIFI_LOGI("AutoStartP2pService, current p2p state:%{public}d", p2pState);
56 if (p2pState != WifiOprMidState::CLOSED) {
57 if (p2pState == WifiOprMidState::CLOSING) {
58 return WIFI_OPT_OPEN_FAIL_WHEN_CLOSING;
59 } else {
60 return WIFI_OPT_OPEN_SUCC_WHEN_OPENED;
61 }
62 }
63
64 #ifdef HDI_CHIP_INTERFACE_SUPPORT
65 if (ifaceName.empty() && !DelayedSingleton<HalDeviceManager>::GetInstance()->CreateP2pIface(
66 std::bind(&WifiP2pManager::IfaceDestoryCallback, this, std::placeholders::_1, std::placeholders::_2),
67 ifaceName)) {
68 WIFI_LOGE("AutoStartP2pService, create iface failed!");
69 return WIFI_OPT_FAILED;
70 }
71 WifiConfigCenter::GetInstance().SetP2pIfaceName(ifaceName);
72 #endif
73
74 if (!WifiConfigCenter::GetInstance().SetP2pMidState(p2pState, WifiOprMidState::OPENING)) {
75 WIFI_LOGE("AutoStartP2pService, set p2p mid state opening failed!");
76 return WIFI_OPT_OPEN_SUCC_WHEN_OPENED;
77 }
78
79 ErrCode ret = WIFI_OPT_FAILED;
80 do {
81 if (WifiServiceManager::GetInstance().CheckAndEnforceService(WIFI_SERVICE_P2P) < 0) {
82 WIFI_LOGE("Load %{public}s service failed!", WIFI_SERVICE_P2P);
83 break;
84 }
85 IP2pService *pService = WifiServiceManager::GetInstance().GetP2pServiceInst();
86 if (pService == nullptr) {
87 WIFI_LOGE("Create %{public}s service failed!", WIFI_SERVICE_P2P);
88 break;
89 }
90 ret = pService->RegisterP2pServiceCallbacks(mP2pCallback);
91 if (ret != WIFI_OPT_SUCCESS) {
92 WIFI_LOGE("Register p2p service callback failed!");
93 break;
94 }
95
96 ret = pService->EnableP2p();
97 if (ret != WIFI_OPT_SUCCESS) {
98 WIFI_LOGE("service EnableP2p failed, ret %{public}d!", static_cast<int>(ret));
99 break;
100 }
101 } while (false);
102 if (ret != WIFI_OPT_SUCCESS) {
103 WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::OPENING, WifiOprMidState::CLOSED);
104 WifiServiceManager::GetInstance().UnloadService(WIFI_SERVICE_P2P);
105 return ret;
106 }
107 std::unique_lock<std::mutex> locker(p2pEnableMutex);
108 p2pEnableCond.wait_for(locker, std::chrono::milliseconds(P2P_ENABLE_WAIT_MS));
109 #ifndef OHOS_ARCH_LITE
110 StopUnloadP2PSaTimer();
111 #endif
112 return WIFI_OPT_SUCCESS;
113 }
114
AutoStopP2pService()115 ErrCode WifiP2pManager::AutoStopP2pService()
116 {
117 WifiOprMidState p2pState = WifiConfigCenter::GetInstance().GetP2pMidState();
118 WIFI_LOGI("AutoStopP2pService, current p2p state:%{public}d", p2pState);
119 if (p2pState != WifiOprMidState::RUNNING) {
120 if (p2pState == WifiOprMidState::OPENING) {
121 return WIFI_OPT_CLOSE_FAIL_WHEN_OPENING;
122 } else {
123 return WIFI_OPT_CLOSE_SUCC_WHEN_CLOSED;
124 }
125 }
126
127 if (!WifiConfigCenter::GetInstance().SetP2pMidState(p2pState, WifiOprMidState::CLOSING)) {
128 WIFI_LOGE("AutoStopP2pService, set p2p mid state opening failed!");
129 return WIFI_OPT_CLOSE_SUCC_WHEN_CLOSED;
130 }
131
132 IP2pService *pService = WifiServiceManager::GetInstance().GetP2pServiceInst();
133 if (pService == nullptr) {
134 WIFI_LOGE("AutoStopP2pService, Instance get p2p service is null!");
135 WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::CLOSED);
136 WifiServiceManager::GetInstance().UnloadService(WIFI_SERVICE_P2P);
137 return WIFI_OPT_CLOSE_SUCC_WHEN_CLOSED;
138 }
139
140 ErrCode ret = pService->DisableP2p();
141 if (ret != WIFI_OPT_SUCCESS) {
142 WIFI_LOGE("service disable p2p failed, ret %{public}d!", static_cast<int>(ret));
143 WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::CLOSING, WifiOprMidState::RUNNING);
144 return ret;
145 }
146 std::unique_lock<std::mutex> locker(p2pEnableMutex);
147 p2pEnableCond.wait_for(locker, std::chrono::milliseconds(P2P_ENABLE_WAIT_MS));
148 return WIFI_OPT_SUCCESS;
149 }
150
151 #ifndef OHOS_ARCH_LITE
UnloadP2PSaTimerCallback()152 static void UnloadP2PSaTimerCallback()
153 {
154 WifiSaLoadManager::GetInstance().UnloadWifiSa(WIFI_P2P_ABILITY_ID);
155 WifiManager::GetInstance().GetWifiP2pManager()->StopUnloadP2PSaTimer();
156 }
157
StopUnloadP2PSaTimer(void)158 void WifiP2pManager::StopUnloadP2PSaTimer(void)
159 {
160 WIFI_LOGI("StopUnloadP2PSaTimer! unloadP2PSaTimerId:%{public}u", unloadP2PSaTimerId);
161 std::unique_lock<std::mutex> lock(unloadP2PSaTimerMutex);
162 if (unloadP2PSaTimerId == 0) {
163 return;
164 }
165 MiscServices::TimeServiceClient::GetInstance()->StopTimer(unloadP2PSaTimerId);
166 MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(unloadP2PSaTimerId);
167 unloadP2PSaTimerId = 0;
168 return;
169 }
170
StartUnloadP2PSaTimer(void)171 void WifiP2pManager::StartUnloadP2PSaTimer(void)
172 {
173 WIFI_LOGI("StartUnloadP2PSaTimer! unloadP2PSaTimerId:%{public}u", unloadP2PSaTimerId);
174 std::unique_lock<std::mutex> lock(unloadP2PSaTimerMutex);
175 if (unloadP2PSaTimerId == 0) {
176 std::shared_ptr<WifiSysTimer> wifiSysTimer = std::make_shared<WifiSysTimer>(false, 0, true, false);
177 wifiSysTimer->SetCallbackInfo(UnloadP2PSaTimerCallback);
178 unloadP2PSaTimerId = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(wifiSysTimer);
179 int64_t currentTime = MiscServices::TimeServiceClient::GetInstance()->GetBootTimeMs();
180 MiscServices::TimeServiceClient::GetInstance()->StartTimer(unloadP2PSaTimerId,
181 currentTime + TIMEOUT_UNLOAD_WIFI_SA);
182 WIFI_LOGI("StartUnloadP2PSaTimer success! unloadP2PSaTimerId:%{public}u", unloadP2PSaTimerId);
183 }
184 return;
185 }
186 #endif
187
CloseP2pService(void)188 void WifiP2pManager::CloseP2pService(void)
189 {
190 WIFI_LOGD("close p2p service");
191 WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::CLOSED);
192 WifiConfigCenter::GetInstance().SetP2pState(static_cast<int>(P2pState::P2P_STATE_CLOSED));
193 WifiEventCallbackMsg cbMsg;
194 cbMsg.msgCode = WIFI_CBK_MSG_P2P_STATE_CHANGE;
195 cbMsg.msgData = static_cast<int>(P2pState::P2P_STATE_CLOSED);
196 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
197 #ifdef HDI_CHIP_INTERFACE_SUPPORT
198 if (!ifaceName.empty()) {
199 DelayedSingleton<HalDeviceManager>::GetInstance()->RemoveP2pIface(ifaceName);
200 ifaceName.clear();
201 WifiConfigCenter::GetInstance().SetP2pIfaceName("");
202 }
203 #endif
204 WifiOprMidState staState = WifiConfigCenter::GetInstance().GetWifiMidState();
205 #ifndef OHOS_ARCH_LITE
206 if (WifiConfigCenter::GetInstance().GetAirplaneModeState() == MODE_STATE_OPEN) {
207 WIFI_LOGI("airplaneMode not close p2p SA!");
208 return;
209 }
210 #endif
211 WIFI_LOGI("CloseP2pService, current sta state:%{public}d", staState);
212 return;
213 }
214
InitP2pCallback(void)215 void WifiP2pManager::InitP2pCallback(void)
216 {
217 using namespace std::placeholders;
218 mP2pCallback.callbackModuleName = "P2pManager";
219 mP2pCallback.OnP2pStateChangedEvent = std::bind(&WifiP2pManager::DealP2pStateChanged, this, _1);
220 mP2pCallback.OnP2pPeersChangedEvent = std::bind(&WifiP2pManager::DealP2pPeersChanged, this, _1);
221 mP2pCallback.OnP2pServicesChangedEvent = std::bind(&WifiP2pManager::DealP2pServiceChanged, this, _1);
222 mP2pCallback.OnP2pConnectionChangedEvent = std::bind(&WifiP2pManager::DealP2pConnectionChanged, this, _1);
223 mP2pCallback.OnP2pThisDeviceChangedEvent = std::bind(&WifiP2pManager::DealP2pThisDeviceChanged, this, _1);
224 mP2pCallback.OnP2pDiscoveryChangedEvent = std::bind(&WifiP2pManager::DealP2pDiscoveryChanged, this, _1);
225 mP2pCallback.OnP2pGroupsChangedEvent = std::bind(&WifiP2pManager::DealP2pGroupsChanged, this);
226 mP2pCallback.OnP2pActionResultEvent = std::bind(&WifiP2pManager::DealP2pActionResult, this, _1, _2);
227 mP2pCallback.OnConfigChangedEvent = std::bind(&WifiP2pManager::DealConfigChanged, this, _1, _2, _3);
228 mP2pCallback.OnP2pGcJoinGroupEvent = std::bind(&WifiP2pManager::DealP2pGcJoinGroup, this, _1);
229 mP2pCallback.OnP2pGcLeaveGroupEvent = std::bind(&WifiP2pManager::DealP2pGcLeaveGroup, this, _1);
230 mP2pCallback.OnP2pPrivatePeersChangedEvent = std::bind(&WifiP2pManager::DealP2pPrivatePeersChanged, this, _1);
231 return;
232 }
233
DealP2pStateChanged(P2pState state)234 void WifiP2pManager::DealP2pStateChanged(P2pState state)
235 {
236 WIFI_LOGI("DealP2pStateChanged, state: %{public}d", static_cast<int>(state));
237 WifiEventCallbackMsg cbMsg;
238 cbMsg.msgCode = WIFI_CBK_MSG_P2P_STATE_CHANGE;
239 cbMsg.msgData = static_cast<int>(state);
240 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
241 if (state == P2pState::P2P_STATE_IDLE) {
242 CloseP2pService();
243 p2pEnableCond.notify_all();
244 }
245 if (state == P2pState::P2P_STATE_STARTED) {
246 WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::OPENING, WifiOprMidState::RUNNING);
247 p2pEnableCond.notify_all();
248 WifiOprMidState staState = WifiConfigCenter::GetInstance().GetWifiMidState();
249 WIFI_LOGI("DealP2pStateChanged, current sta state:%{public}d", staState);
250 if (staState == WifiOprMidState::CLOSING || staState == WifiOprMidState::CLOSED) {
251 AutoStopP2pService();
252 }
253 }
254 if (state == P2pState::P2P_STATE_CLOSED) {
255 bool ret = WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::OPENING, WifiOprMidState::CLOSED);
256 if (ret) {
257 WIFI_LOGE("P2p start failed, stop wifi!");
258 AutoStopP2pService();
259 }
260 }
261 WifiCommonEventHelper::PublishP2pStateChangedEvent((int)state, "OnP2pStateChanged");
262 return;
263 }
264
DealP2pPeersChanged(const std::vector<WifiP2pDevice> & vPeers)265 void WifiP2pManager::DealP2pPeersChanged(const std::vector<WifiP2pDevice> &vPeers)
266 {
267 WifiEventCallbackMsg cbMsg;
268 cbMsg.msgCode = WIFI_CBK_MSG_PEER_CHANGE;
269 cbMsg.device = vPeers;
270 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
271 WifiCommonEventHelper::PublishP2pPeersStateChangedEvent(vPeers.size(), "OnP2pPeersChanged");
272 return;
273 }
274
DealP2pPrivatePeersChanged(const std::string & privateInfo)275 void WifiP2pManager::DealP2pPrivatePeersChanged(const std::string &privateInfo)
276 {
277 WifiEventCallbackMsg cbMsg;
278 cbMsg.msgCode = WIFI_CBK_MSG_PRIVATE_PEER_CHANGE;
279 cbMsg.privateWfdInfo = privateInfo;
280 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
281 return;
282 }
283
DealP2pServiceChanged(const std::vector<WifiP2pServiceInfo> & vServices)284 void WifiP2pManager::DealP2pServiceChanged(const std::vector<WifiP2pServiceInfo> &vServices)
285 {
286 WifiEventCallbackMsg cbMsg;
287 cbMsg.msgCode = WIFI_CBK_MSG_SERVICE_CHANGE;
288 cbMsg.serviceInfo = vServices;
289 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
290 return;
291 }
292
DealP2pConnectionChanged(const WifiP2pLinkedInfo & info)293 void WifiP2pManager::DealP2pConnectionChanged(const WifiP2pLinkedInfo &info)
294 {
295 WifiEventCallbackMsg cbMsg;
296 cbMsg.msgCode = WIFI_CBK_MSG_CONNECT_CHANGE;
297 cbMsg.p2pInfo = info;
298 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
299 WifiCommonEventHelper::PublishP2pConnStateEvent((int)info.GetConnectState(), "OnP2pConnectStateChanged");
300 WifiP2pGroupInfo group;
301 IP2pService *pService = WifiServiceManager::GetInstance().GetP2pServiceInst();
302 if (pService == nullptr) {
303 WIFI_LOGE("Get P2P service failed!");
304 return;
305 }
306 ErrCode errCode = pService->GetCurrentGroup(group);
307 if (errCode != WIFI_OPT_SUCCESS) {
308 WIFI_LOGE("Get current group info failed!");
309 return;
310 }
311 WriteWifiP2pStateHiSysEvent(group.GetInterface(), (int32_t)info.IsGroupOwner(), (int32_t)info.GetConnectState());
312 if (info.GetConnectState() == P2pConnectedState::P2P_CONNECTED) {
313 WriteP2pKpiCountHiSysEvent(static_cast<int>(P2P_CHR_EVENT::CONN_SUC_CNT));
314 }
315 return;
316 }
317
DealP2pThisDeviceChanged(const WifiP2pDevice & info)318 void WifiP2pManager::DealP2pThisDeviceChanged(const WifiP2pDevice &info)
319 {
320 WifiEventCallbackMsg cbMsg;
321 cbMsg.msgCode = WIFI_CBK_MSG_THIS_DEVICE_CHANGE;
322 cbMsg.p2pDevice = info;
323 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
324 WifiCommonEventHelper::PublishP2pCurrentDeviceStateChangedEvent(
325 (int)info.GetP2pDeviceStatus(), "OnP2pThisDeviceChanged");
326 return;
327 }
328
DealP2pDiscoveryChanged(bool bState)329 void WifiP2pManager::DealP2pDiscoveryChanged(bool bState)
330 {
331 WifiEventCallbackMsg cbMsg;
332 cbMsg.msgCode = WIFI_CBK_MSG_DISCOVERY_CHANGE;
333 cbMsg.msgData = static_cast<int>(bState);
334 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
335 return;
336 }
337
DealP2pGroupsChanged()338 void WifiP2pManager::DealP2pGroupsChanged() __attribute__((no_sanitize("cfi")))
339 {
340 WifiEventCallbackMsg cbMsg;
341 cbMsg.msgCode = WIFI_CBK_MSG_PERSISTENT_GROUPS_CHANGE;
342 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
343 WifiCommonEventHelper::PublishP2pGroupStateChangedEvent(0, "OnP2pGroupStateChanged");
344 return;
345 }
346
DealP2pActionResult(P2pActionCallback action,ErrCode code)347 void WifiP2pManager::DealP2pActionResult(P2pActionCallback action, ErrCode code)
348 {
349 WifiEventCallbackMsg cbMsg;
350 cbMsg.msgCode = WIFI_CBK_MSG_P2P_ACTION_RESULT;
351 cbMsg.p2pAction = action;
352 cbMsg.msgData = static_cast<int>(code);
353 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
354 return;
355 }
356
DealP2pGcJoinGroup(const GcInfo & info)357 void WifiP2pManager::DealP2pGcJoinGroup(const GcInfo &info)
358 {
359 WifiEventCallbackMsg cbMsg;
360 cbMsg.msgCode = WIFI_CBK_MSG_P2P_GC_JOIN_GROUP;
361 cbMsg.gcInfo = info;
362 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
363 return;
364 }
365
DealP2pGcLeaveGroup(const GcInfo & info)366 void WifiP2pManager::DealP2pGcLeaveGroup(const GcInfo &info)
367 {
368 WifiEventCallbackMsg cbMsg;
369 cbMsg.msgCode = WIFI_CBK_MSG_P2P_GC_LEAVE_GROUP;
370 cbMsg.gcInfo = info;
371 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
372 return;
373 }
374
DealConfigChanged(CfgType type,char * data,int dataLen)375 void WifiP2pManager::DealConfigChanged(CfgType type, char* data, int dataLen)
376 {
377 if (data == nullptr || dataLen <= 0) {
378 return;
379 }
380 WifiEventCallbackMsg cbMsg;
381 cbMsg.msgCode = WIFI_CBK_MSG_CFG_CHANGE;
382 CfgInfo* cfgInfoPtr = new (std::nothrow) CfgInfo();
383 if (cfgInfoPtr == nullptr) {
384 WIFI_LOGE("DealConfigChanged: new CfgInfo failed");
385 return;
386 }
387 cfgInfoPtr->type = type;
388 char* cfgData = new (std::nothrow) char[dataLen];
389 if (cfgData == nullptr) {
390 WIFI_LOGE("DealConfigChanged: new data failed");
391 delete cfgInfoPtr;
392 cfgInfoPtr = nullptr;
393 return;
394 }
395 if (memcpy_s(cfgData, dataLen, data, dataLen) != EOK) {
396 WIFI_LOGE("DealConfigChanged: memcpy_s failed");
397 delete cfgInfoPtr;
398 cfgInfoPtr = nullptr;
399 delete[] cfgData;
400 cfgData = nullptr;
401 return;
402 }
403 cfgInfoPtr->data = cfgData;
404 cfgInfoPtr->dataLen = dataLen;
405 cbMsg.cfgInfo = cfgInfoPtr;
406 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
407 return;
408 }
409
IfaceDestoryCallback(std::string & destoryIfaceName,int createIfaceType)410 void WifiP2pManager::IfaceDestoryCallback(std::string &destoryIfaceName, int createIfaceType)
411 {
412 WIFI_LOGI("IfaceDestoryCallback, ifaceName:%{public}s, ifaceType:%{public}d",
413 destoryIfaceName.c_str(), createIfaceType);
414 if (destoryIfaceName == ifaceName) {
415 ifaceName.clear();
416 WifiConfigCenter::GetInstance().SetP2pIfaceName("");
417 }
418 return;
419 }
420
421 } // namespace Wifi
422 } // namespace OHOS
423 #endif