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_listener.h"
17
18 #include <securec.h>
19
20 #include "anonymizer.h"
21 #include "lnn_distributed_net_ledger.h"
22 #include "lnn_lane_common.h"
23 #include "lnn_lane_link.h"
24 #include "lnn_log.h"
25 #include "lnn_node_info.h"
26 #include "lnn_trans_lane.h"
27 #include "bus_center_manager.h"
28 #include "softbus_adapter_mem.h"
29 #include "softbus_errcode.h"
30 #include "wifi_direct_manager.h"
31 #include "softbus_socket.h"
32
33 const static LaneType SUPPORT_TYPE_LIST[] = {LANE_TYPE_HDLC, LANE_TYPE_TRANS, LANE_TYPE_CTRL};
34
35 typedef struct {
36 ListNode node;
37 LaneType laneType;
38 uint64_t laneId;
39 uint32_t ref;
40 } LaneBusinessInfo;
41
42 typedef struct {
43 ListNode node;
44 LaneStatusListener listener;
45 LaneType type;
46 } LaneListenerInfo;
47
48 static SoftBusMutex g_laneStateListenerMutex;
49 static ListNode g_laneListenerList;
50 static ListNode g_laneBusinessInfoList;
51
LaneListenerLock(void)52 static int32_t LaneListenerLock(void)
53 {
54 return SoftBusMutexLock(&g_laneStateListenerMutex);
55 }
56
LaneListenerUnlock(void)57 static void LaneListenerUnlock(void)
58 {
59 (void)SoftBusMutexUnlock(&g_laneStateListenerMutex);
60 }
61
LaneTypeCheck(LaneType type)62 static bool LaneTypeCheck(LaneType type)
63 {
64 uint32_t size = sizeof(SUPPORT_TYPE_LIST) / sizeof(LaneType);
65 for (uint32_t i = 0; i < size; i++) {
66 if (SUPPORT_TYPE_LIST[i] == type) {
67 return true;
68 }
69 }
70 LNN_LOGE(LNN_LANE, "laneType=%{public}d not supported", type);
71 return false;
72 }
73
GetLaneBusinessInfoWithoutLock(const LaneBusinessInfo * laneBusinessInfo)74 static LaneBusinessInfo *GetLaneBusinessInfoWithoutLock(const LaneBusinessInfo *laneBusinessInfo)
75 {
76 if (laneBusinessInfo == NULL) {
77 LNN_LOGE(LNN_LANE, "invalid param");
78 return NULL;
79 }
80 LaneBusinessInfo *item = NULL;
81 LaneBusinessInfo *next = NULL;
82 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_laneBusinessInfoList, LaneBusinessInfo, node) {
83 if (laneBusinessInfo->laneType == item->laneType &&
84 laneBusinessInfo->laneId == item->laneId) {
85 return item;
86 }
87 }
88 return NULL;
89 }
90
UpdateLaneBusinessInfoItem(uint64_t oldLaneId,uint64_t newLaneId)91 int32_t UpdateLaneBusinessInfoItem(uint64_t oldLaneId, uint64_t newLaneId)
92 {
93 if (oldLaneId == INVALID_LANE_ID || newLaneId == INVALID_LANE_ID) {
94 LNN_LOGE(LNN_LANE, "invalid param");
95 return SOFTBUS_INVALID_PARAM;
96 }
97 LaneBusinessInfo laneBusinessInfo;
98 (void)memset_s(&laneBusinessInfo, sizeof(LaneBusinessInfo), 0, sizeof(LaneBusinessInfo));
99 laneBusinessInfo.laneId = oldLaneId;
100 laneBusinessInfo.laneType = LANE_TYPE_TRANS;
101 if (LaneListenerLock() != SOFTBUS_OK) {
102 LNN_LOGE(LNN_LANE, "lane listener lock fail");
103 return SOFTBUS_LOCK_ERR;
104 }
105 LaneBusinessInfo *item = GetLaneBusinessInfoWithoutLock(&laneBusinessInfo);
106 if (item != NULL) {
107 item->laneId = newLaneId;
108 LNN_LOGI(LNN_LANE, "update oldLaneId=%{public}" PRIu64 ", newLaneId=%{public}" PRIu64, oldLaneId, newLaneId);
109 LaneListenerUnlock();
110 return SOFTBUS_OK;
111 }
112 LaneListenerUnlock();
113 return SOFTBUS_NOT_FIND;
114 }
115
AddLaneBusinessInfoItem(LaneType laneType,uint64_t laneId)116 int32_t AddLaneBusinessInfoItem(LaneType laneType, uint64_t laneId)
117 {
118 if (!LaneTypeCheck(laneType) || laneId == INVALID_LANE_ID) {
119 LNN_LOGE(LNN_LANE, "invalid param");
120 return SOFTBUS_INVALID_PARAM;
121 }
122 LaneBusinessInfo laneBusinessInfo;
123 (void)memset_s(&laneBusinessInfo, sizeof(LaneBusinessInfo), 0, sizeof(LaneBusinessInfo));
124 laneBusinessInfo.laneId = laneId;
125 laneBusinessInfo.laneType = laneType;
126 laneBusinessInfo.ref = 1;
127 if (LaneListenerLock() != SOFTBUS_OK) {
128 LNN_LOGE(LNN_LANE, "lane listener lock fail");
129 return SOFTBUS_LOCK_ERR;
130 }
131 LaneBusinessInfo *item = GetLaneBusinessInfoWithoutLock(&laneBusinessInfo);
132 if (item != NULL) {
133 item->ref++;
134 LNN_LOGI(LNN_LANE, "add laneBusiness succ, laneType=%{public}d, laneId=%{public}" PRIu64 ", ref=%{public}u",
135 laneType, laneId, item->ref);
136 LaneListenerUnlock();
137 return SOFTBUS_OK;
138 }
139 LaneBusinessInfo *laneBusinessInfoItem = (LaneBusinessInfo *)SoftBusCalloc(sizeof(LaneBusinessInfo));
140 if (laneBusinessInfoItem == NULL) {
141 LNN_LOGE(LNN_LANE, "calloc laneBusinessInfoItem fail");
142 LaneListenerUnlock();
143 return SOFTBUS_MALLOC_ERR;
144 }
145 if (memcpy_s(laneBusinessInfoItem, sizeof(LaneBusinessInfo), &laneBusinessInfo,
146 sizeof(LaneBusinessInfo)) != EOK) {
147 SoftBusFree(laneBusinessInfoItem);
148 LNN_LOGE(LNN_LANE, "memcpy laneBusinessInfo fail");
149 LaneListenerUnlock();
150 return SOFTBUS_MEM_ERR;
151 }
152 ListAdd(&g_laneBusinessInfoList, &laneBusinessInfoItem->node);
153 LaneListenerUnlock();
154 LNN_LOGI(LNN_LANE, "create new laneBusiness succ, laneType=%{public}d, laneId=%{public}" PRIu64 "",
155 laneType, laneId);
156 return SOFTBUS_OK;
157 }
158
DelLaneBusinessInfoItem(LaneType laneType,uint64_t laneId)159 int32_t DelLaneBusinessInfoItem(LaneType laneType, uint64_t laneId)
160 {
161 if (!LaneTypeCheck(laneType)) {
162 LNN_LOGE(LNN_LANE, "invalid param");
163 return SOFTBUS_INVALID_PARAM;
164 }
165 LaneBusinessInfo laneBusinessInfo;
166 (void)memset_s(&laneBusinessInfo, sizeof(LaneBusinessInfo), 0, sizeof(LaneBusinessInfo));
167 laneBusinessInfo.laneId = laneId;
168 laneBusinessInfo.laneType = laneType;
169 if (LaneListenerLock() != SOFTBUS_OK) {
170 LNN_LOGE(LNN_LANE, "lane listener lock fail");
171 return SOFTBUS_LOCK_ERR;
172 }
173 LaneBusinessInfo *item = GetLaneBusinessInfoWithoutLock(&laneBusinessInfo);
174 if (item != NULL) {
175 uint32_t ref = item->ref;
176 if (item->ref != 0) {
177 ref = --item->ref;
178 }
179 if (ref == 0) {
180 ListDelete(&item->node);
181 SoftBusFree(item);
182 }
183 LNN_LOGI(LNN_LANE, "del laneBusiness succ, laneType=%{public}d, laneId=%{public}" PRIu64 ", ref=%{public}u",
184 laneType, laneId, ref);
185 }
186 LaneListenerUnlock();
187 return SOFTBUS_OK;
188 }
189
FindLaneBusinessInfoByLinkInfo(const LaneLinkInfo * laneLinkInfo,uint32_t * resNum,LaneBusinessInfo * laneBusinessInfo,uint32_t laneBusinessNum)190 static int32_t FindLaneBusinessInfoByLinkInfo(const LaneLinkInfo *laneLinkInfo,
191 uint32_t *resNum, LaneBusinessInfo *laneBusinessInfo, uint32_t laneBusinessNum)
192 {
193 if (laneLinkInfo == NULL || laneBusinessInfo == NULL) {
194 LNN_LOGE(LNN_LANE, "invalid param");
195 return SOFTBUS_INVALID_PARAM;
196 }
197 char localUdid[UDID_BUF_LEN] = {0};
198 if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, localUdid, UDID_BUF_LEN) != SOFTBUS_OK) {
199 LNN_LOGE(LNN_LANE, "get udid fail");
200 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
201 }
202 uint64_t laneId = GenerateLaneId(localUdid, laneLinkInfo->peerUdid, laneLinkInfo->type);
203 if (LaneListenerLock() != SOFTBUS_OK) {
204 LNN_LOGE(LNN_LANE, "lane listener lock fail");
205 return SOFTBUS_LOCK_ERR;
206 }
207 *resNum = 0;
208 LaneBusinessInfo *item = NULL;
209 LaneBusinessInfo *next = NULL;
210 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_laneBusinessInfoList, LaneBusinessInfo, node) {
211 if (item->laneId == laneId) {
212 if (memcpy_s(&laneBusinessInfo[(*resNum)++], sizeof(LaneBusinessInfo),
213 item, sizeof(LaneBusinessInfo)) != EOK) {
214 LNN_LOGE(LNN_LANE, "memcpy lane bussiness info fail");
215 LaneListenerUnlock();
216 return SOFTBUS_MEM_ERR;
217 }
218 }
219 if (*resNum >= laneBusinessNum) {
220 LNN_LOGE(LNN_LANE, "find laneBusinessinfo num more than expected");
221 break;
222 }
223 }
224 LaneListenerUnlock();
225 return SOFTBUS_OK;
226 }
227
LaneListenerIsExist(LaneType type)228 static LaneListenerInfo *LaneListenerIsExist(LaneType type)
229 {
230 LaneListenerInfo *item = NULL;
231 LaneListenerInfo *next = NULL;
232 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_laneListenerList, LaneListenerInfo, node) {
233 if (type == item->type) {
234 return item;
235 }
236 }
237 return NULL;
238 }
239
FindLaneListenerInfoByLaneType(LaneType type,LaneListenerInfo * laneListenerInfo)240 static int32_t FindLaneListenerInfoByLaneType(LaneType type, LaneListenerInfo *laneListenerInfo)
241 {
242 if (!LaneTypeCheck(type) || laneListenerInfo == NULL) {
243 LNN_LOGE(LNN_LANE, "invalid param");
244 return SOFTBUS_INVALID_PARAM;
245 }
246 if (LaneListenerLock() != SOFTBUS_OK) {
247 LNN_LOGE(LNN_LANE, "lane listener lock fail");
248 return SOFTBUS_LOCK_ERR;
249 }
250 LaneListenerInfo* item = LaneListenerIsExist(type);
251 if (item == NULL) {
252 LaneListenerUnlock();
253 LNN_LOGE(LNN_LANE, "lane listener is not exist");
254 return SOFTBUS_LANE_NOT_FOUND;
255 }
256 laneListenerInfo->type = item->type;
257 laneListenerInfo->listener = item->listener;
258 LaneListenerUnlock();
259 return SOFTBUS_OK;
260 }
261
LaneLinkupNotify(const char * peerUdid,const LaneLinkInfo * laneLinkInfo)262 int32_t LaneLinkupNotify(const char *peerUdid, const LaneLinkInfo *laneLinkInfo)
263 {
264 if (peerUdid == NULL || laneLinkInfo == NULL) {
265 LNN_LOGE(LNN_LANE, "invalid param");
266 return SOFTBUS_INVALID_PARAM;
267 }
268 LaneProfile profile;
269 (void)memset_s(&profile, sizeof(LaneProfile), 0, sizeof(LaneProfile));
270 LaneConnInfo laneConnInfo;
271 (void)memset_s(&laneConnInfo, sizeof(LaneConnInfo), 0, sizeof(LaneConnInfo));
272 int32_t ret = LaneInfoProcess(laneLinkInfo, &laneConnInfo, &profile);
273 if (ret != SOFTBUS_OK) {
274 LNN_LOGE(LNN_LANE, "laneInfo proc fail");
275 return ret;
276 }
277 LaneListenerInfo listenerList[LANE_TYPE_BUTT];
278 (void)memset_s(listenerList, sizeof(listenerList), 0, sizeof(listenerList));
279 if (LaneListenerLock() != SOFTBUS_OK) {
280 LNN_LOGE(LNN_LANE, "lane listener lock fail");
281 return SOFTBUS_LOCK_ERR;
282 }
283 LaneListenerInfo *item = NULL;
284 LaneListenerInfo *next = NULL;
285 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_laneListenerList, LaneListenerInfo, node) {
286 listenerList[item->type].listener = item->listener;
287 }
288 LaneListenerUnlock();
289 char localUdid[UDID_BUF_LEN] = {0};
290 if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, localUdid, UDID_BUF_LEN) != SOFTBUS_OK) {
291 LNN_LOGE(LNN_LANE, "get udid fail");
292 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
293 }
294 uint64_t laneId = GenerateLaneId(localUdid, peerUdid, laneLinkInfo->type);
295 for (uint32_t i = 0; i < LANE_TYPE_BUTT; i++) {
296 if (listenerList[i].listener.onLaneLinkup != NULL) {
297 LNN_LOGI(LNN_LANE, "notify lane linkup, laneType=%{public}u", i);
298 listenerList[i].listener.onLaneLinkup(laneId, peerUdid, &laneConnInfo);
299 }
300 }
301 return SOFTBUS_OK;
302 }
303
LaneLinkdownNotify(const char * peerUdid,const LaneLinkInfo * laneLinkInfo)304 int32_t LaneLinkdownNotify(const char *peerUdid, const LaneLinkInfo *laneLinkInfo)
305 {
306 if (peerUdid == NULL || laneLinkInfo == NULL) {
307 LNN_LOGE(LNN_LANE, "invalid param");
308 return SOFTBUS_INVALID_PARAM;
309 }
310 LaneResource resourceItem;
311 (void)memset_s(&resourceItem, sizeof(LaneResource), 0, sizeof(LaneResource));
312 if (FindLaneResourceByLinkType(peerUdid, laneLinkInfo->type, &resourceItem) == SOFTBUS_OK) {
313 if (laneLinkInfo->type == LANE_HML) {
314 RemoveDelayDestroyMessage(resourceItem.laneId);
315 }
316 DelLogicAndLaneRelationship(resourceItem.laneId);
317 ClearLaneResourceByLaneId(resourceItem.laneId);
318 }
319 if (laneLinkInfo->type == LANE_HML &&
320 FindLaneResourceByLinkType(peerUdid, LANE_HML_RAW, &resourceItem) == SOFTBUS_OK) {
321 DelLogicAndLaneRelationship(resourceItem.laneId);
322 ClearLaneResourceByLaneId(resourceItem.laneId);
323 }
324 uint32_t resNum;
325 LaneBusinessInfo laneBusinessInfo[LANE_TYPE_BUTT];
326 if (FindLaneBusinessInfoByLinkInfo(laneLinkInfo, &resNum, laneBusinessInfo, LANE_TYPE_BUTT) != SOFTBUS_OK) {
327 LNN_LOGE(LNN_STATE, "not found laneBusinessInfo, no need to notify");
328 return SOFTBUS_OK;
329 }
330 LaneListenerInfo laneListener;
331 LaneProfile profile;
332 (void)memset_s(&profile, sizeof(LaneProfile), 0, sizeof(LaneProfile));
333 LaneConnInfo laneConnInfo;
334 (void)memset_s(&laneConnInfo, sizeof(LaneConnInfo), 0, sizeof(LaneConnInfo));
335 for (uint32_t i = 0; i < resNum; i++) {
336 if (FindLaneListenerInfoByLaneType(laneBusinessInfo[i].laneType, &laneListener) != SOFTBUS_OK) {
337 LNN_LOGE(LNN_STATE, "find lane listener fail, laneType=%{public}d", laneBusinessInfo[i].laneType);
338 continue;
339 }
340 if (laneListener.listener.onLaneLinkdown == NULL) {
341 LNN_LOGE(LNN_STATE, "invalid lane status listen");
342 continue;
343 }
344 if (LaneInfoProcess(laneLinkInfo, &laneConnInfo, &profile) != SOFTBUS_OK) {
345 LNN_LOGE(LNN_LANE, "laneInfo proc fail");
346 continue;
347 }
348 LNN_LOGI(LNN_LANE, "notify lane linkdown, laneType=%{public}d", laneListener.type);
349 laneListener.listener.onLaneLinkdown(laneBusinessInfo[i].laneId, peerUdid, &laneConnInfo);
350 }
351 return SOFTBUS_OK;
352 }
353
GetStateNotifyInfo(const char * peerIp,const char * peerUuid,LaneLinkInfo * laneLinkInfo)354 static int32_t GetStateNotifyInfo(const char *peerIp, const char *peerUuid, LaneLinkInfo *laneLinkInfo)
355 {
356 if (peerIp == NULL || peerUuid == NULL || laneLinkInfo == NULL) {
357 LNN_LOGE(LNN_LANE, "invalid param");
358 return SOFTBUS_INVALID_PARAM;
359 }
360 laneLinkInfo->type = IsHmlIpAddr(peerIp) ? LANE_HML : LANE_P2P;
361 if (strncpy_s(laneLinkInfo->linkInfo.p2p.connInfo.peerIp, IP_LEN, peerIp, IP_LEN) != EOK) {
362 LNN_LOGE(LNN_STATE, "strncpy peerIp fail");
363 return SOFTBUS_STRCPY_ERR;
364 }
365
366 NodeInfo nodeInfo;
367 (void)memset_s(&nodeInfo, sizeof(NodeInfo), 0, sizeof(NodeInfo));
368 if (LnnGetRemoteNodeInfoById(peerUuid, CATEGORY_UUID, &nodeInfo) != SOFTBUS_OK) {
369 char *anonyUuid = NULL;
370 Anonymize(peerUuid, &anonyUuid);
371 LNN_LOGE(LNN_STATE, "get remote nodeinfo failed, peerUuid=%{public}s", AnonymizeWrapper(anonyUuid));
372 AnonymizeFree(anonyUuid);
373 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
374 }
375 if (strncpy_s(laneLinkInfo->peerUdid, UDID_BUF_LEN, nodeInfo.deviceInfo.deviceUdid, UDID_BUF_LEN) != EOK) {
376 LNN_LOGE(LNN_STATE, "copy peerudid fail");
377 return SOFTBUS_STRCPY_ERR;
378 }
379 return SOFTBUS_OK;
380 }
381
LnnOnWifiDirectDeviceOnline(const char * peerMac,const char * peerIp,const char * peerUuid,bool isSource)382 static void LnnOnWifiDirectDeviceOnline(const char *peerMac, const char *peerIp, const char *peerUuid, bool isSource)
383 {
384 LNN_LOGI(LNN_LANE, "lnn wifidirect up");
385 if (peerMac == NULL || peerUuid == NULL || peerIp == NULL) {
386 LNN_LOGE(LNN_LANE, "invalid param");
387 return;
388 }
389 LaneLinkInfo laneLinkInfo;
390 (void)memset_s(&laneLinkInfo, sizeof(LaneLinkInfo), 0, sizeof(LaneLinkInfo));
391 if (GetStateNotifyInfo(peerIp, peerUuid, &laneLinkInfo) != SOFTBUS_OK) {
392 LNN_LOGE(LNN_STATE, "get lane state notify info fail");
393 return;
394 }
395 if (PostLaneStateChangeMessage(LANE_STATE_LINKUP, laneLinkInfo.peerUdid, &laneLinkInfo) != SOFTBUS_OK) {
396 LNN_LOGE(LNN_LANE, "post laneState linkup msg fail");
397 }
398 }
399
LnnOnWifiDirectDeviceOffline(const char * peerMac,const char * peerIp,const char * peerUuid,const char * localIp)400 static void LnnOnWifiDirectDeviceOffline(const char *peerMac, const char *peerIp, const char *peerUuid,
401 const char *localIp)
402 {
403 LNN_LOGI(LNN_LANE, "lnn wifidirect down");
404 if (peerMac == NULL || peerUuid == NULL || peerIp == NULL) {
405 LNN_LOGE(LNN_LANE, "invalid param");
406 return;
407 }
408 LaneLinkInfo laneLinkInfo;
409 (void)memset_s(&laneLinkInfo, sizeof(LaneLinkInfo), 0, sizeof(LaneLinkInfo));
410 if (GetStateNotifyInfo(peerIp, peerUuid, &laneLinkInfo) != SOFTBUS_OK) {
411 LNN_LOGE(LNN_STATE, "get lane state notify info fail");
412 return;
413 }
414 DetectDisableWifiDirectApply();
415 if (PostLaneStateChangeMessage(LANE_STATE_LINKDOWN, laneLinkInfo.peerUdid, &laneLinkInfo) != SOFTBUS_OK) {
416 LNN_LOGE(LNN_LANE, "post laneState linkdown msg fail");
417 }
418 }
419
LnnOnWifiDirectRoleChange(enum WifiDirectRole oldRole,enum WifiDirectRole newRole)420 static void LnnOnWifiDirectRoleChange(enum WifiDirectRole oldRole, enum WifiDirectRole newRole)
421 {
422 LNN_LOGD(LNN_LANE, "lnn wifiDirect roleChange");
423 (void)oldRole;
424 (void)newRole;
425 }
426
RegisterLaneListener(LaneType type,const LaneStatusListener * listener)427 int32_t RegisterLaneListener(LaneType type, const LaneStatusListener *listener)
428 {
429 LNN_LOGI(LNN_LANE, "register lane listener, laneType=%{public}d", type);
430 if (!LaneTypeCheck(type) || listener == NULL) {
431 LNN_LOGE(LNN_LANE, "invalid param");
432 return SOFTBUS_INVALID_PARAM;
433 }
434 if (LaneListenerLock() != SOFTBUS_OK) {
435 LNN_LOGE(LNN_LANE, "lane listener lock fail");
436 return SOFTBUS_LOCK_ERR;
437 }
438 LaneListenerInfo *item = LaneListenerIsExist(type);
439 if (item != NULL) {
440 LaneListenerUnlock();
441 return SOFTBUS_OK;
442 }
443 LaneListenerInfo *laneListenerItem = (LaneListenerInfo *)SoftBusCalloc(sizeof(LaneListenerInfo));
444 if (laneListenerItem == NULL) {
445 LNN_LOGE(LNN_LANE, "calloc lane listener fail");
446 LaneListenerUnlock();
447 return SOFTBUS_MALLOC_ERR;
448 }
449 laneListenerItem->type = type;
450 laneListenerItem->listener = *listener;
451 ListAdd(&g_laneListenerList, &laneListenerItem->node);
452 LaneListenerUnlock();
453 return SOFTBUS_OK;
454 }
455
UnRegisterLaneListener(LaneType type)456 int32_t UnRegisterLaneListener(LaneType type)
457 {
458 LNN_LOGI(LNN_LANE, "unregister lane listener, laneType=%{public}d", type);
459 if (!LaneTypeCheck(type)) {
460 LNN_LOGE(LNN_LANE, "invalid param");
461 return SOFTBUS_INVALID_PARAM;
462 }
463 if (LaneListenerLock() != SOFTBUS_OK) {
464 LNN_LOGE(LNN_LANE, "lane listener lock fail");
465 return SOFTBUS_LOCK_ERR;
466 }
467 LaneListenerInfo *item = LaneListenerIsExist(type);
468 if (item != NULL) {
469 ListDelete(&item->node);
470 SoftBusFree(item);
471 }
472 LaneListenerUnlock();
473 return SOFTBUS_OK;
474 }
475
CreateSinkLinkInfo(const struct WifiDirectSinkLink * link,LaneLinkInfo * linkInfo)476 static int32_t CreateSinkLinkInfo(const struct WifiDirectSinkLink *link, LaneLinkInfo *linkInfo)
477 {
478 if (link == NULL || linkInfo == NULL) {
479 return SOFTBUS_INVALID_PARAM;
480 }
481 linkInfo->type = link->linkType == WIFI_DIRECT_LINK_TYPE_HML ? LANE_HML : LANE_P2P;
482 LNN_LOGI(LNN_LANE, "bandWidth=%{public}d", link->bandWidth);
483 linkInfo->linkInfo.p2p.bw = (LaneBandwidth)link->bandWidth;
484 if (strcpy_s(linkInfo->linkInfo.p2p.connInfo.localIp, IP_LEN, link->localIp) != EOK ||
485 strcpy_s(linkInfo->linkInfo.p2p.connInfo.peerIp, IP_LEN, link->remoteIp) != EOK) {
486 LNN_LOGE(LNN_LANE, "strcpy Ip fail");
487 return SOFTBUS_STRCPY_ERR;
488 }
489 linkInfo->linkInfo.p2p.channel = link->channelId;
490 NodeInfo nodeInfo;
491 (void)memset_s(&nodeInfo, sizeof(NodeInfo), 0, sizeof(NodeInfo));
492 if (LnnGetRemoteNodeInfoById(link->remoteUuid, CATEGORY_UUID, &nodeInfo) != SOFTBUS_OK) {
493 char *anonyUuid = NULL;
494 Anonymize(link->remoteUuid, &anonyUuid);
495 LNN_LOGE(LNN_STATE, "get remote nodeinfo failed, remoteUuid=%{public}s", AnonymizeWrapper(anonyUuid));
496 AnonymizeFree(anonyUuid);
497 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
498 }
499 if (strncpy_s(linkInfo->peerUdid, UDID_BUF_LEN, nodeInfo.deviceInfo.deviceUdid, UDID_BUF_LEN) != EOK) {
500 LNN_LOGE(LNN_STATE, "copy peerudid fail");
501 return SOFTBUS_STRCPY_ERR;
502 }
503 return SOFTBUS_OK;
504 }
505
LnnOnWifiDirectConnectedForSink(const struct WifiDirectSinkLink * link)506 static void LnnOnWifiDirectConnectedForSink(const struct WifiDirectSinkLink *link)
507 {
508 if (link == NULL) {
509 LNN_LOGE(LNN_LANE, "invalid param");
510 return;
511 }
512 LNN_LOGI(LNN_LANE, "on server wifidirect link=%{public}d connected", link->linkType);
513 LaneLinkInfo laneLinkInfo;
514 (void)memset_s(&laneLinkInfo, sizeof(LaneLinkInfo), 0, sizeof(LaneLinkInfo));
515 if (CreateSinkLinkInfo(link, &laneLinkInfo) != SOFTBUS_OK) {
516 LNN_LOGE(LNN_STATE, "generate link info fail");
517 return;
518 }
519 char localUdid[UDID_BUF_LEN] = {0};
520 if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, localUdid, UDID_BUF_LEN) != SOFTBUS_OK) {
521 LNN_LOGE(LNN_LANE, "get local udid fail");
522 return;
523 }
524 uint64_t laneId = INVALID_LANE_ID;
525 if (strlen(laneLinkInfo.peerUdid) != 0) {
526 laneId = GenerateLaneId(localUdid, laneLinkInfo.peerUdid, laneLinkInfo.type);
527 } else {
528 laneId = GenerateLaneId(localUdid, link->remoteIp, laneLinkInfo.type);
529 }
530 if (laneId == INVALID_LANE_ID) {
531 LNN_LOGE(LNN_LANE, "generate laneid fail");
532 return;
533 }
534 if (AddLaneResourceToPool(&laneLinkInfo, laneId, true) != SOFTBUS_OK) {
535 LNN_LOGE(LNN_LANE, "add server lane resource fail");
536 }
537 (void)HandleLaneQosChange(&laneLinkInfo);
538 }
539
LnnOnWifiDirectDisconnectedForSink(const struct WifiDirectSinkLink * link)540 static void LnnOnWifiDirectDisconnectedForSink(const struct WifiDirectSinkLink *link)
541 {
542 if (link == NULL) {
543 LNN_LOGE(LNN_LANE, "invalid param");
544 return;
545 }
546 LNN_LOGI(LNN_LANE, "on server wifidirect link=%{public}d disconnected", link->linkType);
547 NodeInfo nodeInfo;
548 (void)memset_s(&nodeInfo, sizeof(NodeInfo), 0, sizeof(NodeInfo));
549 if (LnnGetRemoteNodeInfoById(link->remoteUuid, CATEGORY_UUID, &nodeInfo) != SOFTBUS_OK) {
550 char *anonyUuid = NULL;
551 Anonymize(link->remoteUuid, &anonyUuid);
552 LNN_LOGE(LNN_STATE, "get remote nodeinfo failed, remoteUuid=%{public}s", AnonymizeWrapper(anonyUuid));
553 AnonymizeFree(anonyUuid);
554 return;
555 }
556 LaneLinkType linkType = link->linkType == WIFI_DIRECT_LINK_TYPE_HML ? LANE_HML : LANE_P2P;
557 LaneResource resourceItem;
558 (void)memset_s(&resourceItem, sizeof(LaneResource), 0, sizeof(LaneResource));
559 if (FindLaneResourceByLinkType(nodeInfo.deviceInfo.deviceUdid, linkType, &resourceItem) != SOFTBUS_OK) {
560 LNN_LOGE(LNN_STATE, "find lane resource fail");
561 return;
562 }
563 DelLaneResourceByLaneId(resourceItem.laneId, true);
564 }
565
RegisterWifiDirectListener(void)566 static void RegisterWifiDirectListener(void)
567 {
568 struct WifiDirectStatusListener listener = {
569 .onDeviceOffLine = LnnOnWifiDirectDeviceOffline,
570 .onLocalRoleChange = LnnOnWifiDirectRoleChange,
571 .onDeviceOnLine = LnnOnWifiDirectDeviceOnline,
572 .onConnectedForSink = LnnOnWifiDirectConnectedForSink,
573 .onDisconnectedForSink = LnnOnWifiDirectDisconnectedForSink,
574 };
575 struct WifiDirectManager *mgr = GetWifiDirectManager();
576 if (mgr == NULL) {
577 LNN_LOGE(LNN_LANE, "get wifiDirect manager null");
578 return;
579 }
580 if (mgr->registerStatusListener != NULL) {
581 LNN_LOGD(LNN_LANE, "regist listener to wifiDirect");
582 mgr->registerStatusListener(&listener);
583 }
584 }
585
InitLaneListener(void)586 int32_t InitLaneListener(void)
587 {
588 if (SoftBusMutexInit(&g_laneStateListenerMutex, NULL) != SOFTBUS_OK) {
589 LNN_LOGI(LNN_LANE, "g_laneStateListenerMutex init fail");
590 return SOFTBUS_NO_INIT;
591 }
592
593 ListInit(&g_laneListenerList);
594 ListInit(&g_laneBusinessInfoList);
595
596 RegisterWifiDirectListener();
597 return SOFTBUS_OK;
598 }
599
DeinitLaneListener(void)600 void DeinitLaneListener(void)
601 {
602 if (LaneListenerLock() != SOFTBUS_OK) {
603 LNN_LOGE(LNN_LANE, "lane listener lock fail");
604 return;
605 }
606 LaneBusinessInfo *businessItem = NULL;
607 LaneBusinessInfo *businessNext = NULL;
608 LIST_FOR_EACH_ENTRY_SAFE(businessItem, businessNext, &g_laneBusinessInfoList, LaneBusinessInfo, node) {
609 ListDelete(&businessItem->node);
610 SoftBusFree(businessItem);
611 }
612 LaneListenerInfo *listenerItem = NULL;
613 LaneListenerInfo *listenerNext = NULL;
614 LIST_FOR_EACH_ENTRY_SAFE(listenerItem, listenerNext, &g_laneListenerList, LaneListenerInfo, node) {
615 ListDelete(&listenerItem->node);
616 SoftBusFree(listenerItem);
617 }
618 LaneListenerUnlock();
619 (void)SoftBusMutexDestroy(&g_laneStateListenerMutex);
620 }
621