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