• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_connId_callback_manager.h"
17 
18 #include <securec.h>
19 
20 #include "lnn_log.h"
21 #include "softbus_adapter_thread.h"
22 #include "softbus_adapter_mem.h"
23 #include "softbus_def.h"
24 #include "softbus_error_code.h"
25 
26 typedef enum {
27     CONNID_CB_OK = 0,
28     CONNID_CB_CONNID_IS_EXIST,
29     CONNID_CB_UDID_IS_EXIST,
30     CONNID_CB_ERROR_MAX
31 } ConnIdCbErrorType;
32 
33 static bool g_connIdCbInit = false;
34 
35 static SoftBusMutex g_lnnConnIdCbMutex;
36 static ListNode *g_lnnConnIdCbInfoList;
37 
LnnConnIdCallbackLock(void)38 static int32_t LnnConnIdCallbackLock(void)
39 {
40     if (!g_connIdCbInit) {
41         LNN_LOGE(LNN_BUILDER, "connIdCallback not init");
42         return SOFTBUS_NO_INIT;
43     }
44     return SoftBusMutexLock(&g_lnnConnIdCbMutex);
45 }
46 
LnnConnIdCallbackUnLock(void)47 static void LnnConnIdCallbackUnLock(void)
48 {
49     (void)SoftBusMutexUnlock(&g_lnnConnIdCbMutex);
50 }
51 
DupItem(const ConnIdCbInfo * item,ConnIdCbInfo * dupItem)52 static int32_t DupItem(const ConnIdCbInfo *item, ConnIdCbInfo *dupItem)
53 {
54     if (item == NULL || dupItem == NULL) {
55         LNN_LOGE(LNN_BUILDER, "item or dupItem is null");
56         return SOFTBUS_INVALID_PARAM;
57     }
58     if (memcpy_s(dupItem, sizeof(ConnIdCbInfo), item, sizeof(ConnIdCbInfo)) != EOK) {
59         LNN_LOGE(LNN_BUILDER, "copy ConnIdCbInfo fail");
60         return SOFTBUS_MEM_ERR;
61     }
62     return SOFTBUS_OK;
63 }
64 
CopyCbToListAndDelCbByUdid(char * udid,ListNode * list)65 static int32_t CopyCbToListAndDelCbByUdid(char *udid, ListNode *list)
66 {
67     if (LnnConnIdCallbackLock() != SOFTBUS_OK) {
68         LNN_LOGE(LNN_BUILDER, "Lock connIdCallback mutex fail");
69         return SOFTBUS_LOCK_ERR;
70     }
71     ConnIdCbInfo *item = NULL;
72     ConnIdCbInfo *next = NULL;
73     LIST_FOR_EACH_ENTRY_SAFE(item, next, g_lnnConnIdCbInfoList, ConnIdCbInfo, node) {
74         if (strncmp(item->udid, udid, UDID_BUF_LEN) == 0) {
75             ConnIdCbInfo *dupItem = (ConnIdCbInfo *)SoftBusCalloc(sizeof(ConnIdCbInfo));
76             if (dupItem == NULL) {
77                 ListDelete(&item->node);
78                 SoftBusFree(item);
79                 LNN_LOGE(LNN_BUILDER, "mcalloc fail.");
80                 continue;
81             }
82             int32_t ret = DupItem(item, dupItem);
83             ListDelete(&item->node);
84             SoftBusFree(item);
85             if (ret != SOFTBUS_OK) {
86                 SoftBusFree(dupItem);
87                 LNN_LOGE(LNN_BUILDER, "dupItem fail");
88                 continue;
89             }
90             ListTailInsert(list, &dupItem->node);
91         }
92     }
93     LnnConnIdCallbackUnLock();
94     return SOFTBUS_OK;
95 }
96 
InvokeCallbackForJoinExt(const char * udid,int32_t result)97 void InvokeCallbackForJoinExt(const char *udid, int32_t result)
98 {
99     if (udid == NULL || strlen(udid) == 0) {
100         LNN_LOGE(LNN_BUILDER, "invalid udid.");
101         return;
102     }
103     if (!g_connIdCbInit) {
104         LNN_LOGE(LNN_BUILDER, "connIdCallback is not init.");
105         return;
106     }
107     ListNode list = {0};
108     ListInit(&list);
109     int32_t ret = CopyCbToListAndDelCbByUdid((char *)udid, &list);
110     if (ret != SOFTBUS_OK) {
111         LNN_LOGE(LNN_BUILDER, "CopyCbToListAndDelCbByUdid fail.");
112         return;
113     }
114     ConnIdCbInfo *item = NULL;
115     ConnIdCbInfo *next = NULL;
116     LIST_FOR_EACH_ENTRY_SAFE(item, next, &list, ConnIdCbInfo, node) {
117         item->callBack.lnnServerJoinExtCallback(&item->sessionAddr, result);
118         LNN_LOGI(LNN_BUILDER, "addr.channelId = %{public}d, result = %{public}d",
119             item->sessionAddr.info.session.channelId, result);
120         ListDelete(&item->node);
121         SoftBusFree(item);
122     }
123 }
124 
IsRepeatConnIdCallbackInfoItem(uint32_t connId,char * peerUdid)125 static ConnIdCbErrorType IsRepeatConnIdCallbackInfoItem(uint32_t connId, char *peerUdid)
126 {
127     if (connId <= 0 || peerUdid == NULL) {
128         LNN_LOGE(LNN_BUILDER, "invalid connId = %{public}u or peerUdid.", connId);
129         return SOFTBUS_INVALID_PARAM;
130     }
131     ConnIdCbErrorType ret = CONNID_CB_OK;
132     ConnIdCbInfo *item = NULL;
133     LIST_FOR_EACH_ENTRY(item, g_lnnConnIdCbInfoList, ConnIdCbInfo, node) {
134         if (connId == item->connId) {
135             return CONNID_CB_CONNID_IS_EXIST;
136         } else {
137             if (strncmp(item->udid, peerUdid, UDID_BUF_LEN) == 0) {
138                 ret = CONNID_CB_UDID_IS_EXIST;
139             }
140         }
141     }
142     return ret;
143 }
144 
FillConnIdCbInfo(ConnIdCbInfo * item,const ConnectionAddr * sessionAddr,const LnnServerJoinExtCallBack * callBack,char * peerUdid)145 static int32_t FillConnIdCbInfo(ConnIdCbInfo *item, const ConnectionAddr *sessionAddr,
146     const LnnServerJoinExtCallBack *callBack, char *peerUdid)
147 {
148     if (strcpy_s(item->udid, UDID_BUF_LEN, peerUdid) != EOK) {
149         LNN_LOGE(LNN_BUILDER, "strcpy udid fail");
150         return SOFTBUS_STRCPY_ERR;
151     }
152     if (memcpy_s(&item->callBack, sizeof(LnnServerJoinExtCallBack),
153         callBack, sizeof(LnnServerJoinExtCallBack)) != EOK) {
154         LNN_LOGE(LNN_BUILDER, "copy callBack fail");
155         return SOFTBUS_MEM_ERR;
156     }
157     if (memcpy_s(&item->sessionAddr, sizeof(ConnectionAddr), sessionAddr, sizeof(ConnectionAddr)) != EOK) {
158         LNN_LOGE(LNN_BUILDER, "copy sessionAddr fail");
159         return SOFTBUS_MEM_ERR;
160     }
161     return SOFTBUS_OK;
162 }
163 
AddConnIdCallbackInfoItem(const ConnectionAddr * sessionAddr,const LnnServerJoinExtCallBack * callBack,uint32_t connId,char * peerUdid)164 int32_t AddConnIdCallbackInfoItem(const ConnectionAddr *sessionAddr, const LnnServerJoinExtCallBack *callBack,
165     uint32_t connId, char *peerUdid)
166 {
167     if (sessionAddr == NULL || callBack == NULL || callBack->lnnServerJoinExtCallback == NULL ||
168         peerUdid == NULL || connId <= 0) {
169         LNN_LOGE(LNN_BUILDER, "invalid param, connId = %{public}u.", connId);
170         return SOFTBUS_INVALID_PARAM;
171     }
172     if (LnnConnIdCallbackLock() != SOFTBUS_OK) {
173         LNN_LOGE(LNN_BUILDER, "Lock connIdCallback mutex fail");
174         return SOFTBUS_LOCK_ERR;
175     }
176     ConnIdCbErrorType errorType = IsRepeatConnIdCallbackInfoItem(connId, peerUdid);
177     if (errorType == CONNID_CB_CONNID_IS_EXIST) {
178         LnnConnIdCallbackUnLock();
179         LNN_LOGE(LNN_BUILDER, "repeat connId, add fail.");
180         return SOFTBUS_NETWORK_JOIN_LNN_START_ERR;
181     }
182 
183     ConnIdCbInfo *item = (ConnIdCbInfo *)SoftBusCalloc(sizeof(ConnIdCbInfo));
184     if (item == NULL) {
185         LNN_LOGE(LNN_BUILDER, "calloc connIdCallback info fail");
186         LnnConnIdCallbackUnLock();
187         return SOFTBUS_MALLOC_ERR;
188     }
189     item->connId = connId;
190     int32_t ret = FillConnIdCbInfo(item, sessionAddr, callBack, peerUdid);
191     if (ret != SOFTBUS_OK) {
192         LNN_LOGE(LNN_BUILDER, "add connIdCallback info fail, need free item. ret = %{public}d", ret);
193         SoftBusFree(item);
194         LnnConnIdCallbackUnLock();
195         return ret;
196     }
197     ListTailInsert(g_lnnConnIdCbInfoList, &item->node);
198     if (errorType == CONNID_CB_UDID_IS_EXIST) {
199         LNN_LOGE(LNN_BUILDER, "repeat udid, only add connIdCbInfo.");
200         ret = SOFTBUS_ALREADY_EXISTED;
201     }
202     LnnConnIdCallbackUnLock();
203     return ret;
204 }
205 
DelConnIdCallbackInfoItem(uint32_t connId)206 int32_t DelConnIdCallbackInfoItem(uint32_t connId)
207 {
208     if (connId <= 0) {
209         LNN_LOGE(LNN_BUILDER, "invalid param");
210         return SOFTBUS_INVALID_PARAM;
211     }
212     if (LnnConnIdCallbackLock() != SOFTBUS_OK) {
213         LNN_LOGE(LNN_BUILDER, "Lock connIdCallback mutex fail");
214         return SOFTBUS_LOCK_ERR;
215     }
216     ConnIdCbInfo *item = NULL;
217     ConnIdCbInfo *next = NULL;
218     LIST_FOR_EACH_ENTRY_SAFE(item, next, g_lnnConnIdCbInfoList, ConnIdCbInfo, node) {
219         if (connId == item->connId) {
220             ListDelete(&item->node);
221             SoftBusFree(item);
222             break;
223         }
224     }
225     LnnConnIdCallbackUnLock();
226     return SOFTBUS_OK;
227 }
228 
GetConnIdCbInfoByAddr(const ConnectionAddr * addr,ConnIdCbInfo * dupItem)229 int32_t GetConnIdCbInfoByAddr(const ConnectionAddr *addr, ConnIdCbInfo *dupItem)
230 {
231     if (addr == NULL || dupItem == NULL) {
232         LNN_LOGE(LNN_BUILDER, "invalid param");
233         return SOFTBUS_INVALID_PARAM;
234     }
235     if (LnnConnIdCallbackLock() != SOFTBUS_OK) {
236         LNN_LOGE(LNN_BUILDER, "Lock connIdCallback mutex fail");
237         return SOFTBUS_LOCK_ERR;
238     }
239     int32_t ret = SOFTBUS_NOT_FIND;
240     ConnIdCbInfo *item = NULL;
241     LIST_FOR_EACH_ENTRY(item, g_lnnConnIdCbInfoList, ConnIdCbInfo, node) {
242         if (addr->type == CONNECTION_ADDR_SESSION || addr->type == CONNECTION_ADDR_SESSION_WITH_KEY) {
243             if (addr->info.session.channelId == item->sessionAddr.info.session.channelId) {
244                 ret = DupItem(item, dupItem);
245                 LnnConnIdCallbackUnLock();
246                 return ret;
247             }
248         }
249     }
250     LnnConnIdCallbackUnLock();
251     return ret;
252 }
253 
LnnInitConnIdCallbackManager(void)254 int32_t LnnInitConnIdCallbackManager(void)
255 {
256     if (g_connIdCbInit) {
257         LNN_LOGW(LNN_BUILDER, "callback manager has init.");
258         return SOFTBUS_OK;
259     }
260     SoftBusMutexAttr attr = {
261         .type = SOFTBUS_MUTEX_RECURSIVE,
262     };
263     int32_t ret = SoftBusMutexInit(&g_lnnConnIdCbMutex, &attr);
264     if (ret != SOFTBUS_OK) {
265         LNN_LOGE(LNN_BUILDER, "g_lnnConnIdCbMutex init fail.");
266         return ret;
267     }
268     g_lnnConnIdCbInfoList = (ListNode *)SoftBusMalloc(sizeof(ListNode));
269     if (g_lnnConnIdCbInfoList == NULL) {
270         (void)SoftBusMutexDestroy(&g_lnnConnIdCbMutex);
271         return SOFTBUS_MALLOC_ERR;
272     }
273     ListInit(g_lnnConnIdCbInfoList);
274     g_connIdCbInit = true;
275     return ret;
276 }
277 
LnnDeinitConnIdCallbackManager(void)278 void LnnDeinitConnIdCallbackManager(void)
279 {
280     if (!g_connIdCbInit) {
281         LNN_LOGE(LNN_BUILDER, "callback manager not init");
282         return;
283     }
284     if (LnnConnIdCallbackLock() != SOFTBUS_OK) {
285         LNN_LOGE(LNN_BUILDER, "Lock ConnIdCallback mutex fail");
286         return;
287     }
288     ConnIdCbInfo *item = NULL;
289     ConnIdCbInfo *next = NULL;
290     LIST_FOR_EACH_ENTRY_SAFE(item, next, g_lnnConnIdCbInfoList, ConnIdCbInfo, node) {
291         ListDelete(&item->node);
292         SoftBusFree(item);
293     }
294     SoftBusFree(g_lnnConnIdCbInfoList);
295     g_lnnConnIdCbInfoList = NULL;
296     g_connIdCbInit = false;
297     LnnConnIdCallbackUnLock();
298     (void)SoftBusMutexDestroy(&g_lnnConnIdCbMutex);
299 }