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