• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_trans_lane.h"
17 
18 #include <securec.h>
19 
20 #include "bus_center_manager.h"
21 #include "common_list.h"
22 #include "lnn_lane.h"
23 #include "lnn_lane_common.h"
24 #include "lnn_lane_def.h"
25 #include "lnn_lane_interface.h"
26 #include "lnn_lane_link.h"
27 #include "lnn_lane_model.h"
28 #include "lnn_lane_select.h"
29 #include "message_handler.h"
30 #include "wifi_direct_manager.h"
31 #include "softbus_adapter_mem.h"
32 #include "softbus_def.h"
33 #include "softbus_errcode.h"
34 #include "softbus_log.h"
35 #include "softbus_utils.h"
36 #include "softbus_protocol_def.h"
37 
38 typedef enum {
39     MSG_TYPE_LANE_TRIGGER_LINK = 0,
40     MSG_TYPE_LANE_LINK_SUCCESS,
41     MSG_TYPE_LANE_LINK_FAIL,
42     MSG_TYPE_LANE_LINK_EXCEPTION,
43 } LaneMsgType;
44 
45 typedef struct {
46     ListNode node;
47     uint32_t laneId;
48     TransOption info;
49     LaneLinkType type;
50     char p2pMac[MAC_ADDR_STR_LEN];
51     ILaneListener listener;
52 } TransReqInfo;
53 
54 typedef struct {
55     uint32_t cnt;
56     ListNode list;
57 } TransLaneList;
58 
59 typedef struct {
60     ListNode node;
61     uint32_t laneId;
62     int32_t pid;
63     char networkId[NETWORK_ID_BUF_LEN];
64     LaneTransType transType;
65     LanePreferredLinkList *linkList; /* Mem provided by laneSelect module */
66     uint32_t listNum;
67     uint32_t linkRetryIdx;
68     bool networkDelegate;
69 } LaneLinkNodeInfo;
70 
71 static ListNode g_multiLinkList;
72 static SoftBusMutex g_transLaneMutex;
73 static TransLaneList *g_requestList = NULL;
74 static SoftBusHandler g_laneLoopHandler;
75 static ILaneIdStateListener *g_laneIdCallback = NULL;
76 
Lock(void)77 static int32_t Lock(void)
78 {
79     return SoftBusMutexLock(&g_transLaneMutex);
80 }
81 
Unlock(void)82 static void Unlock(void)
83 {
84     (void)SoftBusMutexUnlock(&g_transLaneMutex);
85 }
86 
PostMsgToHandler(int32_t msgType,uint64_t param1,uint64_t param2,void * obj)87 NO_SANITIZE("cfi") static int32_t PostMsgToHandler(int32_t msgType, uint64_t param1, uint64_t param2, void *obj)
88 {
89     SoftBusMessage *msg = (SoftBusMessage *)SoftBusCalloc(sizeof(SoftBusMessage));
90     if (msg == NULL) {
91         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "[transLane]create handler msg failed");
92         return SOFTBUS_MALLOC_ERR;
93     }
94     msg->what = msgType;
95     msg->arg1 = param1;
96     msg->arg2 = param2;
97     msg->handler = &g_laneLoopHandler;
98     msg->obj = obj;
99     g_laneLoopHandler.looper->PostMessage(g_laneLoopHandler.looper, msg);
100     return SOFTBUS_OK;
101 }
102 
LinkSuccess(uint32_t laneId,const LaneLinkInfo * linkInfo)103 static void LinkSuccess(uint32_t laneId, const LaneLinkInfo *linkInfo)
104 {
105     if (linkInfo == NULL) {
106         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "linkSuccess param invalid");
107         return;
108     }
109     LaneLinkInfo *linkParam = (LaneLinkInfo *)SoftBusCalloc(sizeof(LaneLinkInfo));
110     if (linkParam == NULL) {
111         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "linkSuccess info malloc fail");
112         return;
113     }
114     if (memcpy_s(linkParam, sizeof(LaneLinkInfo), linkInfo, sizeof(LaneLinkInfo)) != EOK) {
115         SoftBusFree(linkParam);
116         return;
117     }
118     if (PostMsgToHandler(MSG_TYPE_LANE_LINK_SUCCESS, laneId, 0, linkParam) != SOFTBUS_OK) {
119         SoftBusFree(linkParam);
120         return;
121     }
122 }
123 
LinkFail(uint32_t laneId,int32_t reason)124 static void LinkFail(uint32_t laneId, int32_t reason)
125 {
126     if (PostMsgToHandler(MSG_TYPE_LANE_LINK_FAIL, laneId, reason, NULL) != SOFTBUS_OK) {
127         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "post lanelink fail msg err");
128         return;
129     }
130 }
131 
LinkException(uint32_t laneId,int32_t reason)132 static void LinkException(uint32_t laneId, int32_t reason)
133 {
134     if (PostMsgToHandler(MSG_TYPE_LANE_LINK_EXCEPTION, laneId, reason, NULL) != SOFTBUS_OK) {
135         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "post laneStateException msg err");
136         return;
137     }
138 }
139 
DeleteLaneLinkNode(uint32_t laneId)140 static void DeleteLaneLinkNode(uint32_t laneId)
141 {
142     if (Lock() != SOFTBUS_OK) {
143         return;
144     }
145     LaneLinkNodeInfo *item = NULL;
146     LaneLinkNodeInfo *next = NULL;
147     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_multiLinkList, LaneLinkNodeInfo, node) {
148         if (item->laneId == laneId) {
149             ListDelete(&item->node);
150             SoftBusFree(item->linkList);
151             SoftBusFree(item);
152             break;
153         }
154     }
155     Unlock();
156 }
157 
TriggerLink(uint32_t laneId,TransOption * request,LanePreferredLinkList * recommendLinkList,uint32_t listNum)158 static int32_t TriggerLink(uint32_t laneId, TransOption *request,
159     LanePreferredLinkList *recommendLinkList, uint32_t listNum)
160 {
161     LaneLinkNodeInfo *linkNode = (LaneLinkNodeInfo *)SoftBusCalloc(sizeof(LaneLinkNodeInfo));
162     if (linkNode == NULL) {
163         return SOFTBUS_MALLOC_ERR;
164     }
165     if (memcpy_s(linkNode->networkId, NETWORK_ID_BUF_LEN,
166         request->networkId, NETWORK_ID_BUF_LEN) != EOK) {
167         SoftBusFree(linkNode);
168         return SOFTBUS_MEM_ERR;
169     }
170     linkNode->laneId = laneId;
171     linkNode->linkRetryIdx = 0;
172     linkNode->listNum = listNum;
173     linkNode->linkList = recommendLinkList;
174     linkNode->transType = request->transType;
175     linkNode->pid = request->pid;
176     linkNode->networkDelegate = request->networkDelegate;
177     ListInit(&linkNode->node);
178     if (Lock() != SOFTBUS_OK) {
179         SoftBusFree(linkNode);
180         return SOFTBUS_LOCK_ERR;
181     }
182     ListTailInsert(&g_multiLinkList, &linkNode->node);
183     Unlock();
184     if (PostMsgToHandler(MSG_TYPE_LANE_TRIGGER_LINK, laneId, request->acceptableProtocols, NULL) != SOFTBUS_OK) {
185         DeleteLaneLinkNode(laneId);
186         return SOFTBUS_ERR;
187     }
188     return SOFTBUS_OK;
189 }
190 
CreateRequestNode(uint32_t laneId,const TransOption * option,const ILaneListener * listener)191 static TransReqInfo *CreateRequestNode(uint32_t laneId, const TransOption *option, const ILaneListener *listener)
192 {
193     TransReqInfo *newNode = (TransReqInfo *)SoftBusCalloc(sizeof(TransReqInfo));
194     if (newNode == NULL) {
195         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "CreateRequestNode malloc fail");
196         return NULL;
197     }
198     if (memcpy_s(&newNode->listener, sizeof(ILaneListener), listener, sizeof(ILaneListener)) != EOK) {
199         SoftBusFree(newNode);
200         return NULL;
201     }
202     if (memcpy_s(&newNode->info, sizeof(TransOption), option, sizeof(TransOption)) != EOK) {
203         SoftBusFree(newNode);
204         return NULL;
205     }
206     newNode->laneId = laneId;
207     ListInit(&newNode->node);
208     return newNode;
209 }
210 
DeleteRequestNode(uint32_t laneId)211 static void DeleteRequestNode(uint32_t laneId)
212 {
213     if (Lock() != SOFTBUS_OK) {
214         return;
215     }
216     TransReqInfo *item = NULL;
217     TransReqInfo *next = NULL;
218     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_requestList->list, TransReqInfo, node) {
219         if (item->laneId == laneId) {
220             ListDelete(&item->node);
221             SoftBusFree(item);
222             g_requestList->cnt--;
223             break;
224         }
225     }
226     Unlock();
227 }
228 
Alloc(uint32_t laneId,const LaneRequestOption * request,const ILaneListener * listener)229 static int32_t Alloc(uint32_t laneId, const LaneRequestOption *request, const ILaneListener *listener)
230 {
231     if ((request == NULL) || (request->type != LANE_TYPE_TRANS)) {
232         return SOFTBUS_INVALID_PARAM;
233     }
234     TransOption *transRequest = (TransOption *)&request->requestInfo.trans;
235     LaneSelectParam selectParam;
236     (void)memset_s(&selectParam, sizeof(LaneSelectParam), 0, sizeof(LaneSelectParam));
237     selectParam.transType = transRequest->transType;
238     selectParam.expectedBw = transRequest->expectedBw;
239     if (memcpy_s(&selectParam.list, sizeof(selectParam.list),
240         &transRequest->expectedLink, sizeof(transRequest->expectedLink)) != EOK) {
241         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "memcpy fail");
242         return SOFTBUS_MEM_ERR;
243     }
244     LanePreferredLinkList *recommendLinkList = (LanePreferredLinkList *)SoftBusMalloc(sizeof(LanePreferredLinkList));
245     recommendLinkList->linkTypeNum = 0;
246     uint32_t listNum = 0;
247     if (SelectLane((const char *)transRequest->networkId, &selectParam, recommendLinkList, &listNum) != SOFTBUS_OK) {
248         return SOFTBUS_ERR;
249     }
250     if (recommendLinkList->linkTypeNum == 0) {
251         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "no link resources available, alloc fail");
252         return SOFTBUS_ERR;
253     }
254     SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "select lane link success, linkNum:%d", listNum);
255     TransReqInfo *newItem = CreateRequestNode(laneId, transRequest, listener);
256     if (newItem == NULL) {
257         SoftBusFree(recommendLinkList);
258         return SOFTBUS_ERR;
259     }
260     if (Lock() != SOFTBUS_OK) {
261         SoftBusFree(newItem);
262         SoftBusFree(recommendLinkList);
263         return SOFTBUS_ERR;
264     }
265     ListTailInsert(&g_requestList->list, &newItem->node);
266     g_requestList->cnt++;
267     Unlock();
268     if (TriggerLink(laneId, transRequest, recommendLinkList, listNum) != SOFTBUS_OK) {
269         SoftBusFree(recommendLinkList);
270         DeleteRequestNode(laneId);
271         return SOFTBUS_ERR;
272     }
273     return SOFTBUS_OK;
274 }
275 
UnbindLaneId(uint32_t laneId,const TransReqInfo * infoNode)276 NO_SANITIZE("cfi") static void UnbindLaneId(uint32_t laneId, const TransReqInfo *infoNode)
277 {
278     LaneGenerateParam param;
279     param.linkType = infoNode->type;
280     param.transType = infoNode->info.transType;
281     param.priority = 0; /* default:0 */
282     uint32_t profileId = GenerateLaneProfileId(&param);
283     g_laneIdCallback->OnLaneIdDisabled(laneId, profileId);
284     UnbindLaneIdFromProfile(laneId, profileId);
285 }
286 
Free(uint32_t laneId)287 static int32_t Free(uint32_t laneId)
288 {
289     if (Lock() != SOFTBUS_OK) {
290         return SOFTBUS_ERR;
291     }
292     TransReqInfo *item = NULL;
293     TransReqInfo *next = NULL;
294     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_requestList->list, TransReqInfo, node) {
295         if (item->laneId == laneId) {
296             ListDelete(&item->node);
297             g_requestList->cnt--;
298             Unlock();
299             DestroyLink(item->info.networkId, laneId, item->type, item->info.pid);
300             UnbindLaneId(laneId, item);
301             SoftBusFree(item);
302             return SOFTBUS_OK;
303         }
304     }
305     Unlock();
306     return SOFTBUS_OK;
307 }
308 
GetLaneReqInfo(uint32_t laneId,TransReqInfo * reqInfo)309 static int32_t GetLaneReqInfo(uint32_t laneId, TransReqInfo *reqInfo)
310 {
311     if (Lock() != SOFTBUS_OK) {
312         return SOFTBUS_ERR;
313     }
314     bool isFound = false;
315     TransReqInfo *item = NULL;
316     LIST_FOR_EACH_ENTRY(item, &g_requestList->list, TransReqInfo, node) {
317         if (item->laneId == laneId) {
318             isFound = true;
319             break;
320         }
321     }
322     if (isFound == false) {
323         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "[transLane] cannot find reqInfo");
324         Unlock();
325         return SOFTBUS_ERR;
326     }
327     if (memcpy_s(reqInfo, sizeof(TransReqInfo), item, sizeof(TransReqInfo)) != EOK) {
328         Unlock();
329         return SOFTBUS_ERR;
330     }
331     Unlock();
332     return SOFTBUS_OK;
333 }
334 
UpdateP2pInfo(TransReqInfo * nodeInfo)335 static void UpdateP2pInfo(TransReqInfo *nodeInfo)
336 {
337     if (nodeInfo->type != LANE_P2P) {
338         return;
339     }
340     if (LnnGetRemoteStrInfo(nodeInfo->info.networkId, STRING_KEY_P2P_MAC,
341         nodeInfo->p2pMac, MAC_ADDR_STR_LEN) != SOFTBUS_OK) {
342         LLOGE("get remote p2p mac fail.");
343         return;
344     }
345 }
346 
UpdateLinkType(uint32_t laneId,LaneLinkType linkType)347 static void UpdateLinkType(uint32_t laneId, LaneLinkType linkType)
348 {
349     if (Lock() != SOFTBUS_OK) {
350         return;
351     }
352     TransReqInfo *item = NULL;
353     LIST_FOR_EACH_ENTRY(item, &g_requestList->list, TransReqInfo, node) {
354         if (item->laneId == laneId) {
355             item->type = linkType;
356             UpdateP2pInfo(item);
357             break;
358         }
359     }
360     Unlock();
361 }
362 
NotifyLaneAllocSuccess(uint32_t laneId,const LaneLinkInfo * info)363 NO_SANITIZE("cfi") static void NotifyLaneAllocSuccess(uint32_t laneId, const LaneLinkInfo *info)
364 {
365     TransReqInfo reqInfo;
366     if (GetLaneReqInfo(laneId, &reqInfo) != SOFTBUS_OK) {
367         return;
368     }
369     LaneProfile profile;
370     LaneConnInfo connInfo;
371     (void)memset_s(&profile, sizeof(LaneProfile), 0, sizeof(LaneProfile));
372     if (LaneInfoProcess(info, &connInfo, &profile) != SOFTBUS_OK) {
373         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "lane alloc success, but laneInfo proc fail");
374         return;
375     }
376     profile.content = reqInfo.info.transType;
377     if (BindLaneIdToProfile(laneId, &profile) != SOFTBUS_OK) {
378         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "bind laneId to profile fail");
379     }
380     SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "Notify laneAlloc succ, laneId:%d, linkType:%d", laneId, info->type);
381     reqInfo.listener.OnLaneRequestSuccess(laneId, &connInfo);
382     UpdateLinkType(laneId, info->type);
383     LaneGenerateParam param;
384     param.linkType = profile.linkType;
385     param.transType = profile.content;
386     param.priority = profile.priority;
387     uint32_t profileId = GenerateLaneProfileId(&param);
388     g_laneIdCallback->OnLaneIdEnabled(laneId, profileId);
389 }
390 
NotifyLaneAllocFail(uint32_t laneId,int32_t reason)391 NO_SANITIZE("cfi") static void NotifyLaneAllocFail(uint32_t laneId, int32_t reason)
392 {
393     TransReqInfo reqInfo;
394     if (GetLaneReqInfo(laneId, &reqInfo) != SOFTBUS_OK) {
395         return;
396     }
397     SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "Notify laneAlloc fail, laneId:0x%x, reason:%d", laneId, reason);
398     reqInfo.listener.OnLaneRequestFail(laneId, LANE_LINK_FAILED);
399     if (Lock() != SOFTBUS_OK) {
400         return;
401     }
402     TransReqInfo *item = NULL;
403     TransReqInfo *next = NULL;
404     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_requestList->list, TransReqInfo, node) {
405         if (item->laneId == laneId) {
406             ListDelete(&item->node);
407             SoftBusFree(item);
408             g_requestList->cnt--;
409             break;
410         }
411     }
412     Unlock();
413 }
414 
NotifyLaneStateChange(uint32_t laneId,int32_t state)415 static void NotifyLaneStateChange(uint32_t laneId, int32_t state)
416 {
417     TransReqInfo reqInfo;
418     if (GetLaneReqInfo(laneId, &reqInfo) != SOFTBUS_OK) {
419         return;
420     }
421     LaneState laneState = LANE_STATE_OK;
422     if (state != SOFTBUS_OK) {
423         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "lane state is changed, state:%d", state);
424         laneState = LANE_STATE_EXCEPTION;
425     }
426     reqInfo.listener.OnLaneStateChange(laneId, laneState);
427 }
428 
GetLaneLinkNodeWithoutLock(uint32_t laneId)429 static LaneLinkNodeInfo *GetLaneLinkNodeWithoutLock(uint32_t laneId)
430 {
431     LaneLinkNodeInfo *linkNode = NULL;
432     LIST_FOR_EACH_ENTRY(linkNode, &g_multiLinkList, LaneLinkNodeInfo, node) {
433         if (linkNode->laneId == laneId) {
434             return linkNode;
435         }
436     }
437     return NULL;
438 }
439 
LaneTriggerLink(SoftBusMessage * msg)440 static void LaneTriggerLink(SoftBusMessage *msg)
441 {
442     uint32_t laneId = msg->arg1;
443     ProtocolType acceptableProtocols = (ProtocolType)msg->arg2;
444     LaneLinkCb linkCb = {
445         .OnLaneLinkSuccess = LinkSuccess,
446         .OnLaneLinkFail = LinkFail,
447         .OnLaneLinkException = LinkException,
448     };
449     LinkRequest requestInfo = { 0 };
450     if (Lock() != SOFTBUS_OK) {
451         return;
452     }
453     LaneLinkNodeInfo *nodeInfo = GetLaneLinkNodeWithoutLock(laneId);
454     if (nodeInfo == NULL) {
455         Unlock();
456         return;
457     }
458     if (nodeInfo->linkRetryIdx >= nodeInfo->listNum) {
459         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "All linkType have been tried");
460         Unlock();
461         return;
462     }
463     requestInfo.networkDelegate = nodeInfo->networkDelegate;
464     requestInfo.linkType = nodeInfo->linkList->linkType[nodeInfo->linkRetryIdx];
465     nodeInfo->linkRetryIdx++;
466     Unlock();
467     requestInfo.pid = nodeInfo->pid;
468     requestInfo.transType = nodeInfo->transType;
469     requestInfo.acceptableProtocols = acceptableProtocols;
470     if (memcpy_s(requestInfo.peerNetworkId, sizeof(requestInfo.peerNetworkId),
471         nodeInfo->networkId, sizeof(nodeInfo->networkId)) != EOK) {
472         return;
473     }
474     int32_t ret = BuildLink(&requestInfo, laneId, &linkCb);
475     if (ret == SOFTBUS_OK) {
476         return;
477     }
478     if (PostMsgToHandler(MSG_TYPE_LANE_LINK_FAIL, laneId, acceptableProtocols, NULL) != SOFTBUS_OK) {
479         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "post laneLinkFail msg err");
480     }
481 }
482 
LaneLinkSuccess(SoftBusMessage * msg)483 static void LaneLinkSuccess(SoftBusMessage *msg)
484 {
485     if (msg->obj == NULL) {
486         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid msg->obj");
487         return;
488     }
489     LaneLinkInfo *info = (LaneLinkInfo *)msg->obj;
490     uint32_t laneId = (uint32_t)msg->arg1;
491     DeleteLaneLinkNode(laneId);
492     NotifyLaneAllocSuccess(laneId, info);
493     SoftBusFree(msg->obj);
494     return;
495 }
496 
LaneLinkFail(SoftBusMessage * msg)497 static void LaneLinkFail(SoftBusMessage *msg)
498 {
499     uint32_t laneId = (uint32_t)msg->arg1;
500     int32_t reason = SOFTBUS_ERR;
501     if (Lock() != SOFTBUS_OK) {
502         return;
503     }
504     LaneLinkNodeInfo *nodeInfo = GetLaneLinkNodeWithoutLock(laneId);
505     if (nodeInfo == NULL) {
506         Unlock();
507         return;
508     }
509     if (nodeInfo->linkRetryIdx >= nodeInfo->listNum) {
510         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "All linkTypes failed, notify the result");
511         Unlock();
512         DeleteLaneLinkNode(laneId);
513         NotifyLaneAllocFail(laneId, reason);
514         return;
515     }
516     SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "Continue to build link");
517     Unlock();
518     ProtocolType acceptableProtocols = (ProtocolType)msg->arg2;
519     if (msg->arg2 == (uint64_t)SOFTBUS_ERR) {
520         acceptableProtocols = LNN_PROTOCOL_ALL ^ LNN_PROTOCOL_NIP;
521     }
522     if (PostMsgToHandler(MSG_TYPE_LANE_TRIGGER_LINK, laneId, acceptableProtocols, NULL) != SOFTBUS_OK) {
523         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "post triggerLink msg fail");
524         return;
525     }
526 }
527 
LaneLinkException(SoftBusMessage * msg)528 static void LaneLinkException(SoftBusMessage *msg)
529 {
530     uint32_t laneId = (uint32_t)msg->arg1;
531     int32_t state = (int32_t)msg->arg2;
532     NotifyLaneStateChange(laneId, state);
533 }
534 
MsgHandler(SoftBusMessage * msg)535 NO_SANITIZE("cfi") static void MsgHandler(SoftBusMessage *msg)
536 {
537     if (msg == NULL) {
538         return;
539     }
540     switch (msg->what) {
541         case MSG_TYPE_LANE_TRIGGER_LINK:
542             LaneTriggerLink(msg);
543             break;
544         case MSG_TYPE_LANE_LINK_SUCCESS:
545             LaneLinkSuccess(msg);
546             break;
547         case MSG_TYPE_LANE_LINK_FAIL:
548             LaneLinkFail(msg);
549             break;
550         case MSG_TYPE_LANE_LINK_EXCEPTION:
551             LaneLinkException(msg);
552             break;
553         default:
554             SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "msg type[%d]cannot found", msg->what);
555             break;
556     }
557     return;
558 }
559 
InitLooper(void)560 static int32_t InitLooper(void)
561 {
562     g_laneLoopHandler.name = "transLaneLooper";
563     g_laneLoopHandler.HandleMessage = MsgHandler;
564     g_laneLoopHandler.looper = GetLooper(LOOP_TYPE_LANE);
565     if (g_laneLoopHandler.looper == NULL) {
566         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "transLane init looper fail");
567         return SOFTBUS_ERR;
568     }
569     return SOFTBUS_OK;
570 }
571 
Init(const ILaneIdStateListener * listener)572 static void Init(const ILaneIdStateListener *listener)
573 {
574     if (g_requestList != NULL) {
575         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_WARN, "already init");
576         return;
577     }
578     if (InitLooper() != SOFTBUS_OK) {
579         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "init looper fail");
580         return;
581     }
582     if (SoftBusMutexInit(&g_transLaneMutex, NULL) != SOFTBUS_OK) {
583         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "transLane mutex init fail");
584         return;
585     }
586     g_requestList = (TransLaneList *)SoftBusCalloc(sizeof(TransLaneList));
587     if (g_requestList == NULL) {
588         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "[init]transLane malloc fail");
589         (void)SoftBusMutexDestroy(&g_transLaneMutex);
590         return;
591     }
592     ListInit(&g_requestList->list);
593     ListInit(&g_multiLinkList);
594     g_laneIdCallback = (ILaneIdStateListener *)listener;
595 }
596 
Deinit(void)597 static void Deinit(void)
598 {
599     if (g_requestList == NULL) {
600         return;
601     }
602     if (Lock() != SOFTBUS_OK) {
603         return;
604     }
605     TransReqInfo *item = NULL;
606     TransReqInfo *nextItem = NULL;
607     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_requestList->list, TransReqInfo, node) {
608         ListDelete(&item->node);
609         SoftBusFree(item);
610         g_requestList->cnt--;
611     }
612     Unlock();
613     (void)SoftBusMutexDestroy(&g_transLaneMutex);
614     SoftBusFree(g_requestList);
615     g_requestList = NULL;
616 }
617 
618 static LaneInterface g_transLaneObject = {
619     .Init = Init,
620     .Deinit = Deinit,
621     .AllocLane = Alloc,
622     .FreeLane = Free,
623 };
624 
TransLaneGetInstance(void)625 NO_SANITIZE("cfi") LaneInterface *TransLaneGetInstance(void)
626 {
627     return &g_transLaneObject;
628 }
629