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(¶m);
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(¶m);
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