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