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 "lnn_lane_link_wifi_direct.h"
17 
18 #include <securec.h>
19 
20 #include "anonymizer.h"
21 #include "auth_interface.h"
22 #include "bus_center_manager.h"
23 #include "lnn_lane_link_p2p.h"
24 #include "lnn_log.h"
25 #include "lnn_trans_lane.h"
26 #include "softbus_adapter_mem.h"
27 #include "softbus_adapter_thread.h"
28 #include "wifi_direct_manager.h"
29 
30 static SoftBusMutex g_linkWifiDirectMutex;
31 static ListNode *g_forceDownList = NULL;
32 
33 #define INVAILD_AUTH_ID (-1)
34 #define INVALID_P2P_REQUEST_ID (-1)
35 #define TRANS_FORCE_DOWN_TIMEOUT 2000
36 #define USECTONSEC 1000LL
37 
38 typedef enum {
39     INFO_TYPE_P2P = 0,
40     INFO_TYPE_AUTH,
41     INFO_TYPE_FORCE_DOWN,
42     INFO_TYPE_BUTT,
43 } ForceDisconnectInfoType;
44 
LinkWifiDirectLock(void)45 static int32_t LinkWifiDirectLock(void)
46 {
47     return SoftBusMutexLock(&g_linkWifiDirectMutex);
48 }
49 
LinkWifiDirectUnlock(void)50 static void LinkWifiDirectUnlock(void)
51 {
52     (void)SoftBusMutexUnlock(&g_linkWifiDirectMutex);
53 }
54 
IsForceDownInfoExists(uint32_t p2pRequestId)55 static bool IsForceDownInfoExists(uint32_t p2pRequestId)
56 {
57     if (LinkWifiDirectLock() != SOFTBUS_OK) {
58         LNN_LOGE(LNN_LANE, "link wifidirect lock fail");
59         return SOFTBUS_LOCK_ERR;
60     }
61     ForceDownInfo *item = NULL;
62     ForceDownInfo *next = NULL;
63     LIST_FOR_EACH_ENTRY_SAFE(item, next, g_forceDownList, ForceDownInfo, node) {
64         if (item->p2pRequestId == p2pRequestId) {
65             LinkWifiDirectUnlock();
66             return true;
67         }
68     }
69     LinkWifiDirectUnlock();
70     return false;
71 }
72 
AddForceDownInfo(const ForceDownInfo * forceDownInfo)73 static int32_t AddForceDownInfo(const ForceDownInfo *forceDownInfo)
74 {
75     if (forceDownInfo == NULL) {
76         LNN_LOGE(LNN_LANE, "invalid param");
77         return SOFTBUS_INVALID_PARAM;
78     }
79     if (IsForceDownInfoExists(forceDownInfo->p2pRequestId)) {
80         LNN_LOGE(LNN_LANE, "forceDownInfo already exists");
81         return SOFTBUS_OK;
82     }
83     ForceDownInfo *newNode = (ForceDownInfo *)SoftBusCalloc(sizeof(ForceDownInfo));
84     if (newNode == NULL) {
85         LNN_LOGE(LNN_LANE, "calloc forceDownInfo fail");
86         return SOFTBUS_MALLOC_ERR;
87     }
88     if (memcpy_s(newNode, sizeof(ForceDownInfo), forceDownInfo, sizeof(ForceDownInfo)) != EOK) {
89         LNN_LOGE(LNN_LANE, "memcpy forceDownInfo fail");
90         SoftBusFree(newNode);
91         return SOFTBUS_MEM_ERR;
92     }
93     if (SoftBusCondInit(&newNode->cond) != SOFTBUS_OK) {
94         SoftBusFree(newNode);
95         return SOFTBUS_NO_INIT;
96     }
97     if (LinkWifiDirectLock() != SOFTBUS_OK) {
98         LNN_LOGE(LNN_LANE, "link wifidirect lock fail");
99         (void)SoftBusCondDestroy(&newNode->cond);
100         SoftBusFree(newNode);
101         return SOFTBUS_LOCK_ERR;
102     }
103     ListTailInsert(g_forceDownList, &newNode->node);
104     LinkWifiDirectUnlock();
105     char *anonyNetworkId = NULL;
106     Anonymize(forceDownInfo->forceDownDevId, &anonyNetworkId);
107     LNN_LOGI(LNN_LANE, "add new forceDownInfo success, p2pRequestId=%{public}u, forceDownDevId=%{public}s, "
108         "forceDownReqId=%{public}u, forceDownLink=%{public}d, forceDownType=%{public}d", forceDownInfo->p2pRequestId,
109         AnonymizeWrapper(anonyNetworkId), forceDownInfo->forceDownReqId,
110         forceDownInfo->forceDownLink, forceDownInfo->downType);
111     AnonymizeFree(anonyNetworkId);
112     return SOFTBUS_OK;
113 }
114 
DelForceDownInfo(uint32_t forceDownReqId)115 static int32_t DelForceDownInfo(uint32_t forceDownReqId)
116 {
117     if (LinkWifiDirectLock() != SOFTBUS_OK) {
118         LNN_LOGE(LNN_LANE, "lock fail");
119         return SOFTBUS_LOCK_ERR;
120     }
121     LNN_LOGI(LNN_LANE, "start to del forceDownInfo by forceDownReqId=%{public}u", forceDownReqId);
122     ForceDownInfo *item = NULL;
123     ForceDownInfo *next = NULL;
124     LIST_FOR_EACH_ENTRY_SAFE(item, next, g_forceDownList, ForceDownInfo, node) {
125         if (item->forceDownReqId == forceDownReqId) {
126             if (item->downType == FORCE_DOWN_TRANS) {
127                 (void)SoftBusCondSignal(&item->cond);
128             }
129             ListDelete(&item->node);
130             (void)SoftBusCondDestroy(&item->cond);
131             SoftBusFree(item);
132             LinkWifiDirectUnlock();
133             return SOFTBUS_OK;
134         }
135     }
136     LinkWifiDirectUnlock();
137     LNN_LOGE(LNN_LANE, "not found forceDownInfo when del");
138     return SOFTBUS_LANE_NOT_FOUND;
139 }
140 
GetForceDownInfoWithoutLock(ForceDisconnectInfoType type,uint32_t requestId)141 static ForceDownInfo* GetForceDownInfoWithoutLock(ForceDisconnectInfoType type, uint32_t requestId)
142 {
143     ForceDownInfo *item = NULL;
144     ForceDownInfo *next = NULL;
145     LIST_FOR_EACH_ENTRY_SAFE(item, next, g_forceDownList, ForceDownInfo, node) {
146         if ((type == INFO_TYPE_AUTH && item->authRequestId == requestId) ||
147             (type == INFO_TYPE_FORCE_DOWN && item->forceDownReqId == requestId)) {
148             return item;
149         }
150     }
151     return NULL;
152 }
153 
FindForceDownInfoByReqId(ForceDisconnectInfoType type,uint32_t requestId,ForceDownInfo * info)154 static int32_t FindForceDownInfoByReqId(ForceDisconnectInfoType type, uint32_t requestId,
155     ForceDownInfo *info)
156 {
157     if (LinkWifiDirectLock() != SOFTBUS_OK) {
158         LNN_LOGE(LNN_LANE, "link wifidirect lock fail");
159         return SOFTBUS_LOCK_ERR;
160     }
161     ForceDownInfo* item = GetForceDownInfoWithoutLock(type, requestId);
162     if (item == NULL) {
163         LNN_LOGE(LNN_LANE, "not found forceDownInfo by type=%{public}d, requestId=%{public}u", type, requestId);
164         LinkWifiDirectUnlock();
165         return SOFTBUS_LANE_NOT_FOUND;
166     }
167     if (memcpy_s(info, sizeof(ForceDownInfo), item, sizeof(ForceDownInfo)) != EOK) {
168         LNN_LOGE(LNN_LANE, "memcpy forceDownInfo fail");
169         LinkWifiDirectUnlock();
170         return SOFTBUS_MEM_ERR;
171     }
172     LinkWifiDirectUnlock();
173     return SOFTBUS_OK;
174 }
175 
FreeResourceForForceDisconnect(ForceDownInfo * forceDownInfo)176 static void FreeResourceForForceDisconnect(ForceDownInfo *forceDownInfo)
177 {
178     if (forceDownInfo == NULL) {
179         LNN_LOGE(LNN_LANE, "invalid param");
180         return;
181     }
182     (void)DelForceDownInfo(forceDownInfo->forceDownReqId);
183     if (forceDownInfo->authHandle.authId != INVAILD_AUTH_ID) {
184         AuthCloseConn(forceDownInfo->authHandle);
185     }
186     RecycleP2pLinkedReqByLinkType(forceDownInfo->forceDownDevId, forceDownInfo->forceDownLink);
187     char peerUdid[UDID_BUF_LEN] = {0};
188     if (LnnGetRemoteStrInfo(forceDownInfo->forceDownDevId, STRING_KEY_DEV_UDID,
189         peerUdid, UDID_BUF_LEN) != SOFTBUS_OK) {
190         LNN_LOGE(LNN_LANE, "get peerUdid error");
191         return;
192     }
193     LaneResource resourceItem;
194     (void)memset_s(&resourceItem, sizeof(LaneResource), 0, sizeof(LaneResource));
195     if (FindLaneResourceByLinkType(peerUdid, forceDownInfo->forceDownLink, &resourceItem) == SOFTBUS_OK) {
196         if (forceDownInfo->forceDownLink == LANE_HML) {
197             RemoveDelayDestroyMessage(resourceItem.laneId);
198         }
199         DelLogicAndLaneRelationship(resourceItem.laneId);
200         ClearLaneResourceByLaneId(resourceItem.laneId);
201     }
202     if (forceDownInfo->forceDownLink == LANE_HML &&
203         FindLaneResourceByLinkType(peerUdid, LANE_HML_RAW, &resourceItem) == SOFTBUS_OK) {
204         DelLogicAndLaneRelationship(resourceItem.laneId);
205         ClearLaneResourceByLaneId(resourceItem.laneId);
206     }
207 }
208 
GetChannelAuthType(const char * peerNetWorkId)209 static bool GetChannelAuthType(const char *peerNetWorkId)
210 {
211     int32_t value = 0;
212     int32_t ret = LnnGetRemoteNumInfo(peerNetWorkId, NUM_KEY_META_NODE, &value);
213     if (ret != SOFTBUS_OK) {
214         LNN_LOGE(LNN_LANE, "GetChannelAuthType fail, ret=%{public}d", ret);
215     }
216     return ((1 << ONLINE_METANODE) == value);
217 }
218 
GetPreferAuthConnInfo(const char * networkId,AuthConnInfo * connInfo,bool isMetaAuth)219 static int32_t GetPreferAuthConnInfo(const char *networkId, AuthConnInfo *connInfo, bool isMetaAuth)
220 {
221     char uuid[UDID_BUF_LEN] = {0};
222     if (LnnGetRemoteStrInfo(networkId, STRING_KEY_UUID, uuid, sizeof(uuid)) != SOFTBUS_OK) {
223         LNN_LOGE(LNN_LANE, "get peer uuid fail");
224         return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
225     }
226     int32_t ret = AuthGetHmlConnInfo(uuid, connInfo, isMetaAuth);
227     if (ret != SOFTBUS_OK) {
228         ret = AuthGetPreferConnInfo(uuid, connInfo, isMetaAuth);
229     }
230     return ret;
231 }
232 
OnWifiDirectForceDisconnectSuccess(uint32_t requestId)233 static void OnWifiDirectForceDisconnectSuccess(uint32_t requestId)
234 {
235     LNN_LOGI(LNN_LANE, "wifidirect force disconnect succ, requestId=%{public}u", requestId);
236     ForceDownInfo forceDownInfo;
237     (void)memset_s(&forceDownInfo, sizeof(ForceDownInfo), 0, sizeof(ForceDownInfo));
238     int32_t ret = FindForceDownInfoByReqId(INFO_TYPE_FORCE_DOWN, requestId, &forceDownInfo);
239     if (ret != SOFTBUS_OK) {
240         LNN_LOGE(LNN_LANE, "find forceDownInfo fail, requestId=%{public}u", requestId);
241         return;
242     }
243     FreeResourceForForceDisconnect(&forceDownInfo);
244     if (forceDownInfo.downType == FORCE_DOWN_LANE) {
245         ret = WifiDirectReconnectDevice(forceDownInfo.p2pRequestId);
246         if (ret != SOFTBUS_OK) {
247             LNN_LOGE(LNN_LANE, "wifidirect reconnect device fail, p2pRequest=%{public}u",
248                 forceDownInfo.p2pRequestId);
249             NotifyLinkFailForForceDown(forceDownInfo.p2pRequestId, ret);
250         }
251     }
252 }
253 
OnWifiDirectForceDisconnectFailure(uint32_t requestId,int32_t reason)254 static void OnWifiDirectForceDisconnectFailure(uint32_t requestId, int32_t reason)
255 {
256     LNN_LOGE(LNN_LANE, "wifidirect force disconnect fail, requestId=%{public}u, reason=%{public}d",
257         requestId, reason);
258     ForceDownInfo forceDownInfo;
259     (void)memset_s(&forceDownInfo, sizeof(ForceDownInfo), 0, sizeof(ForceDownInfo));
260     int32_t ret = FindForceDownInfoByReqId(INFO_TYPE_FORCE_DOWN, requestId, &forceDownInfo);
261     if (ret != SOFTBUS_OK) {
262         LNN_LOGE(LNN_LANE, "find forceDownInfo fail, requestId=%{public}u", requestId);
263         return;
264     }
265     (void)DelForceDownInfo(requestId);
266     if (forceDownInfo.authHandle.authId != INVAILD_AUTH_ID) {
267         AuthCloseConn(forceDownInfo.authHandle);
268     }
269     if (forceDownInfo.downType == FORCE_DOWN_LANE) {
270         NotifyLinkFailForForceDown(forceDownInfo.p2pRequestId, reason);
271     }
272 }
273 
GenerateForceDownWifiDirectInfo(const ForceDownInfo * forceDownInfo,struct WifiDirectForceDisconnectInfo * info)274 static int32_t GenerateForceDownWifiDirectInfo(const ForceDownInfo* forceDownInfo,
275     struct WifiDirectForceDisconnectInfo *info)
276 {
277     if (forceDownInfo == NULL || info == NULL) {
278         LNN_LOGE(LNN_LANE, "invalid param");
279         return SOFTBUS_INVALID_PARAM;
280     }
281     info->requestId = forceDownInfo->forceDownReqId;
282     info->linkType = forceDownInfo->forceDownLink == LANE_HML ?
283         WIFI_DIRECT_LINK_TYPE_HML : WIFI_DIRECT_LINK_TYPE_P2P;
284     char peerUuid[UUID_BUF_LEN] = {0};
285     if (LnnGetRemoteStrInfo(forceDownInfo->forceDownDevId, STRING_KEY_UUID, peerUuid,
286         sizeof(peerUuid)) != SOFTBUS_OK) {
287         LNN_LOGE(LNN_LANE, "get peer uuid fail");
288         return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
289     }
290     if (strcpy_s(info->remoteUuid, sizeof(info->remoteUuid), peerUuid) != EOK) {
291         LNN_LOGE(LNN_LANE, "strcpy remote uuid fail");
292         return SOFTBUS_STRCMP_ERR;
293     }
294     return SOFTBUS_OK;
295 }
296 
UpdateForceDownInfoParam(uint32_t authRequestId,AuthHandle authHandle,ForceDownInfo * forceDownInfo)297 static int32_t UpdateForceDownInfoParam(uint32_t authRequestId, AuthHandle authHandle, ForceDownInfo *forceDownInfo)
298 {
299     if (forceDownInfo == NULL) {
300         LNN_LOGE(LNN_LANE, "invalid param");
301         return SOFTBUS_INVALID_PARAM;
302     }
303     if (LinkWifiDirectLock() != SOFTBUS_OK) {
304         LNN_LOGE(LNN_LANE, "link wifidirect lock fail");
305         return SOFTBUS_LOCK_ERR;
306     }
307     ForceDownInfo* item = GetForceDownInfoWithoutLock(INFO_TYPE_AUTH, authRequestId);
308     if (item == NULL) {
309         LNN_LOGE(LNN_LANE, "not found forceDownInfo by authRequestId=%{public}u", authRequestId);
310         LinkWifiDirectUnlock();
311         return SOFTBUS_LANE_NOT_FOUND;
312     }
313     item->authHandle = authHandle;
314     if (memcpy_s(forceDownInfo, sizeof(ForceDownInfo), item, sizeof(ForceDownInfo)) != EOK) {
315         LNN_LOGE(LNN_LANE, "memcpy forceDownInfo fail");
316         LinkWifiDirectUnlock();
317         return SOFTBUS_MEM_ERR;
318     }
319     LinkWifiDirectUnlock();
320     return SOFTBUS_OK;
321 }
322 
OnConnOpenedForForceDisconnect(uint32_t authRequestId,AuthHandle authHandle)323 static void OnConnOpenedForForceDisconnect(uint32_t authRequestId, AuthHandle authHandle)
324 {
325     LNN_LOGI(LNN_LANE, "auth opened for force disconnect wifidirect, authRequestId=%{public}u, "
326         "authId=%{public}" PRId64 "", authRequestId, authHandle.authId);
327     struct WifiDirectForceDisconnectInfo info;
328     (void)memset_s(&info, sizeof(info), 0, sizeof(info));
329     info.negoChannel.type = NEGO_CHANNEL_AUTH;
330     info.negoChannel.handle.authHandle = authHandle;
331     ForceDownInfo forceDownInfo;
332     (void)memset_s(&forceDownInfo, sizeof(ForceDownInfo), 0, sizeof(ForceDownInfo));
333     int32_t ret = UpdateForceDownInfoParam(authRequestId, authHandle, &forceDownInfo);
334     if (ret != SOFTBUS_OK) {
335         LNN_LOGE(LNN_LANE, "update forceDownInfo param fail");
336         goto FAIL;
337     }
338     ret = GenerateForceDownWifiDirectInfo(&forceDownInfo, &info);
339     if (ret != SOFTBUS_OK) {
340         LNN_LOGE(LNN_LANE, "get force disconnect wifidirect fail");
341         goto FAIL;
342     }
343     struct WifiDirectDisconnectCallback callback = {
344         .onDisconnectSuccess = OnWifiDirectForceDisconnectSuccess,
345         .onDisconnectFailure = OnWifiDirectForceDisconnectFailure,
346     };
347     LNN_LOGI(LNN_LANE, "force disconnect wifidirect, p2pRequestId=%{public}u, linkType=%{public}d",
348         info.requestId, info.linkType);
349     ret = GetWifiDirectManager()->forceDisconnectDevice(&info, &callback);
350     if (ret != SOFTBUS_OK) {
351         LNN_LOGE(LNN_LANE, "force disconnect device fail, reason=%{public}d", ret);
352         goto FAIL;
353     }
354     return;
355 FAIL:
356     (void)DelForceDownInfo(forceDownInfo.forceDownReqId);
357     if (authHandle.authId != INVAILD_AUTH_ID) {
358         AuthCloseConn(authHandle);
359     }
360     if (forceDownInfo.downType == FORCE_DOWN_LANE) {
361         NotifyLinkFailForForceDown(forceDownInfo.p2pRequestId, ret);
362     }
363 }
364 
ForceDisconnectWifiDirectWithoutAuth(const ForceDownInfo * forceDownInfo)365 static int32_t ForceDisconnectWifiDirectWithoutAuth(const ForceDownInfo *forceDownInfo)
366 {
367     if (forceDownInfo == NULL) {
368         LNN_LOGE(LNN_LANE, "invalid param");
369         return SOFTBUS_INVALID_PARAM;
370     }
371     struct WifiDirectForceDisconnectInfo info;
372     (void)memset_s(&info, sizeof(info), 0, sizeof(info));
373     int32_t ret = GenerateForceDownWifiDirectInfo(forceDownInfo, &info);
374     if (ret != SOFTBUS_OK) {
375         LNN_LOGE(LNN_LANE, "get force disconnect wifidirect fail");
376         return ret;
377     }
378     struct WifiDirectDisconnectCallback callback = {
379         .onDisconnectSuccess = OnWifiDirectForceDisconnectSuccess,
380         .onDisconnectFailure = OnWifiDirectForceDisconnectFailure,
381     };
382     LNN_LOGI(LNN_LANE, "force disconnect wifidirect, p2pRequestId=%{public}u, linkType=%{public}d",
383         info.requestId, info.linkType);
384     ret = GetWifiDirectManager()->forceDisconnectDevice(&info, &callback);
385     if (ret != SOFTBUS_OK) {
386         LNN_LOGE(LNN_LANE, "force disconnect device fail, reason=%{public}d", ret);
387         return ret;
388     }
389     return SOFTBUS_OK;
390 }
391 
OnConnOpenFailedForForceDisconnect(uint32_t authRequestId,int32_t reason)392 static void OnConnOpenFailedForForceDisconnect(uint32_t authRequestId, int32_t reason)
393 {
394     LNN_LOGE(LNN_LANE, "auth open fail for force disconnect wifidirect, authRequestId=%{public}u, reason=%{public}d",
395         authRequestId, reason);
396     ForceDownInfo forceDownInfo;
397     (void)memset_s(&forceDownInfo, sizeof(ForceDownInfo), 0, sizeof(ForceDownInfo));
398     if (FindForceDownInfoByReqId(INFO_TYPE_AUTH, authRequestId, &forceDownInfo) != SOFTBUS_OK) {
399         LNN_LOGE(LNN_LANE, "find forceDownInfo fail, authRequestId=%{public}u", authRequestId);
400         return;
401     }
402     int32_t ret = ForceDisconnectWifiDirectWithoutAuth(&forceDownInfo);
403     if (ret != SOFTBUS_OK) {
404         LNN_LOGE(LNN_LANE, "force disconnect device fail, reason=%{public}d", ret);
405         (void)DelForceDownInfo(forceDownInfo.forceDownReqId);
406         if (forceDownInfo.downType == FORCE_DOWN_LANE) {
407             NotifyLinkFailForForceDown(forceDownInfo.p2pRequestId, reason);
408         }
409     }
410     return;
411 }
412 
OpenAuthToForceDisconnect(const char * forceDownDevId,uint32_t forceDownReqId)413 static int32_t OpenAuthToForceDisconnect(const char *forceDownDevId, uint32_t forceDownReqId)
414 {
415     if (forceDownDevId == NULL) {
416         LNN_LOGE(LNN_LANE, "invalid param");
417         return SOFTBUS_INVALID_PARAM;
418     }
419     AuthConnInfo connInfo;
420     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
421     bool isMetaAuth = GetChannelAuthType(forceDownDevId);
422     int32_t ret = GetPreferAuthConnInfo(forceDownDevId, &connInfo, isMetaAuth);
423     if (ret != SOFTBUS_OK) {
424         LNN_LOGE(LNN_LANE, "no auth conn exist");
425         return ret;
426     }
427     uint32_t authRequestId = AuthGenRequestId();
428     if (LinkWifiDirectLock() != SOFTBUS_OK) {
429         LNN_LOGE(LNN_LANE, "link wifidirect lock fail");
430         return SOFTBUS_LOCK_ERR;
431     }
432     ForceDownInfo* forceDownInfo = GetForceDownInfoWithoutLock(INFO_TYPE_FORCE_DOWN, forceDownReqId);
433     if (forceDownInfo == NULL) {
434         LNN_LOGE(LNN_LANE, "not found forceDownInfo by forceDownReqId=%{public}u", forceDownReqId);
435         LinkWifiDirectUnlock();
436         return SOFTBUS_LANE_NOT_FOUND;
437     }
438     forceDownInfo->authRequestId = authRequestId;
439     LinkWifiDirectUnlock();
440     AuthConnCallback cb = {
441         .onConnOpened = OnConnOpenedForForceDisconnect,
442         .onConnOpenFailed = OnConnOpenFailedForForceDisconnect,
443     };
444     LNN_LOGI(LNN_LANE, "open auth for force disconnect wifidirect, authRequestId=%{public}u", authRequestId);
445     ret = AuthOpenConn(&connInfo, authRequestId, &cb, isMetaAuth);
446     if (ret != SOFTBUS_OK) {
447         LNN_LOGE(LNN_LANE, "open auth conn fail, authRequestId=%{public}u", authRequestId);
448         return ret;
449     }
450     return SOFTBUS_OK;
451 }
452 
AddNewForceDownInfo(ForceDownType downType,const char * forceDownDevId,LaneLinkType forceDownLink,uint32_t p2pRequestId,uint32_t forceDownReqId)453 static int32_t AddNewForceDownInfo(ForceDownType downType, const char *forceDownDevId, LaneLinkType forceDownLink,
454     uint32_t p2pRequestId, uint32_t forceDownReqId)
455 {
456     if (forceDownDevId == NULL) {
457         LNN_LOGE(LNN_LANE, "invalid param");
458         return SOFTBUS_INVALID_PARAM;
459     }
460     ForceDownInfo forceDownInfo;
461     (void)memset_s(&forceDownInfo, sizeof(ForceDownInfo), 0, sizeof(ForceDownInfo));
462     if (strcpy_s(forceDownInfo.forceDownDevId, sizeof(forceDownInfo.forceDownDevId),
463         forceDownDevId) != EOK) {
464         LNN_LOGE(LNN_LANE, "copy forceDownDevId fail");
465         return SOFTBUS_STRCPY_ERR;
466     }
467     forceDownInfo.p2pRequestId = p2pRequestId;
468     forceDownInfo.forceDownLink = forceDownLink;
469     forceDownInfo.forceDownReqId = forceDownReqId;
470     forceDownInfo.authRequestId = AUTH_INVALID_ID;
471     AuthHandle authHandle = { .authId = INVAILD_AUTH_ID };
472     forceDownInfo.authHandle = authHandle;
473     forceDownInfo.downType = downType;
474     int32_t ret = AddForceDownInfo(&forceDownInfo);
475     if (ret != SOFTBUS_OK) {
476         LNN_LOGE(LNN_LANE, "add new forceDownInfo fail");
477         return ret;
478     }
479     return SOFTBUS_OK;
480 }
481 
FreeLinkConflictDevInfo(LinkConflictInfo * inputItem)482 static void FreeLinkConflictDevInfo(LinkConflictInfo *inputItem)
483 {
484     if (inputItem == NULL) {
485         LNN_LOGE(LNN_LANE, "invalid param");
486         return;
487     }
488     if (inputItem->devIdCnt > 0) {
489         SoftBusFree(inputItem->devIdList);
490         inputItem->devIdList = NULL;
491     }
492     if (inputItem->devIpCnt > 0) {
493         SoftBusFree(inputItem->devIpList);
494         inputItem->devIpList = NULL;
495     }
496     inputItem->devIdCnt = 0;
497     inputItem->devIpCnt = 0;
498 }
499 
ComputeWaitForceDownTime(uint32_t waitMillis,SoftBusSysTime * outtime)500 static void ComputeWaitForceDownTime(uint32_t waitMillis, SoftBusSysTime *outtime)
501 {
502     SoftBusSysTime now;
503     (void)SoftBusGetTime(&now);
504     int64_t time = now.sec * USECTONSEC * USECTONSEC + now.usec + (int64_t)waitMillis * USECTONSEC;
505     outtime->sec = time / USECTONSEC / USECTONSEC;
506     outtime->usec = time % (USECTONSEC * USECTONSEC);
507 }
508 
ForceDownCondWait(ForceDownType downType,uint32_t forceDownReqId)509 static void ForceDownCondWait(ForceDownType downType, uint32_t forceDownReqId)
510 {
511     if (downType != FORCE_DOWN_TRANS) {
512         LNN_LOGI(LNN_LANE, "not support downType=%{public}d", downType);
513         return;
514     }
515     SoftBusSysTime outtime;
516     ComputeWaitForceDownTime(TRANS_FORCE_DOWN_TIMEOUT, &outtime);
517     LNN_LOGI(LNN_LANE, "set forceDown condWait with %{public}d millis, forceDownReqId=%{public}u",
518         TRANS_FORCE_DOWN_TIMEOUT, forceDownReqId);
519     if (LinkWifiDirectLock() != SOFTBUS_OK) {
520         LNN_LOGE(LNN_LANE, "lock fail");
521         return;
522     }
523     ForceDownInfo *item = NULL;
524     ForceDownInfo *next = NULL;
525     LIST_FOR_EACH_ENTRY_SAFE(item, next, g_forceDownList, ForceDownInfo, node) {
526         if (item->forceDownReqId == forceDownReqId) {
527             (void)SoftBusCondWait(&item->cond, &g_linkWifiDirectMutex, &outtime);
528             LinkWifiDirectUnlock();
529             return;
530         }
531     }
532     LinkWifiDirectUnlock();
533     LNN_LOGE(LNN_LANE, "not found forceDownInfo when set condWait");
534 }
535 
ForceDisconnectWifiDirect(ForceDownType downType,const char * forceDownDevId,LaneLinkType forceDownLink,uint32_t p2pRequestId)536 static int32_t ForceDisconnectWifiDirect(ForceDownType downType, const char *forceDownDevId,
537     LaneLinkType forceDownLink, uint32_t p2pRequestId)
538 {
539     if (forceDownDevId == NULL) {
540         LNN_LOGE(LNN_LANE, "invalid param");
541         return SOFTBUS_INVALID_PARAM;
542     }
543     uint32_t forceDownReqId = GetWifiDirectManager()->getRequestId();
544     int32_t ret = AddNewForceDownInfo(downType, forceDownDevId, forceDownLink, p2pRequestId, forceDownReqId);
545     if (ret !=SOFTBUS_OK) {
546         LNN_LOGE(LNN_LANE, "add new force disconnect info fail");
547         return ret;
548     }
549     enum WifiDirectLinkType linkType = forceDownLink == LANE_HML ?
550         WIFI_DIRECT_LINK_TYPE_HML : WIFI_DIRECT_LINK_TYPE_P2P;
551     ret = SOFTBUS_OK;
552     if (!GetWifiDirectManager()->isNegotiateChannelNeeded(forceDownDevId, linkType) ||
553         OpenAuthToForceDisconnect(forceDownDevId, forceDownReqId) != SOFTBUS_OK) {
554         LNN_LOGI(LNN_LANE, "no need auth or open auth fail, force disconnect without auth");
555         ForceDownInfo forceDownInfo;
556         (void)memset_s(&forceDownInfo, sizeof(ForceDownInfo), 0, sizeof(ForceDownInfo));
557         ret = FindForceDownInfoByReqId(INFO_TYPE_FORCE_DOWN, forceDownReqId, &forceDownInfo);
558         if (ret != SOFTBUS_OK) {
559             LNN_LOGE(LNN_LANE, "find forceDownInfo fail, forceDownReqId=%{public}u", forceDownReqId);
560             return ret;
561         }
562         ret = ForceDisconnectWifiDirectWithoutAuth(&forceDownInfo);
563         if (ret != SOFTBUS_OK) {
564             (void)DelForceDownInfo(forceDownReqId);
565             LNN_LOGE(LNN_LANE, "force disconnect wifidirect without auth fail, reason=%{public}d", ret);
566         }
567     }
568     if (ret == SOFTBUS_OK) {
569         ForceDownCondWait(downType, forceDownReqId);
570     }
571     return ret;
572 }
573 
HandleForceDownWifiDirect(const char * networkId,LinkConflictType conflictType,uint32_t p2pRequestId)574 int32_t HandleForceDownWifiDirect(const char *networkId, LinkConflictType conflictType, uint32_t p2pRequestId)
575 {
576     if (networkId == NULL) {
577         LNN_LOGE(LNN_LANE, "invalid param");
578         return SOFTBUS_INVALID_PARAM;
579     }
580     LinkConflictInfo conflictItem;
581     (void)memset_s(&conflictItem, sizeof(LinkConflictInfo), 0, sizeof(LinkConflictInfo));
582     DevIdentifyInfo identifyInfo;
583     (void)memset_s(&identifyInfo, sizeof(DevIdentifyInfo), 0, sizeof(DevIdentifyInfo));
584     identifyInfo.type = IDENTIFY_TYPE_DEV_ID;
585     if (strcpy_s(identifyInfo.devInfo.peerDevId, sizeof(identifyInfo.devInfo.peerDevId), networkId) != EOK) {
586         LNN_LOGE(LNN_LANE, "strcpy peerDevId fail");
587         return SOFTBUS_STRCPY_ERR;
588     }
589     int32_t ret = FindLinkConflictInfoByDevId(&identifyInfo, conflictType, &conflictItem);
590     if (ret != SOFTBUS_OK) {
591         LNN_LOGE(LNN_LANE, "find link conflict info fail");
592         return ret;
593     }
594     RemoveConflictInfoTimelinessMsg(&(conflictItem.identifyInfo), conflictType);
595     (void)DelLinkConflictInfo(&(conflictItem.identifyInfo), conflictType);
596     if (conflictItem.devIdCnt > 0) {
597         char forceDownDevId[NETWORK_ID_BUF_LEN] = {0};
598         if (memcpy_s(forceDownDevId, NETWORK_ID_BUF_LEN, conflictItem.devIdList, NETWORK_ID_BUF_LEN) != EOK) {
599             LNN_LOGE(LNN_LANE, "memcpy networkId fail");
600             FreeLinkConflictDevInfo(&conflictItem);
601             return SOFTBUS_MEM_ERR;
602         }
603         ret = ForceDisconnectWifiDirect(FORCE_DOWN_LANE, forceDownDevId, conflictItem.releaseLink, p2pRequestId);
604         if (ret != SOFTBUS_OK) {
605             LNN_LOGE(LNN_LANE, "force disconnect wifidirect fail");
606         }
607         FreeLinkConflictDevInfo(&conflictItem);
608         return ret;
609     }
610     LNN_LOGI(LNN_LANE, "link conflict device not exists, no need force disconnect");
611     return SOFTBUS_LANE_NOT_FOUND;
612 }
613 
HandleForceDownWifiDirectTrans(const char * udidhashStr,LinkConflictType conflictType)614 int32_t HandleForceDownWifiDirectTrans(const char *udidhashStr, LinkConflictType conflictType)
615 {
616     if (udidhashStr == NULL) {
617         LNN_LOGE(LNN_LANE, "invalid param");
618         return SOFTBUS_INVALID_PARAM;
619     }
620     LinkConflictInfo conflictItem;
621     (void)memset_s(&conflictItem, sizeof(LinkConflictInfo), 0, sizeof(LinkConflictInfo));
622     DevIdentifyInfo identifyInfo;
623     (void)memset_s(&identifyInfo, sizeof(DevIdentifyInfo), 0, sizeof(DevIdentifyInfo));
624     identifyInfo.type = IDENTIFY_TYPE_UDID_HASH;
625     if (strcpy_s(identifyInfo.devInfo.udidHash, sizeof(identifyInfo.devInfo.udidHash), udidhashStr) != EOK) {
626         LNN_LOGE(LNN_LANE, "strcpy peerDevId fail");
627         return SOFTBUS_STRCPY_ERR;
628     }
629     int32_t ret = FindLinkConflictInfoByDevId(&identifyInfo, conflictType, &conflictItem);
630     if (ret != SOFTBUS_OK) {
631         LNN_LOGE(LNN_LANE, "find link conflict info fail");
632         return ret;
633     }
634     RemoveConflictInfoTimelinessMsg(&(conflictItem.identifyInfo), conflictType);
635     (void)DelLinkConflictInfo(&(conflictItem.identifyInfo), conflictType);
636     if (conflictItem.devIdCnt > 0) {
637         char forceDownDevId[NETWORK_ID_BUF_LEN] = {0};
638         if (memcpy_s(forceDownDevId, NETWORK_ID_BUF_LEN, conflictItem.devIdList, NETWORK_ID_BUF_LEN) != EOK) {
639             LNN_LOGE(LNN_LANE, "memcpy networkId fail");
640             FreeLinkConflictDevInfo(&conflictItem);
641             return SOFTBUS_MEM_ERR;
642         }
643         ret = ForceDisconnectWifiDirect(FORCE_DOWN_TRANS, forceDownDevId, conflictItem.releaseLink,
644             INVALID_P2P_REQUEST_ID);
645         if (ret != SOFTBUS_OK) {
646             LNN_LOGE(LNN_LANE, "force disconnect wifidirect fail");
647         }
648         FreeLinkConflictDevInfo(&conflictItem);
649         return ret;
650     }
651     LNN_LOGI(LNN_LANE, "link conflict device not exists, no need force disconnect");
652     return SOFTBUS_LANE_NOT_FOUND;
653 }
654 
InitLinkWifiDirect(void)655 int32_t InitLinkWifiDirect(void)
656 {
657     if (SoftBusMutexInit(&g_linkWifiDirectMutex, NULL) != SOFTBUS_OK) {
658         LNN_LOGE(LNN_INIT, "mutex init fail");
659         return SOFTBUS_NO_INIT;
660     }
661     g_forceDownList = (ListNode *)SoftBusCalloc(sizeof(ListNode));
662     if (g_forceDownList == NULL) {
663         LNN_LOGE(LNN_LANE, "malloc g_forceDownList fail");
664         (void)SoftBusMutexDestroy(&g_linkWifiDirectMutex);
665         return SOFTBUS_MALLOC_ERR;
666     }
667     ListInit(g_forceDownList);
668     return SOFTBUS_OK;
669 }
670 
DeInitLinkWifiDirect(void)671 void DeInitLinkWifiDirect(void)
672 {
673     if (g_forceDownList == NULL) {
674         return;
675     }
676     if (LinkWifiDirectLock() != SOFTBUS_OK) {
677         LNN_LOGE(LNN_LANE, "link wifidirect lock fail");
678         return;
679     }
680     ForceDownInfo *relinkItem = NULL;
681     ForceDownInfo *relinkNext = NULL;
682     LIST_FOR_EACH_ENTRY_SAFE(relinkItem, relinkNext, g_forceDownList, ForceDownInfo, node) {
683         ListDelete(&relinkItem->node);
684         SoftBusFree(relinkItem);
685     }
686     SoftBusFree(g_forceDownList);
687     g_forceDownList = NULL;
688     LinkWifiDirectUnlock();
689     SoftBusMutexUnlock(&g_linkWifiDirectMutex);
690     (void)SoftBusMutexDestroy(&g_linkWifiDirectMutex);
691 }
692