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_conflict.h"
17
18 #include <securec.h>
19
20 #include "anonymizer.h"
21 #include "bus_center_info_key.h"
22 #include "bus_center_manager.h"
23 #include "lnn_lane_link_wifi_direct.h"
24 #include "lnn_log.h"
25 #include "message_handler.h"
26 #include "softbus_adapter_crypto.h"
27 #include "softbus_adapter_mem.h"
28 #include "softbus_common.h"
29 #include "softbus_def.h"
30 #include "softbus_utils.h"
31
32 #define CONFLICT_INFO_TIMELINESS 30000
33 #define CONFLICT_SHORT_HASH_LEN_TMP 8
34
35 typedef enum {
36 MSG_TYPE_CONFLICT_TIMELINESS = 0,
37 MSG_TYPE_CONFLICT_BUTT,
38 } LinkConflictMsgType;
39
40 static SoftBusList g_linkConflictList;
41 static SoftBusHandler g_linkConflictLoopHandler;
42
LinkConflictLock(void)43 static int32_t LinkConflictLock(void)
44 {
45 return SoftBusMutexLock(&g_linkConflictList.lock);
46 }
47
LinkConflictUnlock(void)48 static void LinkConflictUnlock(void)
49 {
50 (void)SoftBusMutexUnlock(&g_linkConflictList.lock);
51 }
52
LinkConflictPostMsgToHandler(int32_t msgType,uint64_t param1,uint64_t param2,void * obj,uint64_t delayMillis)53 static int32_t LinkConflictPostMsgToHandler(int32_t msgType, uint64_t param1, uint64_t param2,
54 void *obj, uint64_t delayMillis)
55 {
56 SoftBusMessage *msg = (SoftBusMessage *)SoftBusCalloc(sizeof(SoftBusMessage));
57 if (msg == NULL) {
58 LNN_LOGE(LNN_LANE, "calloc link conflict handler msg fail");
59 return SOFTBUS_MALLOC_ERR;
60 }
61 if (g_linkConflictLoopHandler.looper == NULL) {
62 LNN_LOGE(LNN_LANE, "linkConflictLoopHandler looper not init");
63 SoftBusFree(msg);
64 return SOFTBUS_NO_INIT;
65 }
66 msg->what = msgType;
67 msg->arg1 = param1;
68 msg->arg2 = param2;
69 msg->handler = &g_linkConflictLoopHandler;
70 msg->obj = obj;
71 if (delayMillis == 0) {
72 g_linkConflictLoopHandler.looper->PostMessage(g_linkConflictLoopHandler.looper, msg);
73 } else {
74 g_linkConflictLoopHandler.looper->PostMessageDelay(g_linkConflictLoopHandler.looper, msg, delayMillis);
75 }
76 return SOFTBUS_OK;
77 }
78
PostConflictInfoTimelinessMsg(const DevIdentifyInfo * info,LinkConflictType conflictType)79 static int32_t PostConflictInfoTimelinessMsg(const DevIdentifyInfo *info, LinkConflictType conflictType)
80 {
81 if (info == NULL) {
82 LNN_LOGE(LNN_LANE, "invalid param");
83 return SOFTBUS_INVALID_PARAM;
84 }
85 char *anonyDevInfo = NULL;
86 Anonymize(info->type == IDENTIFY_TYPE_UDID_HASH ? info->devInfo.udidHash : info->devInfo.peerDevId,
87 &anonyDevInfo);
88 LNN_LOGI(LNN_LANE, "post conflict info timeliness msg, identifyType=%{public}d, devInfo=%{public}s,"
89 " conflictType=%{public}d", info->type, AnonymizeWrapper(anonyDevInfo), conflictType);
90 AnonymizeFree(anonyDevInfo);
91 LinkConflictInfo *conflictItem = (LinkConflictInfo *)SoftBusCalloc(sizeof(LinkConflictInfo));
92 if (conflictItem == NULL) {
93 LNN_LOGE(LNN_LANE, "calloc conflictItem fail");
94 return SOFTBUS_MALLOC_ERR;
95 }
96 if (memcpy_s(&conflictItem->identifyInfo, sizeof(DevIdentifyInfo), info, sizeof(DevIdentifyInfo)) != EOK) {
97 LNN_LOGE(LNN_LANE, "memcpy identifyInfo fail");
98 SoftBusFree(conflictItem);
99 return SOFTBUS_MEM_ERR;
100 }
101 conflictItem->conflictType = conflictType;
102 int32_t ret = LinkConflictPostMsgToHandler(MSG_TYPE_CONFLICT_TIMELINESS, 0, 0,
103 conflictItem, CONFLICT_INFO_TIMELINESS);
104 if (ret != SOFTBUS_OK) {
105 LNN_LOGE(LNN_LANE, "post link conflict msg fail");
106 SoftBusFree(conflictItem);
107 return ret;
108 }
109 return SOFTBUS_OK;
110 }
111
RemoveConflictInfoTimeliness(const SoftBusMessage * msg,void * data)112 static int32_t RemoveConflictInfoTimeliness(const SoftBusMessage *msg, void *data)
113 {
114 if (msg == NULL || msg->obj == NULL || data == NULL) {
115 LNN_LOGE(LNN_LANE, "invalid param");
116 return SOFTBUS_INVALID_PARAM;
117 }
118 LinkConflictInfo *srcInfo = (LinkConflictInfo*)msg->obj;
119 LinkConflictInfo *dstInfo = (LinkConflictInfo*)data;
120 if (msg->what != MSG_TYPE_CONFLICT_TIMELINESS) {
121 return SOFTBUS_INVALID_PARAM;
122 }
123 if (srcInfo->conflictType == dstInfo->conflictType &&
124 memcmp(&srcInfo->identifyInfo, &dstInfo->identifyInfo, sizeof(DevIdentifyInfo)) == 0) {
125 LNN_LOGI(LNN_LANE, "remove timeliness msg succ");
126 SoftBusFree(srcInfo);
127 return SOFTBUS_OK;
128 }
129 return SOFTBUS_INVALID_PARAM;
130 }
131
RemoveConflictInfoTimelinessMsg(const DevIdentifyInfo * inputInfo,LinkConflictType conflictType)132 void RemoveConflictInfoTimelinessMsg(const DevIdentifyInfo *inputInfo, LinkConflictType conflictType)
133 {
134 if (inputInfo == NULL) {
135 LNN_LOGE(LNN_LANE, "invalid param");
136 return;
137 }
138 char *anonyDevInfo = NULL;
139 Anonymize(inputInfo->type == IDENTIFY_TYPE_UDID_HASH ?
140 inputInfo->devInfo.udidHash : inputInfo->devInfo.peerDevId, &anonyDevInfo);
141 LNN_LOGI(LNN_LANE, "remove timeliness msg, identifyType=%{public}d, devInfo=%{public}s, conflictType=%{public}d",
142 inputInfo->type, AnonymizeWrapper(anonyDevInfo), conflictType);
143 AnonymizeFree(anonyDevInfo);
144 LinkConflictInfo conflictItem;
145 (void)memset_s(&conflictItem, sizeof(LinkConflictInfo), 0, sizeof(LinkConflictInfo));
146 if (memcpy_s(&conflictItem.identifyInfo, sizeof(DevIdentifyInfo), inputInfo, sizeof(DevIdentifyInfo)) != EOK) {
147 LNN_LOGE(LNN_LANE, "memcpy identifyInfo fail");
148 return;
149 }
150 conflictItem.conflictType = conflictType;
151 g_linkConflictLoopHandler.looper->RemoveMessageCustom(g_linkConflictLoopHandler.looper,
152 &g_linkConflictLoopHandler, RemoveConflictInfoTimeliness, &conflictItem);
153 }
154
GetConflictTypeWithErrcode(int32_t conflictErrcode)155 LinkConflictType GetConflictTypeWithErrcode(int32_t conflictErrcode)
156 {
157 if (conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_P2P_GO_GC_CONFLICT ||
158 conflictErrcode == SOFTBUS_CONN_PV1_BOTH_GO_ERR ||
159 conflictErrcode == SOFTBUS_CONN_PV1_GC_CONNECTED_TO_ANOTHER_DEVICE ||
160 conflictErrcode == SOFTBUS_CONN_PV2_P2P_GC_AVAILABLE_WITH_MISMATCHED_ROLE) {
161 return CONFLICT_ROLE;
162 }
163 if (conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_HML_NUM_LIMITED_CONFLICT ||
164 conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_P2P_NUM_LIMITED_CONFLICT) {
165 return CONFLICT_LINK_NUM_LIMITED;
166 }
167 if (conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_STA_P2P_HML_55_CONFLICT ||
168 conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_STA_P2P_HML_225_CONFLICT ||
169 conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_STA_P2P_HML_255_CONFLICT ||
170 conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_STA_P2P_HML_525_CONFLICT ||
171 conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_STA_P2P_HML_555_CONFLICT ||
172 conflictErrcode == SOFTBUS_CONN_HML_P2P_DFS_CHANNEL_CONFLICT) {
173 return CONFLICT_THREE_VAP;
174 }
175 if (conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_AP_STA_CHIP_CONFLICT ||
176 conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_AP_P2P_CHIP_CONFLICT ||
177 conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_AP_HML_CHIP_CONFLICT ||
178 conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_AP_STA_HML_CHIP_CONFLICT ||
179 conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_AP_STA_P2P_CHIP_CONFLICT ||
180 conflictErrcode == SOFTBUS_CONN_ACTIVE_TYPE_AP_P2P_HML_CHIP_CONFLICT) {
181 return CONFLICT_SOFTAP;
182 }
183 return CONFLICT_BUTT;
184 }
185
GenerateConflictInfo(const LinkConflictInfo * inputInfo,LinkConflictInfo * outputInfo)186 static int32_t GenerateConflictInfo(const LinkConflictInfo *inputInfo, LinkConflictInfo *outputInfo)
187 {
188 if (inputInfo == NULL || outputInfo == NULL) {
189 LNN_LOGE(LNN_LANE, "invalid param");
190 return SOFTBUS_INVALID_PARAM;
191 }
192 if (memcpy_s(&outputInfo->identifyInfo, sizeof(DevIdentifyInfo), &inputInfo->identifyInfo,
193 sizeof(DevIdentifyInfo)) != EOK) {
194 LNN_LOGE(LNN_LANE, "memcpy identifyInfo fail");
195 return SOFTBUS_MEM_ERR;
196 }
197 if (outputInfo->devIdCnt > 0) {
198 SoftBusFree(outputInfo->devIdList);
199 outputInfo->devIdList = NULL;
200 outputInfo->devIdCnt = 0;
201 }
202 if (inputInfo->devIdCnt > 0) {
203 char (*devIdList)[NETWORK_ID_BUF_LEN] =
204 (char (*)[NETWORK_ID_BUF_LEN])SoftBusCalloc(inputInfo->devIdCnt * NETWORK_ID_BUF_LEN);
205 if (devIdList == NULL) {
206 LNN_LOGE(LNN_LANE, "calloc devIdList fail");
207 return SOFTBUS_MALLOC_ERR;
208 }
209 outputInfo->devIdList = devIdList;
210 if (memcpy_s(devIdList, inputInfo->devIdCnt * NETWORK_ID_BUF_LEN,
211 inputInfo->devIdList, inputInfo->devIdCnt * NETWORK_ID_BUF_LEN) != EOK) {
212 LNN_LOGE(LNN_LANE, "memcpy devIdList fail");
213 SoftBusFree(devIdList);
214 outputInfo->devIdList = NULL;
215 return SOFTBUS_MEM_ERR;
216 }
217 outputInfo->devIdCnt = inputInfo->devIdCnt;
218 }
219 outputInfo->releaseLink = inputInfo->releaseLink;
220 outputInfo->conflictType = inputInfo->conflictType;
221 return SOFTBUS_OK;
222 }
223
UpdateExistsLinkConflictInfo(const LinkConflictInfo * inputInfo)224 static int32_t UpdateExistsLinkConflictInfo(const LinkConflictInfo *inputInfo)
225 {
226 if (inputInfo == NULL) {
227 LNN_LOGE(LNN_LANE, "invalid param");
228 return SOFTBUS_INVALID_PARAM;
229 }
230 if (LinkConflictLock() != SOFTBUS_OK) {
231 LNN_LOGE(LNN_LANE, "linkConflictInfo lock fail");
232 return SOFTBUS_LOCK_ERR;
233 }
234 LinkConflictInfo *item = NULL;
235 LinkConflictInfo *next = NULL;
236 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_linkConflictList.list, LinkConflictInfo, node) {
237 if (item->conflictType == inputInfo->conflictType &&
238 memcmp(&item->identifyInfo, &inputInfo->identifyInfo, sizeof(DevIdentifyInfo)) == 0) {
239 int32_t ret = GenerateConflictInfo(inputInfo, item);
240 if (ret != SOFTBUS_OK) {
241 LNN_LOGE(LNN_LANE, "generate conflictDevInfo fail");
242 LinkConflictUnlock();
243 return ret;
244 }
245 LinkConflictUnlock();
246 return SOFTBUS_OK;
247 }
248 }
249 LinkConflictUnlock();
250 return SOFTBUS_LANE_NOT_FOUND;
251 }
252
CreateNewLinkConflictInfo(const LinkConflictInfo * inputInfo)253 static int32_t CreateNewLinkConflictInfo(const LinkConflictInfo *inputInfo)
254 {
255 LinkConflictInfo *linkConflictItem = (LinkConflictInfo *)SoftBusCalloc(sizeof(LinkConflictInfo));
256 if (linkConflictItem == NULL) {
257 LNN_LOGE(LNN_LANE, "calloc linkConflictItem fail");
258 return SOFTBUS_MALLOC_ERR;
259 }
260 int32_t ret = GenerateConflictInfo(inputInfo, linkConflictItem);
261 if (ret != SOFTBUS_OK) {
262 LNN_LOGE(LNN_LANE, "generate conflictDevInfo fail");
263 SoftBusFree(linkConflictItem);
264 return ret;
265 }
266 if (LinkConflictLock() != SOFTBUS_OK) {
267 LNN_LOGE(LNN_LANE, "linkConflict lock fail");
268 SoftBusFree(linkConflictItem);
269 return SOFTBUS_LOCK_ERR;
270 }
271 ListAdd(&g_linkConflictList.list, &linkConflictItem->node);
272 g_linkConflictList.cnt++;
273 LinkConflictUnlock();
274 char *anonyDevInfo = NULL;
275 Anonymize(inputInfo->identifyInfo.type == IDENTIFY_TYPE_UDID_HASH ?
276 inputInfo->identifyInfo.devInfo.udidHash : inputInfo->identifyInfo.devInfo.peerDevId, &anonyDevInfo);
277 LNN_LOGI(LNN_LANE, "create new conflict link success, identifyType=%{public}d, devInfo=%{public}s, "
278 "conflictType=%{public}d, releaseLink=%{public}d", inputInfo->identifyInfo.type, AnonymizeWrapper(anonyDevInfo),
279 inputInfo->conflictType, inputInfo->releaseLink);
280 AnonymizeFree(anonyDevInfo);
281 return SOFTBUS_OK;
282 }
283
DelLinkConflictInfo(const DevIdentifyInfo * inputInfo,LinkConflictType conflictType)284 int32_t DelLinkConflictInfo(const DevIdentifyInfo *inputInfo, LinkConflictType conflictType)
285 {
286 if (inputInfo == NULL) {
287 LNN_LOGE(LNN_LANE, "invalid param");
288 return SOFTBUS_INVALID_PARAM;
289 }
290 if (LinkConflictLock() != SOFTBUS_OK) {
291 LNN_LOGE(LNN_LANE, "linkConflict lock fail");
292 return SOFTBUS_LOCK_ERR;
293 }
294 char *anonyDevInfo = NULL;
295 Anonymize(inputInfo->type == IDENTIFY_TYPE_UDID_HASH ?
296 inputInfo->devInfo.udidHash : inputInfo->devInfo.peerDevId, &anonyDevInfo);
297 LNN_LOGI(LNN_LANE, "start to del link conflict info by identifyType=%{public}d, devInfo=%{public}s,"
298 " conflictType=%{public}d", inputInfo->type, AnonymizeWrapper(anonyDevInfo), conflictType);
299 AnonymizeFree(anonyDevInfo);
300 LinkConflictInfo *item = NULL;
301 LinkConflictInfo *next = NULL;
302 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_linkConflictList.list, LinkConflictInfo, node) {
303 if (item->conflictType == conflictType &&
304 memcmp(&item->identifyInfo, inputInfo, sizeof(DevIdentifyInfo)) == 0) {
305 ListDelete(&item->node);
306 if (item->devIdCnt > 0) {
307 SoftBusFree(item->devIdList);
308 item->devIdList = NULL;
309 }
310 if (item->devIpCnt > 0) {
311 SoftBusFree(item->devIpList);
312 item->devIpList = NULL;
313 }
314 SoftBusFree(item);
315 g_linkConflictList.cnt--;
316 LinkConflictUnlock();
317 return SOFTBUS_OK;
318 }
319 }
320 LinkConflictUnlock();
321 LNN_LOGE(LNN_LANE, "not found link conflict info when del");
322 return SOFTBUS_LANE_NOT_FOUND;
323 }
324
AddLinkConflictInfo(const LinkConflictInfo * inputInfo)325 int32_t AddLinkConflictInfo(const LinkConflictInfo *inputInfo)
326 {
327 if (inputInfo == NULL) {
328 LNN_LOGE(LNN_LANE, "invalid param");
329 return SOFTBUS_INVALID_PARAM;
330 }
331 int32_t ret = UpdateExistsLinkConflictInfo(inputInfo);
332 if (ret == SOFTBUS_OK) {
333 LNN_LOGE(LNN_LANE, "update link conflict info succ");
334 RemoveConflictInfoTimelinessMsg(&inputInfo->identifyInfo, inputInfo->conflictType);
335 ret = PostConflictInfoTimelinessMsg(&inputInfo->identifyInfo, inputInfo->conflictType);
336 if (ret != SOFTBUS_OK) {
337 (void)DelLinkConflictInfo(&inputInfo->identifyInfo, inputInfo->conflictType);
338 LNN_LOGE(LNN_LANE, "post conflict info timeliness msg fail, reason=%{public}d", ret);
339 return ret;
340 }
341 return SOFTBUS_OK;
342 }
343 ret = CreateNewLinkConflictInfo(inputInfo);
344 if (ret != SOFTBUS_OK) {
345 LNN_LOGE(LNN_LANE, "create new link conflict info fail, reason=%{public}d", ret);
346 return ret;
347 }
348 ret = PostConflictInfoTimelinessMsg(&inputInfo->identifyInfo, inputInfo->conflictType);
349 if (ret != SOFTBUS_OK) {
350 (void)DelLinkConflictInfo(&inputInfo->identifyInfo, inputInfo->conflictType);
351 LNN_LOGE(LNN_LANE, "post conflict info timeliness msg fail, reason=%{public}d", ret);
352 return ret;
353 }
354 return SOFTBUS_OK;
355 }
356
GenerateConflictInfoWithDevIdHash(const DevIdentifyInfo * inputInfo,DevIdentifyInfo * outputInfo)357 static void GenerateConflictInfoWithDevIdHash(const DevIdentifyInfo *inputInfo, DevIdentifyInfo *outputInfo)
358 {
359 char peerUdid[UDID_BUF_LEN] = {0};
360 int32_t ret = LnnGetRemoteStrInfo(inputInfo->devInfo.peerDevId, STRING_KEY_DEV_UDID, peerUdid, UDID_BUF_LEN);
361 if (ret != SOFTBUS_OK) {
362 LNN_LOGE(LNN_LANE, "get udid error, ret=%{public}d", ret);
363 return;
364 }
365 uint8_t udidHash[UDID_HASH_LEN] = {0};
366 ret = SoftBusGenerateStrHash((const unsigned char*)peerUdid, strlen(peerUdid), udidHash);
367 if (ret != SOFTBUS_OK) {
368 LNN_LOGE(LNN_LANE, "generate udidHash fail, ret=%{public}d", ret);
369 return;
370 }
371 ret = ConvertBytesToHexString(outputInfo->devInfo.udidHash, CONFLICT_UDIDHASH_STR_LEN + 1, udidHash,
372 CONFLICT_SHORT_HASH_LEN_TMP);
373 if (ret != SOFTBUS_OK) {
374 LNN_LOGE(LNN_LANE, "convert bytes to string fail, ret=%{public}d", ret);
375 return;
376 }
377 }
378
FindLinkConflictInfoByDevId(const DevIdentifyInfo * inputInfo,LinkConflictType conflictType,LinkConflictInfo * outputInfo)379 int32_t FindLinkConflictInfoByDevId(const DevIdentifyInfo *inputInfo, LinkConflictType conflictType,
380 LinkConflictInfo *outputInfo)
381 {
382 if (inputInfo == NULL || outputInfo == NULL) {
383 LNN_LOGE(LNN_LANE, "invalid param");
384 return SOFTBUS_INVALID_PARAM;
385 }
386 DevIdentifyInfo hashInfo;
387 (void)memset_s(&hashInfo, sizeof(DevIdentifyInfo), 0, sizeof(DevIdentifyInfo));
388 if (inputInfo->type == IDENTIFY_TYPE_DEV_ID) {
389 hashInfo.type = IDENTIFY_TYPE_UDID_HASH;
390 GenerateConflictInfoWithDevIdHash(inputInfo, &hashInfo);
391 }
392 if (LinkConflictLock() != SOFTBUS_OK) {
393 LNN_LOGE(LNN_LANE, "linkConflict lock fail");
394 return SOFTBUS_LOCK_ERR;
395 }
396 LinkConflictInfo *item = NULL;
397 LinkConflictInfo *next = NULL;
398 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_linkConflictList.list, LinkConflictInfo, node) {
399 if (item->conflictType == conflictType &&
400 (memcmp(&item->identifyInfo, inputInfo, sizeof(DevIdentifyInfo)) == 0 ||
401 memcmp(&item->identifyInfo, &hashInfo, sizeof(DevIdentifyInfo)) == 0)) {
402 int32_t ret = GenerateConflictInfo(item, outputInfo);
403 if (ret != SOFTBUS_OK) {
404 LNN_LOGE(LNN_LANE, "generate link conflict devInfo fail");
405 LinkConflictUnlock();
406 return ret;
407 }
408 LinkConflictUnlock();
409 return SOFTBUS_OK;
410 }
411 }
412 LinkConflictUnlock();
413 char *anonyDevInfo = NULL;
414 Anonymize(inputInfo->type == IDENTIFY_TYPE_UDID_HASH ?
415 inputInfo->devInfo.udidHash : inputInfo->devInfo.peerDevId, &anonyDevInfo);
416 LNN_LOGE(LNN_LANE, "not found link conflict info by identifyType=%{public}d, devInfo=%{public}s,"
417 " conflictType=%{public}d", inputInfo->type, AnonymizeWrapper(anonyDevInfo), conflictType);
418 AnonymizeFree(anonyDevInfo);
419 return SOFTBUS_LANE_NOT_FOUND;
420 }
421
CheckLinkConflictByReleaseLink(LaneLinkType releaseLink)422 int32_t CheckLinkConflictByReleaseLink(LaneLinkType releaseLink)
423 {
424 if (releaseLink != LANE_HML) {
425 LNN_LOGE(LNN_LANE, "invalid releaseLink=%{public}d", releaseLink);
426 return SOFTBUS_INVALID_PARAM;
427 }
428 if (LinkConflictLock() != SOFTBUS_OK) {
429 LNN_LOGE(LNN_LANE, "linkConflict lock fail");
430 return SOFTBUS_LOCK_ERR;
431 }
432 LinkConflictInfo *item = NULL;
433 LinkConflictInfo *next = NULL;
434 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_linkConflictList.list, LinkConflictInfo, node) {
435 if (item->releaseLink == releaseLink) {
436 LinkConflictUnlock();
437 LNN_LOGI(LNN_LANE, "link conflict info matched by releaseLink=%{public}d", releaseLink);
438 return SOFTBUS_OK;
439 }
440 }
441 LinkConflictUnlock();
442 return SOFTBUS_LANE_NOT_FOUND;
443 }
444
HandleConflictInfoTimeliness(SoftBusMessage * msg)445 static void HandleConflictInfoTimeliness(SoftBusMessage *msg)
446 {
447 if (msg->obj == NULL) {
448 LNN_LOGE(LNN_LANE, "invalid msg->obj");
449 return;
450 }
451 LinkConflictInfo *conflictItem = (LinkConflictInfo*)msg->obj;
452 LNN_LOGI(LNN_LANE, "handle conflict info timeliness");
453 if (DelLinkConflictInfo(&conflictItem->identifyInfo, conflictItem->conflictType) != SOFTBUS_OK) {
454 LNN_LOGE(LNN_LANE, "del link conflict info fail");
455 }
456 SoftBusFree(conflictItem);
457 }
458
MsgHandler(SoftBusMessage * msg)459 static void MsgHandler(SoftBusMessage *msg)
460 {
461 if (msg == NULL) {
462 LNN_LOGE(LNN_LANE, "invalid msg");
463 return;
464 }
465 switch (msg->what) {
466 case MSG_TYPE_CONFLICT_TIMELINESS:
467 HandleConflictInfoTimeliness(msg);
468 break;
469 default:
470 LNN_LOGE(LNN_LANE, "msg type=%{public}d not support", msg->what);
471 break;
472 }
473 return;
474 }
475
InitLinkConflictLooper(void)476 static int32_t InitLinkConflictLooper(void)
477 {
478 g_linkConflictLoopHandler.name = "linkConflictLooper";
479 g_linkConflictLoopHandler.HandleMessage = MsgHandler;
480 g_linkConflictLoopHandler.looper = GetLooper(LOOP_TYPE_LNN);
481 if (g_linkConflictLoopHandler.looper == NULL) {
482 LNN_LOGE(LNN_LANE, "link conflict init looper fail");
483 return SOFTBUS_NO_INIT;
484 }
485 return SOFTBUS_OK;
486 }
487
InitLaneLinkConflict(void)488 int32_t InitLaneLinkConflict(void)
489 {
490 if (InitLinkConflictLooper() != SOFTBUS_OK) {
491 LNN_LOGE(LNN_LANE, "init link conflict looper fail");
492 return SOFTBUS_NO_INIT;
493 }
494 if (SoftBusMutexInit(&g_linkConflictList.lock, NULL) != SOFTBUS_OK) {
495 LNN_LOGE(LNN_LANE, "link conflict mutex init fail");
496 return SOFTBUS_NO_INIT;
497 }
498 ListInit(&g_linkConflictList.list);
499 g_linkConflictList.cnt = 0;
500
501 if (InitLinkWifiDirect() != SOFTBUS_OK) {
502 LNN_LOGE(LNN_LANE, "init link wifidirect fail");
503 (void)SoftBusMutexDestroy(&g_linkConflictList.lock);
504 return SOFTBUS_NO_INIT;
505 }
506 return SOFTBUS_OK;
507 }
508
DeinitLaneLinkConflict(void)509 void DeinitLaneLinkConflict(void)
510 {
511 DeInitLinkWifiDirect();
512 g_linkConflictLoopHandler.HandleMessage = NULL;
513 g_linkConflictLoopHandler.looper = NULL;
514 if (LinkConflictLock() != SOFTBUS_OK) {
515 LNN_LOGE(LNN_LANE, "linkConflictInfo lock fail");
516 return;
517 }
518 LinkConflictInfo *item = NULL;
519 LinkConflictInfo *next = NULL;
520 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_linkConflictList.list, LinkConflictInfo, node) {
521 ListDelete(&item->node);
522 if (item->devIdCnt > 0) {
523 SoftBusFree(item->devIdList);
524 }
525 if (item->devIpCnt > 0) {
526 SoftBusFree(item->devIpList);
527 }
528 SoftBusFree(item);
529 g_linkConflictList.cnt--;
530 }
531 LinkConflictUnlock();
532 (void)SoftBusMutexDestroy(&g_linkConflictList.lock);
533 }
534