1 /*
2 * Copyright (c) 2021-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 "client_trans_tcp_direct_manager.h"
17
18 #include <securec.h>
19
20 #include "client_trans_tcp_direct_callback.h"
21 #include "client_trans_tcp_direct_listener.h"
22 #include "softbus_adapter_mem.h"
23 #include "softbus_base_listener.h"
24 #include "softbus_def.h"
25 #include "softbus_errcode.h"
26 #include "softbus_socket.h"
27 #include "softbus_utils.h"
28 #include "trans_log.h"
29 #include "trans_pending_pkt.h"
30 #include "trans_server_proxy.h"
31
32 #define HEART_TIME 300
33 #define TCP_KEEPALIVE_INTERVAL 4
34 #define TCP_KEEPALIVE_COUNT 5
35 #define USER_TIME_OUT (320 * 1000)
36
37 static SoftBusList *g_tcpDirectChannelInfoList = NULL;
38
CheckInfoAndMutexLock(TcpDirectChannelInfo * info)39 static bool CheckInfoAndMutexLock(TcpDirectChannelInfo *info)
40 {
41 if (info == NULL) {
42 TRANS_LOGE(TRANS_SDK, "param invalid.");
43 return false;
44 }
45 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
46 TRANS_LOGE(TRANS_SDK, "lock failed");
47 return false;
48 }
49 return true;
50 }
51
TransTdcGetInfoById(int32_t channelId,TcpDirectChannelInfo * info)52 TcpDirectChannelInfo *TransTdcGetInfoById(int32_t channelId, TcpDirectChannelInfo *info)
53 {
54 if (!CheckInfoAndMutexLock(info)) {
55 return NULL;
56 }
57
58 TcpDirectChannelInfo *item = NULL;
59 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
60 if (item->channelId == channelId) {
61 (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
62 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
63 return item;
64 }
65 }
66
67 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
68 return NULL;
69 }
70
TransTdcSetListenerStateById(int32_t channelId,bool needStopListener)71 int32_t TransTdcSetListenerStateById(int32_t channelId, bool needStopListener)
72 {
73 if (g_tcpDirectChannelInfoList == NULL) {
74 TRANS_LOGE(TRANS_SDK, "g_tcpDirectChannelInfoList is NULL, channelId=%{public}d", channelId);
75 return SOFTBUS_INVALID_PARAM;
76 }
77 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
78 TRANS_LOGE(TRANS_SDK, "lock failed, channelId=%{public}d", channelId);
79 return SOFTBUS_LOCK_ERR;
80 }
81
82 TcpDirectChannelInfo *item = NULL;
83 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
84 if (item->channelId == channelId) {
85 item->detail.needStopListener = needStopListener;
86 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
87 TRANS_LOGI(TRANS_SDK, "succ, channelId=%{public}d, needStopListener=%{public}d", channelId,
88 needStopListener);
89 return SOFTBUS_OK;
90 }
91 }
92
93 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
94 TRANS_LOGE(TRANS_SDK, "channel not found, channelId=%{public}d", channelId);
95 return SOFTBUS_NOT_FIND;
96 }
97
TransTdcGetInfoByIdWithIncSeq(int32_t channelId,TcpDirectChannelInfo * info)98 TcpDirectChannelInfo *TransTdcGetInfoByIdWithIncSeq(int32_t channelId, TcpDirectChannelInfo *info)
99 {
100 if (!CheckInfoAndMutexLock(info)) {
101 return NULL;
102 }
103
104 TcpDirectChannelInfo *item = NULL;
105 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
106 if (item->channelId == channelId) {
107 (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
108 item->detail.sequence++;
109 item->detail.fdRefCnt++;
110 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
111 return item;
112 }
113 }
114
115 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
116 return NULL;
117 }
118
TransTdcGetInfoByFd(int32_t fd,TcpDirectChannelInfo * info)119 TcpDirectChannelInfo *TransTdcGetInfoByFd(int32_t fd, TcpDirectChannelInfo *info)
120 {
121 if (!CheckInfoAndMutexLock(info)) {
122 return NULL;
123 }
124
125 TcpDirectChannelInfo *item = NULL;
126 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
127 if (item->detail.fd == fd) {
128 (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
129 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
130 return item;
131 }
132 }
133
134 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
135 return NULL;
136 }
137
TransTdcCloseChannel(int32_t channelId)138 void TransTdcCloseChannel(int32_t channelId)
139 {
140 TRANS_LOGI(TRANS_SDK, "Close tdc Channel, channelId=%{public}d.", channelId);
141 if (ServerIpcCloseChannel(NULL, channelId, CHANNEL_TYPE_TCP_DIRECT) != SOFTBUS_OK) {
142 TRANS_LOGE(TRANS_SDK, "close server tdc channelId=%{public}d err.", channelId);
143 }
144
145 TcpDirectChannelInfo *item = NULL;
146 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
147 TRANS_LOGE(TRANS_SDK, "lock failed");
148 return;
149 }
150
151 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
152 if (item->channelId != channelId) {
153 continue;
154 }
155 TransTdcReleaseFd(item->detail.fd);
156 item->detail.needRelease = true;
157 if (item->detail.fdRefCnt <= 0) {
158 SoftBusMutexDestroy(&(item->detail.fdLock));
159 ListDelete(&item->node);
160 SoftBusFree(item);
161 item = NULL;
162 }
163 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
164 DelPendingPacket(channelId, PENDING_TYPE_DIRECT);
165 TRANS_LOGI(TRANS_SDK, "Delete tdc item success. channelId=%{public}d", channelId);
166 return;
167 }
168
169 TRANS_LOGE(TRANS_SDK, "Target item not exist. channelId=%{public}d", channelId);
170 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
171 }
172
TransGetNewTcpChannel(const ChannelInfo * channel)173 static TcpDirectChannelInfo *TransGetNewTcpChannel(const ChannelInfo *channel)
174 {
175 if (channel == NULL) {
176 TRANS_LOGE(TRANS_SDK, "param invalid");
177 return NULL;
178 }
179 TcpDirectChannelInfo *item = (TcpDirectChannelInfo *)SoftBusCalloc(sizeof(TcpDirectChannelInfo));
180 if (item == NULL) {
181 TRANS_LOGE(TRANS_SDK, "calloc failed");
182 return NULL;
183 }
184 item->channelId = channel->channelId;
185 item->detail.fd = channel->fd;
186 item->detail.channelType = channel->channelType;
187 if (SoftBusMutexInit(&(item->detail.fdLock), NULL) != SOFTBUS_OK) {
188 SoftBusFree(item);
189 TRANS_LOGE(TRANS_SDK, "init fd lock failed");
190 return NULL;
191 }
192 if (memcpy_s(item->detail.sessionKey, SESSION_KEY_LENGTH, channel->sessionKey, SESSION_KEY_LENGTH) != EOK) {
193 SoftBusFree(item);
194 TRANS_LOGE(TRANS_SDK, "sessionKey copy failed");
195 return NULL;
196 }
197 if (strcpy_s(item->detail.myIp, IP_LEN, channel->myIp) != EOK) {
198 SoftBusFree(item);
199 TRANS_LOGE(TRANS_SDK, "myIp copy failed");
200 return NULL;
201 }
202 return item;
203 }
204
ClientTransCheckTdcChannelExist(int32_t channelId)205 static int32_t ClientTransCheckTdcChannelExist(int32_t channelId)
206 {
207 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
208 TRANS_LOGE(TRANS_SDK, "lock failed.");
209 return SOFTBUS_LOCK_ERR;
210 }
211 TcpDirectChannelInfo *item = NULL;
212 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
213 if (item->channelId == channelId) {
214 TRANS_LOGE(TRANS_SDK, "tcp direct already exist. channelId=%{public}d", channelId);
215 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
216 return SOFTBUS_TRANS_TDC_CHANNEL_ALREADY_EXIST;
217 }
218 }
219 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
220 return SOFTBUS_OK;
221 }
222
TransTdcDelChannelInfo(int32_t channelId,int32_t errCode)223 static void TransTdcDelChannelInfo(int32_t channelId, int32_t errCode)
224 {
225 TRANS_LOGI(TRANS_SDK, "Delete tdc channelId=%{public}d.", channelId);
226
227 TcpDirectChannelInfo *item = NULL;
228 TcpDirectChannelInfo *nextNode = NULL;
229 if (g_tcpDirectChannelInfoList == NULL) {
230 return;
231 }
232 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
233 TRANS_LOGE(TRANS_SDK, "lock failed");
234 return;
235 }
236
237 LIST_FOR_EACH_ENTRY_SAFE(item, nextNode, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
238 if (item->channelId == channelId) {
239 if (errCode == SOFTBUS_TRANS_NEGOTIATE_REJECTED) {
240 TransTdcCloseFd(item->detail.fd);
241 TRANS_LOGI(
242 TRANS_SDK, "Server reject conn, channelId=%{public}d, fd=%{public}d", channelId, item->detail.fd);
243 } else {
244 TransTdcReleaseFd(item->detail.fd);
245 }
246 ListDelete(&item->node);
247 SoftBusMutexDestroy(&(item->detail.fdLock));
248 SoftBusFree(item);
249 item = NULL;
250 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
251 TRANS_LOGI(TRANS_SDK, "Delete tdc item success. channelId=%{public}d", channelId);
252 return;
253 }
254 }
255
256 TRANS_LOGE(TRANS_SDK, "Target item not exist. channelId=%{public}d", channelId);
257 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
258 }
259
ClientTransTdcHandleListener(const char * sessionName,const ChannelInfo * channel)260 static int32_t ClientTransTdcHandleListener(const char *sessionName, const ChannelInfo *channel)
261 {
262 bool isSocket = false;
263 int32_t ret = ClientTransTdcIfChannelForSocket(sessionName, &isSocket);
264 if (ret != SOFTBUS_OK) {
265 TRANS_LOGE(TRANS_SDK, "get channel socket fail, channelId=%{public}d", channel->channelId);
266 return ret;
267 }
268
269 if (channel->isServer && isSocket) {
270 TRANS_LOGI(TRANS_SDK, "no need listen here, channelId=%{public}d", channel->channelId);
271 return SOFTBUS_OK;
272 }
273
274 ret = TransTdcCreateListenerWithoutAddTrigger(channel->fd);
275 if (ret != SOFTBUS_OK) {
276 TRANS_LOGE(TRANS_SDK, "create listener fail, channelId=%{public}d", channel->channelId);
277 return ret;
278 }
279 if (g_tcpDirectChannelInfoList == NULL) {
280 TRANS_LOGE(TRANS_SDK, "g_tcpDirectChannelInfoList is NULL, channelId=%{public}d", channel->channelId);
281 return SOFTBUS_INVALID_PARAM;
282 }
283 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
284 TRANS_LOGE(TRANS_SDK, "lock failed, channelId=%{public}d", channel->channelId);
285 return SOFTBUS_LOCK_ERR;
286 }
287
288 TcpDirectChannelInfo info;
289 (void)memset_s(&info, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
290 TcpDirectChannelInfo *res = TransTdcGetInfoById(channel->channelId, &info);
291 if (res == NULL) {
292 DelTrigger(DIRECT_CHANNEL_CLIENT, channel->fd, READ_TRIGGER);
293 TRANS_LOGE(TRANS_SDK, "TransTdcGetInfoById failed, channelId=%{public}d", channel->channelId);
294 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
295 return SOFTBUS_NOT_FIND;
296 }
297
298 if (!info.detail.needStopListener) {
299 TRANS_LOGI(TRANS_SDK, "info.detail.needStopListener false, channelId=%{public}d", channel->channelId);
300 AddTrigger(DIRECT_CHANNEL_CLIENT, channel->fd, READ_TRIGGER);
301 }
302 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
303 return SOFTBUS_OK;
304 }
305
ClientTransSetTcpOption(int32_t fd)306 static int32_t ClientTransSetTcpOption(int32_t fd)
307 {
308 int32_t ret = ConnSetTcpKeepalive(fd, HEART_TIME, TCP_KEEPALIVE_INTERVAL, TCP_KEEPALIVE_COUNT);
309 if (ret != SOFTBUS_OK) {
310 TRANS_LOGE(TRANS_SDK, "ConnSetTcpKeepalive failed, fd=%{public}d.", fd);
311 return ret;
312 }
313 ret = ConnSetTcpUserTimeOut(fd, USER_TIME_OUT);
314 if (ret != SOFTBUS_OK) {
315 TRANS_LOGE(TRANS_SDK, "ConnSetTcpUserTimeOut failed, fd=%{public}d.", fd);
316 return ret;
317 }
318 return SOFTBUS_OK;
319 }
320
ClientTransTdcOnChannelOpened(const char * sessionName,const ChannelInfo * channel)321 int32_t ClientTransTdcOnChannelOpened(const char *sessionName, const ChannelInfo *channel)
322 {
323 TRANS_CHECK_AND_RETURN_RET_LOGE(sessionName != NULL && channel != NULL,
324 SOFTBUS_INVALID_PARAM, TRANS_SDK, "param invalid");
325
326 int32_t ret = ClientTransCheckTdcChannelExist(channel->channelId);
327 TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_FILE, "check tdc channel fail!");
328
329 TcpDirectChannelInfo *item = TransGetNewTcpChannel(channel);
330 TRANS_CHECK_AND_RETURN_RET_LOGE(item != NULL, SOFTBUS_MEM_ERR,
331 TRANS_SDK, "get new tcp channel err. channelId=%{public}d", channel->channelId);
332 ret = TransAddDataBufNode(channel->channelId, channel->fd);
333 if (ret != SOFTBUS_OK) {
334 TRANS_LOGE(TRANS_SDK, "add node fail. channelId=%{public}d, fd=%{public}d", channel->channelId, channel->fd);
335 SoftBusFree(item);
336 return ret;
337 }
338
339 ret = ClientTransSetTcpOption(channel->fd);
340 if (ret != SOFTBUS_OK) {
341 goto EXIT_ERR;
342 }
343 ret = SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock);
344 if (ret != SOFTBUS_OK) {
345 TRANS_LOGE(TRANS_SDK, "lock failed.");
346 goto EXIT_ERR;
347 }
348 ListAdd(&g_tcpDirectChannelInfoList->list, &item->node);
349 TRANS_LOGI(TRANS_SDK, "add channelId=%{public}d, fd=%{public}d", item->channelId, channel->fd);
350 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
351
352 ret = ClientTransTdcOnSessionOpened(sessionName, channel);
353 if (ret != SOFTBUS_OK) {
354 TransDelDataBufNode(channel->channelId);
355 TransTdcDelChannelInfo(channel->channelId, ret);
356 TRANS_LOGE(TRANS_SDK, "notify on session opened err.");
357 return ret;
358 }
359
360 ret = ClientTransTdcHandleListener(sessionName, channel);
361 if (ret != SOFTBUS_OK) {
362 ClientTransTdcOnSessionClosed(channel->channelId, SHUTDOWN_REASON_LOCAL);
363 TransDelDataBufNode(channel->channelId);
364 TransTdcDelChannelInfo(channel->channelId, ret);
365 return ret;
366 }
367
368 return SOFTBUS_OK;
369 EXIT_ERR:
370 TransDelDataBufNode(channel->channelId);
371 SoftBusFree(item);
372 return ret;
373 }
374
TransTdcManagerInit(const IClientSessionCallBack * callback)375 int32_t TransTdcManagerInit(const IClientSessionCallBack *callback)
376 {
377 g_tcpDirectChannelInfoList = CreateSoftBusList();
378 if (g_tcpDirectChannelInfoList == NULL || TransDataListInit() != SOFTBUS_OK) {
379 TRANS_LOGE(TRANS_INIT, "init tcp direct channel fail.");
380 return SOFTBUS_NO_INIT;
381 }
382 int32_t ret = ClientTransTdcSetCallBack(callback);
383 if (ret != SOFTBUS_OK) {
384 TRANS_LOGE(TRANS_INIT, "ClientTransTdcSetCallBack fail, ret=%{public}d", ret);
385 return ret;
386 }
387 ret = PendingInit(PENDING_TYPE_DIRECT);
388 if (ret != SOFTBUS_OK) {
389 TRANS_LOGE(TRANS_INIT, "trans direct pending init failed, ret=%{public}d", ret);
390 return SOFTBUS_NO_INIT;
391 }
392 TRANS_LOGE(TRANS_INIT, "init tcp direct channel success.");
393 return SOFTBUS_OK;
394 }
395
TransTdcManagerDeinit(void)396 void TransTdcManagerDeinit(void)
397 {
398 if (g_tcpDirectChannelInfoList == NULL) {
399 return;
400 }
401
402 TransDataListDeinit();
403 DestroySoftBusList(g_tcpDirectChannelInfoList);
404 g_tcpDirectChannelInfoList = NULL;
405 PendingDeinit(PENDING_TYPE_DIRECT);
406 }
407
ClientTransTdcOnChannelOpenFailed(int32_t channelId,int32_t errCode)408 int32_t ClientTransTdcOnChannelOpenFailed(int32_t channelId, int32_t errCode)
409 {
410 return ClientTransTdcOnSessionOpenFailed(channelId, errCode);
411 }
412
TransTdcGetSessionKey(int32_t channelId,char * key,unsigned int len)413 int32_t TransTdcGetSessionKey(int32_t channelId, char *key, unsigned int len)
414 {
415 if (key == NULL) {
416 TRANS_LOGW(TRANS_SDK, "invalid param.");
417 return SOFTBUS_INVALID_PARAM;
418 }
419 TcpDirectChannelInfo channel;
420 if (TransTdcGetInfoById(channelId, &channel) == NULL) {
421 TRANS_LOGE(TRANS_SDK, "get tdc info failed. channelId=%{public}d", channelId);
422 return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
423 }
424 if (memcpy_s(key, len, channel.detail.sessionKey, SESSION_KEY_LENGTH) != EOK) {
425 TRANS_LOGE(TRANS_SDK, "copy session key failed.");
426 return SOFTBUS_MEM_ERR;
427 }
428 return SOFTBUS_OK;
429 }
430
TransTdcGetHandle(int32_t channelId,int * handle)431 int32_t TransTdcGetHandle(int32_t channelId, int *handle)
432 {
433 if (handle == NULL) {
434 TRANS_LOGW(TRANS_SDK, "invalid param.");
435 return SOFTBUS_INVALID_PARAM;
436 }
437 TcpDirectChannelInfo channel;
438 if (TransTdcGetInfoById(channelId, &channel) == NULL) {
439 TRANS_LOGE(TRANS_SDK, "get tdc info failed. channelId=%{public}d", channelId);
440 return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
441 }
442 *handle = channel.detail.fd;
443 return SOFTBUS_OK;
444 }
445
TransDisableSessionListener(int32_t channelId)446 int32_t TransDisableSessionListener(int32_t channelId)
447 {
448 TcpDirectChannelInfo channel;
449 if (TransTdcGetInfoById(channelId, &channel) == NULL) {
450 TRANS_LOGE(TRANS_SDK, "get tdc info failed. channelId=%{public}d", channelId);
451 return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
452 }
453 if (channel.detail.fd < 0) {
454 TRANS_LOGE(TRANS_SDK, "invalid handle.");
455 return SOFTBUS_INVALID_FD;
456 }
457 if (g_tcpDirectChannelInfoList == NULL) {
458 TRANS_LOGE(TRANS_SDK, "g_tcpDirectChannelInfoList is NULL, channelId=%{public}d", channelId);
459 return SOFTBUS_NO_INIT;
460 }
461 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
462 TRANS_LOGE(TRANS_SDK, "lock failed, channelId=%{public}d", channelId);
463 return SOFTBUS_LOCK_ERR;
464 }
465
466 (void)TransTdcSetListenerStateById(channelId, true);
467 int32_t ret = TransTdcStopRead(channel.detail.fd);
468 if (ret != SOFTBUS_OK) {
469 TRANS_LOGW(TRANS_SDK, "stop read failed. channelId=%{public}d, ret=%{public}d", channelId, ret);
470 }
471 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
472 return SOFTBUS_OK;
473 }
474
TransUpdateFdState(int32_t channelId)475 void TransUpdateFdState(int32_t channelId)
476 {
477 if (g_tcpDirectChannelInfoList == NULL) {
478 TRANS_LOGE(TRANS_SDK, "g_tcpDirectChannelInfoList is NULL, channelId=%{public}d", channelId);
479 return;
480 }
481 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
482 TRANS_LOGE(TRANS_SDK, "lock failed, channelId=%{public}d", channelId);
483 return;
484 }
485
486 TcpDirectChannelInfo *item = NULL;
487 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
488 if (item->channelId == channelId) {
489 item->detail.fdRefCnt--;
490 if (item->detail.needRelease && item->detail.fdRefCnt <= 0) {
491 SoftBusMutexDestroy(&(item->detail.fdLock));
492 ListDelete(&item->node);
493 SoftBusFree(item);
494 item = NULL;
495 TRANS_LOGI(TRANS_SDK, "Delete tdc item success. channelId=%{public}d", channelId);
496 }
497 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
498 return;
499 }
500 }
501
502 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
503 TRANS_LOGE(TRANS_SDK, "channel not found, channelId=%{public}d", channelId);
504 return;
505 }
506