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 }