• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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