1 /*
2 * Copyright (c) 2021-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 "client_trans_tcp_direct_manager.h"
17
18 #include <securec.h>
19
20 #include "client_bus_center_manager.h"
21 #include "client_trans_tcp_direct_callback.h"
22 #include "client_trans_tcp_direct_listener.h"
23 #include "softbus_adapter_mem.h"
24 #include "softbus_base_listener.h"
25 #include "softbus_def.h"
26 #include "softbus_error_code.h"
27 #include "softbus_mintp_socket.h"
28 #include "softbus_socket.h"
29 #include "softbus_utils.h"
30 #include "trans_log.h"
31 #include "trans_pending_pkt.h"
32 #include "trans_server_proxy.h"
33
34 #define HEART_TIME 300
35 #define TCP_KEEPALIVE_INTERVAL 4
36 #define TCP_KEEPALIVE_COUNT 5
37 #define USER_TIME_OUT (320 * 1000)
38 #define MS_TO_US 1000
39
40 static SoftBusList *g_tcpDirectChannelInfoList = NULL;
41
CheckInfoAndMutexLock(TcpDirectChannelInfo * info)42 static bool CheckInfoAndMutexLock(TcpDirectChannelInfo *info)
43 {
44 if (info == NULL) {
45 TRANS_LOGE(TRANS_SDK, "param invalid.");
46 return false;
47 }
48 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
49 TRANS_LOGE(TRANS_SDK, "lock failed");
50 return false;
51 }
52 return true;
53 }
54
TransTdcGetInfoById(int32_t channelId,TcpDirectChannelInfo * info)55 int32_t TransTdcGetInfoById(int32_t channelId, TcpDirectChannelInfo *info)
56 {
57 if (!CheckInfoAndMutexLock(info)) {
58 return SOFTBUS_LOCK_ERR;
59 }
60
61 TcpDirectChannelInfo *item = NULL;
62 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
63 if (item->channelId == channelId) {
64 (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
65 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
66 return SOFTBUS_OK;
67 }
68 }
69
70 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
71 return SOFTBUS_NOT_FIND;
72 }
73
TransTdcSetListenerStateById(int32_t channelId,bool needStopListener)74 int32_t TransTdcSetListenerStateById(int32_t channelId, bool needStopListener)
75 {
76 if (g_tcpDirectChannelInfoList == NULL) {
77 TRANS_LOGE(TRANS_SDK, "g_tcpDirectChannelInfoList is NULL, channelId=%{public}d", channelId);
78 return SOFTBUS_INVALID_PARAM;
79 }
80 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
81 TRANS_LOGE(TRANS_SDK, "lock failed, channelId=%{public}d", channelId);
82 return SOFTBUS_LOCK_ERR;
83 }
84
85 TcpDirectChannelInfo *item = NULL;
86 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
87 if (item->channelId == channelId) {
88 item->detail.needStopListener = needStopListener;
89 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
90 TRANS_LOGI(
91 TRANS_SDK, "succ, channelId=%{public}d, needStopListener=%{public}d", channelId, needStopListener);
92 return SOFTBUS_OK;
93 }
94 }
95
96 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
97 TRANS_LOGE(TRANS_SDK, "channel not found, channelId=%{public}d", channelId);
98 return SOFTBUS_NOT_FIND;
99 }
100
TransTdcGetInfoIncFdRefById(int32_t channelId,TcpDirectChannelInfo * info,bool withSeq)101 TcpDirectChannelInfo *TransTdcGetInfoIncFdRefById(int32_t channelId, TcpDirectChannelInfo *info, bool withSeq)
102 {
103 if (!CheckInfoAndMutexLock(info)) {
104 return NULL;
105 }
106
107 TcpDirectChannelInfo *item = NULL;
108 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
109 if (item->channelId == channelId) {
110 (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
111 item->detail.sequence = withSeq ? (item->detail.sequence + 1) : (item->detail.sequence);
112 item->detail.fdRefCnt++;
113 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
114 return item;
115 }
116 }
117
118 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
119 return NULL;
120 }
121
TransTdcGetInfoByFd(int32_t fd,TcpDirectChannelInfo * info)122 int32_t TransTdcGetInfoByFd(int32_t fd, TcpDirectChannelInfo *info)
123 {
124 if (!CheckInfoAndMutexLock(info)) {
125 return SOFTBUS_LOCK_ERR;
126 }
127
128 TcpDirectChannelInfo *item = NULL;
129 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
130 if (item->detail.fd == fd) {
131 (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
132 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
133 return SOFTBUS_OK;
134 }
135 }
136
137 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
138 return SOFTBUS_NOT_FIND;
139 }
140
TransTdcDeleteChannelInfo(int32_t channelId)141 static void TransTdcDeleteChannelInfo(int32_t channelId)
142 {
143 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
144 TRANS_LOGE(TRANS_SDK, "lock failed");
145 return;
146 }
147
148 TcpDirectChannelInfo *item = NULL;
149 TcpDirectChannelInfo *next = NULL;
150 LIST_FOR_EACH_ENTRY_SAFE(item, next, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
151 if (item->channelId != channelId) {
152 continue;
153 }
154
155 item->detail.needRelease = true;
156 if (item->detail.fdRefCnt <= 0) {
157 TransTdcReleaseFd(item->detail.fd);
158 (void)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
TransTdcCloseChannel(int32_t channelId)173 void TransTdcCloseChannel(int32_t channelId)
174 {
175 TRANS_LOGI(TRANS_SDK, "Close tdc Channel, channelId=%{public}d.", channelId);
176
177 TransTdcDeleteChannelInfo(channelId);
178 if (ServerIpcCloseChannel(NULL, channelId, CHANNEL_TYPE_TCP_DIRECT) != SOFTBUS_OK) {
179 TRANS_LOGE(TRANS_SDK, "close server tdc channelId=%{public}d err.", channelId);
180 }
181 }
182
TransGetNewTcpChannel(const ChannelInfo * channel)183 static TcpDirectChannelInfo *TransGetNewTcpChannel(const ChannelInfo *channel)
184 {
185 if (channel == NULL) {
186 TRANS_LOGE(TRANS_SDK, "param invalid");
187 return NULL;
188 }
189 TcpDirectChannelInfo *item = (TcpDirectChannelInfo *)SoftBusCalloc(sizeof(TcpDirectChannelInfo));
190 if (item == NULL) {
191 TRANS_LOGE(TRANS_SDK, "calloc failed");
192 return NULL;
193 }
194 item->channelId = channel->channelId;
195 item->detail.fd = channel->fd;
196 item->detail.channelType = channel->channelType;
197 item->detail.isLowLatency = channel->isLowLatency;
198 item->detail.fdProtocol = channel->fdProtocol;
199 item->detail.peerPort = channel->peerPort;
200 if (SoftBusMutexInit(&(item->detail.fdLock), NULL) != SOFTBUS_OK) {
201 SoftBusFree(item);
202 TRANS_LOGE(TRANS_SDK, "init fd lock failed");
203 return NULL;
204 }
205 if (memcpy_s(item->detail.sessionKey, SESSION_KEY_LENGTH, channel->sessionKey, channel->keyLen) != EOK) {
206 (void)SoftBusMutexDestroy(&(item->detail.fdLock));
207 SoftBusFree(item);
208 TRANS_LOGE(TRANS_SDK, "sessionKey copy failed");
209 return NULL;
210 }
211 if (strcpy_s(item->detail.myIp, IP_LEN, channel->myIp) != EOK) {
212 (void)SoftBusMutexDestroy(&(item->detail.fdLock));
213 SoftBusFree(item);
214 TRANS_LOGE(TRANS_SDK, "myIp copy failed");
215 return NULL;
216 }
217 if (strcpy_s(item->detail.peerIp, IP_LEN, channel->peerIp) != EOK) {
218 (void)SoftBusMutexDestroy(&(item->detail.fdLock));
219 SoftBusFree(item);
220 TRANS_LOGE(TRANS_SDK, "peerIp copy failed");
221 return NULL;
222 }
223 if (strcpy_s(item->detail.peerDeviceId, DEVICE_ID_SIZE_MAX, channel->peerDeviceId) != EOK) {
224 (void)SoftBusMutexDestroy(&(item->detail.fdLock));
225 SoftBusFree(item);
226 TRANS_LOGE(TRANS_SDK, "peerDeviceId copy failed");
227 return NULL;
228 }
229 if (strcpy_s(item->detail.pkgName, PKG_NAME_SIZE_MAX, channel->pkgName) != EOK) {
230 (void)SoftBusMutexDestroy(&(item->detail.fdLock));
231 SoftBusFree(item);
232 TRANS_LOGE(TRANS_SDK, "pkgName copy failed");
233 return NULL;
234 }
235 return item;
236 }
237
ClientTransCheckTdcChannelExist(int32_t channelId)238 static int32_t ClientTransCheckTdcChannelExist(int32_t channelId)
239 {
240 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
241 TRANS_LOGE(TRANS_SDK, "lock failed.");
242 return SOFTBUS_LOCK_ERR;
243 }
244 TcpDirectChannelInfo *item = NULL;
245 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
246 if (item->channelId == channelId) {
247 TRANS_LOGE(TRANS_SDK, "tcp direct already exist. channelId=%{public}d", channelId);
248 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
249 return SOFTBUS_TRANS_TDC_CHANNEL_ALREADY_EXIST;
250 }
251 }
252 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
253 return SOFTBUS_OK;
254 }
255
TransTdcReleaseFdResources(int32_t fd,int32_t errCode)256 static void TransTdcReleaseFdResources(int32_t fd, int32_t errCode)
257 {
258 if (errCode == SOFTBUS_TRANS_NEGOTIATE_REJECTED) {
259 TransTdcCloseFd(fd);
260 TRANS_LOGI(TRANS_SDK, "Server reject conn, fd=%{public}d", fd);
261 } else {
262 TransTdcReleaseFd(fd);
263 }
264 }
265
TransTdcDelChannelInfo(int32_t channelId,int32_t errCode)266 static void TransTdcDelChannelInfo(int32_t channelId, int32_t errCode)
267 {
268 TRANS_LOGI(TRANS_SDK, "Delete tdc channelId=%{public}d.", channelId);
269
270 TcpDirectChannelInfo *item = NULL;
271 TcpDirectChannelInfo *nextNode = NULL;
272 if (g_tcpDirectChannelInfoList == NULL) {
273 return;
274 }
275 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
276 TRANS_LOGE(TRANS_SDK, "lock failed");
277 return;
278 }
279
280 LIST_FOR_EACH_ENTRY_SAFE(item, nextNode, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
281 if (item->channelId == channelId) {
282 item->detail.needRelease = true;
283 if (item->detail.fdRefCnt <= 0) {
284 TransTdcReleaseFdResources(item->detail.fd, errCode);
285 (void)SoftBusMutexDestroy(&(item->detail.fdLock));
286 ListDelete(&item->node);
287 SoftBusFree(item);
288 item = NULL;
289 }
290 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
291 TRANS_LOGI(TRANS_SDK, "Delete tdc item success. channelId=%{public}d", channelId);
292 return;
293 }
294 }
295
296 TRANS_LOGE(TRANS_SDK, "Target item not exist. channelId=%{public}d", channelId);
297 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
298 }
299
ClientTransTdcHandleListener(const char * sessionName,const ChannelInfo * channel)300 static int32_t ClientTransTdcHandleListener(const char *sessionName, const ChannelInfo *channel)
301 {
302 bool isSocket = false;
303 int32_t ret = ClientTransTdcIfChannelForSocket(sessionName, &isSocket);
304 if (ret != SOFTBUS_OK) {
305 TRANS_LOGE(TRANS_SDK, "get channel socket fail, channelId=%{public}d", channel->channelId);
306 return ret;
307 }
308
309 if (channel->isServer && isSocket) {
310 TRANS_LOGI(TRANS_SDK, "no need listen here, channelId=%{public}d", channel->channelId);
311 return SOFTBUS_OK;
312 }
313
314 ret = TransTdcCreateListenerWithoutAddTrigger(channel->fd);
315 if (ret != SOFTBUS_OK) {
316 TRANS_LOGE(TRANS_SDK, "create listener fail, channelId=%{public}d", channel->channelId);
317 return ret;
318 }
319 if (g_tcpDirectChannelInfoList == NULL) {
320 TRANS_LOGE(TRANS_SDK, "g_tcpDirectChannelInfoList is NULL, channelId=%{public}d", channel->channelId);
321 return SOFTBUS_INVALID_PARAM;
322 }
323 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
324 TRANS_LOGE(TRANS_SDK, "lock failed, channelId=%{public}d", channel->channelId);
325 return SOFTBUS_LOCK_ERR;
326 }
327
328 TcpDirectChannelInfo info;
329 (void)memset_s(&info, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
330 ret = TransTdcGetInfoById(channel->channelId, &info);
331 if (ret != SOFTBUS_OK) {
332 DelTrigger(DIRECT_CHANNEL_CLIENT, channel->fd, READ_TRIGGER);
333 TRANS_LOGE(TRANS_SDK, "TransTdcGetInfoById failed, channelId=%{public}d", channel->channelId);
334 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
335 return SOFTBUS_NOT_FIND;
336 }
337
338 if (!info.detail.needStopListener) {
339 TRANS_LOGI(TRANS_SDK, "info.detail.needStopListener false, channelId=%{public}d", channel->channelId);
340 AddTrigger(DIRECT_CHANNEL_CLIENT, channel->fd, READ_TRIGGER);
341 }
342 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
343 return SOFTBUS_OK;
344 }
345
ClientTransSetTcpOption(int32_t fd)346 static int32_t ClientTransSetTcpOption(int32_t fd)
347 {
348 int32_t ret = ConnSetTcpKeepalive(fd, HEART_TIME, TCP_KEEPALIVE_INTERVAL, TCP_KEEPALIVE_COUNT);
349 if (ret != SOFTBUS_OK) {
350 TRANS_LOGE(TRANS_SDK, "ConnSetTcpKeepalive failed, fd=%{public}d.", fd);
351 return ret;
352 }
353 ret = ConnSetTcpUserTimeOut(fd, USER_TIME_OUT);
354 if (ret != SOFTBUS_OK) {
355 TRANS_LOGE(TRANS_SDK, "ConnSetTcpUserTimeOut failed, fd=%{public}d.", fd);
356 return ret;
357 }
358 return SOFTBUS_OK;
359 }
360
GetFdByPeerIpAndPort(const char * peerIp,uint16_t peerPort,int32_t * fd)361 static int32_t GetFdByPeerIpAndPort(const char *peerIp, uint16_t peerPort, int32_t *fd)
362 {
363 if (g_tcpDirectChannelInfoList == NULL) {
364 TRANS_LOGE(TRANS_SDK, "g_tcpDirectChannelInfoList is NULL");
365 return SOFTBUS_INVALID_PARAM;
366 }
367 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
368 TRANS_LOGE(TRANS_SDK, "lock failed");
369 return SOFTBUS_LOCK_ERR;
370 }
371
372 TcpDirectChannelInfo *item = NULL;
373 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
374 if (strcmp(item->detail.peerIp, peerIp) == 0 && item->detail.peerPort == peerPort) {
375 *fd = item->detail.fd;
376 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
377 return SOFTBUS_OK;
378 }
379 }
380
381 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
382 TRANS_LOGE(TRANS_SDK, "channel not found, peerPort=%{public}d", peerPort);
383 return SOFTBUS_NOT_FIND;
384 }
385
OnTimeSyncResultByIp(const TimeSyncResultWithSocket * info,int32_t result)386 static void OnTimeSyncResultByIp(const TimeSyncResultWithSocket *info, int32_t result)
387 {
388 if (result != SOFTBUS_OK) {
389 TRANS_LOGW(TRANS_SDK, "time sync err, result=%{public}d", result);
390 return;
391 }
392 if (info == NULL) {
393 TRANS_LOGW(TRANS_SDK, "time sync info is null");
394 return;
395 }
396 int32_t fd = -1;
397 int32_t ret = GetFdByPeerIpAndPort(info->targetSocketInfo.peerIp, info->targetSocketInfo.peerPort, &fd);
398 if (ret != SOFTBUS_OK) {
399 TRANS_LOGE(TRANS_SDK, "get fd by peer ip and port failed, ret=%{public}d", ret);
400 return;
401 }
402 MintpTimeSync timeSync;
403 timeSync.valid = 1;
404 timeSync.offset = info->result.millisecond * MS_TO_US + info->result.microsecond;
405 ret = SetMintpSocketTimeSync(fd, &timeSync);
406 if (ret != SOFTBUS_OK) {
407 TRANS_LOGW(TRANS_SDK, "SetMintpSocketTimeSync failed, ret=%{public}d", ret);
408 return;
409 }
410 TRANS_LOGI(TRANS_SDK, "time sync success, offset=%{public}d", timeSync.offset);
411 }
412
413 static ITimeSyncCbWithSocket g_timeSyncCallback = {
414 .onTimeSyncResultWithSocket = OnTimeSyncResultByIp,
415 };
416
TransStartTimeSync(const ChannelInfo * channel)417 static int32_t TransStartTimeSync(const ChannelInfo *channel)
418 {
419 TimeSyncSocketInfo socketInfo;
420 if (strcpy_s(socketInfo.peerIp, IP_STR_MAX_LEN, channel->peerIp) != EOK) {
421 TRANS_LOGE(TRANS_SDK, "peerIp copy failed");
422 return SOFTBUS_STRCPY_ERR;
423 }
424 socketInfo.peerPort = channel->peerPort;
425 if (strcpy_s(socketInfo.targetNetworkId, NETWORK_ID_BUF_LEN, channel->peerDeviceId) != EOK) {
426 TRANS_LOGE(TRANS_SDK, "targetNetworkId copy failed");
427 return SOFTBUS_STRCPY_ERR;
428 }
429 int32_t ret =
430 StartTimeSyncWithSocketInner(channel->pkgName, &socketInfo, HIGH_ACCURACY, SHORT_PERIOD, &g_timeSyncCallback);
431 if (ret != SOFTBUS_OK) {
432 TRANS_LOGE(TRANS_SDK, "StartTimeSync failed, ret=%{public}d", ret);
433 return ret;
434 }
435 TRANS_LOGI(TRANS_SDK, "StartTimeSync success");
436 return SOFTBUS_OK;
437 }
438
ClientTransTdcOnChannelOpened(const char * sessionName,const ChannelInfo * channel,SocketAccessInfo * accessInfo)439 int32_t ClientTransTdcOnChannelOpened(const char *sessionName, const ChannelInfo *channel, SocketAccessInfo *accessInfo)
440 {
441 TRANS_CHECK_AND_RETURN_RET_LOGE(
442 sessionName != NULL && channel != NULL, SOFTBUS_INVALID_PARAM, TRANS_SDK, "param invalid");
443
444 int32_t ret = ClientTransCheckTdcChannelExist(channel->channelId);
445 TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_FILE, "check tdc channel fail!");
446
447 TcpDirectChannelInfo *item = TransGetNewTcpChannel(channel);
448 TRANS_CHECK_AND_RETURN_RET_LOGE(
449 item != NULL, SOFTBUS_MEM_ERR, TRANS_SDK, "get new tcp channel err. channelId=%{public}d", channel->channelId);
450 ret = TransAddDataBufNode(channel->channelId, channel->fd);
451 if (ret != SOFTBUS_OK) {
452 TRANS_LOGE(TRANS_SDK, "add node fail. channelId=%{public}d, fd=%{public}d", channel->channelId, channel->fd);
453 SoftBusFree(item);
454 return ret;
455 }
456 if (channel->fdProtocol != LNN_PROTOCOL_MINTP) {
457 ret = ClientTransSetTcpOption(channel->fd);
458 if (ret != SOFTBUS_OK) {
459 TRANS_LOGW(TRANS_SDK,
460 "Failed to set keep-alive, warning but do not terminate. channelId=%{public}d, fd=%{public}d",
461 channel->channelId, channel->fd);
462 }
463 }
464 ret = SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock);
465 if (ret != SOFTBUS_OK) {
466 TRANS_LOGE(TRANS_SDK, "lock failed.");
467 TransDelDataBufNode(channel->channelId);
468 SoftBusFree(item);
469 return ret;
470 }
471 ListAdd(&g_tcpDirectChannelInfoList->list, &item->node);
472 TRANS_LOGI(TRANS_SDK, "add channelId=%{public}d, fd=%{public}d", item->channelId, channel->fd);
473 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
474 if (channel->fdProtocol == LNN_PROTOCOL_MINTP && !channel->isServer) {
475 (void)TransStartTimeSync(channel);
476 }
477 ret = ClientTransTdcOnSessionOpened(sessionName, channel, accessInfo);
478 if (ret != SOFTBUS_OK) {
479 TransDelDataBufNode(channel->channelId);
480 TransTdcDelChannelInfo(channel->channelId, ret);
481 TRANS_LOGE(TRANS_SDK, "notify on session opened err.");
482 return ret;
483 }
484
485 ret = ClientTransTdcHandleListener(sessionName, channel);
486 if (ret != SOFTBUS_OK) {
487 ClientTransTdcOnSessionClosed(channel->channelId, SHUTDOWN_REASON_LOCAL);
488 TransDelDataBufNode(channel->channelId);
489 TransTdcDelChannelInfo(channel->channelId, ret);
490 return ret;
491 }
492
493 return SOFTBUS_OK;
494 }
495
TransTdcManagerInit(const IClientSessionCallBack * callback)496 int32_t TransTdcManagerInit(const IClientSessionCallBack *callback)
497 {
498 g_tcpDirectChannelInfoList = CreateSoftBusList();
499 if (g_tcpDirectChannelInfoList == NULL || TransDataListInit() != SOFTBUS_OK) {
500 TRANS_LOGE(TRANS_INIT, "init tcp direct channel fail.");
501 return SOFTBUS_NO_INIT;
502 }
503 int32_t ret = ClientTransTdcSetCallBack(callback);
504 if (ret != SOFTBUS_OK) {
505 TRANS_LOGE(TRANS_INIT, "ClientTransTdcSetCallBack fail, ret=%{public}d", ret);
506 return ret;
507 }
508 ret = PendingInit(PENDING_TYPE_DIRECT);
509 if (ret != SOFTBUS_OK) {
510 TRANS_LOGE(TRANS_INIT, "trans direct pending init failed, ret=%{public}d", ret);
511 return SOFTBUS_NO_INIT;
512 }
513 TRANS_LOGE(TRANS_INIT, "init tcp direct channel success.");
514 return SOFTBUS_OK;
515 }
516
TransTdcManagerDeinit(void)517 void TransTdcManagerDeinit(void)
518 {
519 if (g_tcpDirectChannelInfoList == NULL) {
520 return;
521 }
522
523 TransDataListDeinit();
524 DestroySoftBusList(g_tcpDirectChannelInfoList);
525 g_tcpDirectChannelInfoList = NULL;
526 PendingDeinit(PENDING_TYPE_DIRECT);
527 TdcLockDeinit();
528 }
529
ClientTransTdcOnChannelOpenFailed(int32_t channelId,int32_t errCode)530 int32_t ClientTransTdcOnChannelOpenFailed(int32_t channelId, int32_t errCode)
531 {
532 return ClientTransTdcOnSessionOpenFailed(channelId, errCode);
533 }
534
TransTdcGetSessionKey(int32_t channelId,char * key,unsigned int len)535 int32_t TransTdcGetSessionKey(int32_t channelId, char *key, unsigned int len)
536 {
537 if (key == NULL) {
538 TRANS_LOGW(TRANS_SDK, "invalid param.");
539 return SOFTBUS_INVALID_PARAM;
540 }
541 TcpDirectChannelInfo channel;
542 if (TransTdcGetInfoById(channelId, &channel) != SOFTBUS_OK) {
543 TRANS_LOGE(TRANS_SDK, "get tdc info failed. channelId=%{public}d", channelId);
544 return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
545 }
546 if (memcpy_s(key, len, channel.detail.sessionKey, SESSION_KEY_LENGTH) != EOK) {
547 TRANS_LOGE(TRANS_SDK, "copy session key failed.");
548 return SOFTBUS_MEM_ERR;
549 }
550 return SOFTBUS_OK;
551 }
552
TransTdcGetHandle(int32_t channelId,int * handle)553 int32_t TransTdcGetHandle(int32_t channelId, int *handle)
554 {
555 if (handle == NULL) {
556 TRANS_LOGW(TRANS_SDK, "invalid param.");
557 return SOFTBUS_INVALID_PARAM;
558 }
559 TcpDirectChannelInfo channel;
560 if (TransTdcGetInfoById(channelId, &channel) != SOFTBUS_OK) {
561 TRANS_LOGE(TRANS_SDK, "get tdc info failed. channelId=%{public}d", channelId);
562 return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
563 }
564 *handle = channel.detail.fd;
565 return SOFTBUS_OK;
566 }
567
TransDisableSessionListener(int32_t channelId)568 int32_t TransDisableSessionListener(int32_t channelId)
569 {
570 TcpDirectChannelInfo channel;
571 if (TransTdcGetInfoById(channelId, &channel) != SOFTBUS_OK) {
572 TRANS_LOGE(TRANS_SDK, "get tdc info failed. channelId=%{public}d", channelId);
573 return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
574 }
575 if (channel.detail.fd < 0) {
576 TRANS_LOGE(TRANS_SDK, "invalid handle.");
577 return SOFTBUS_INVALID_FD;
578 }
579 if (g_tcpDirectChannelInfoList == NULL) {
580 TRANS_LOGE(TRANS_SDK, "g_tcpDirectChannelInfoList is NULL, channelId=%{public}d", channelId);
581 return SOFTBUS_NO_INIT;
582 }
583 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
584 TRANS_LOGE(TRANS_SDK, "lock failed, channelId=%{public}d", channelId);
585 return SOFTBUS_LOCK_ERR;
586 }
587
588 (void)TransTdcSetListenerStateById(channelId, true);
589 int32_t ret = TransTdcStopRead(channel.detail.fd);
590 if (ret != SOFTBUS_OK) {
591 TRANS_LOGW(TRANS_SDK, "stop read failed. channelId=%{public}d, ret=%{public}d", channelId, ret);
592 }
593 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
594 return SOFTBUS_OK;
595 }
596
TransUpdateFdState(int32_t channelId)597 void TransUpdateFdState(int32_t channelId)
598 {
599 if (g_tcpDirectChannelInfoList == NULL) {
600 TRANS_LOGE(TRANS_SDK, "g_tcpDirectChannelInfoList is NULL, channelId=%{public}d", channelId);
601 return;
602 }
603 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
604 TRANS_LOGE(TRANS_SDK, "lock failed, channelId=%{public}d", channelId);
605 return;
606 }
607
608 TcpDirectChannelInfo *item = NULL;
609 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
610 if (item->channelId == channelId) {
611 item->detail.fdRefCnt--;
612 if (item->detail.needRelease && item->detail.fdRefCnt <= 0) {
613 TransTdcReleaseFd(item->detail.fd);
614 (void)SoftBusMutexDestroy(&(item->detail.fdLock));
615 ListDelete(&item->node);
616 SoftBusFree(item);
617 item = NULL;
618 TRANS_LOGI(TRANS_SDK, "Delete tdc item success. channelId=%{public}d", channelId);
619 }
620 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
621 return;
622 }
623 }
624
625 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
626 TRANS_LOGE(TRANS_SDK, "channel not found, channelId=%{public}d", channelId);
627 return;
628 }
629
TransStopTimeSync(int32_t channelId)630 int32_t TransStopTimeSync(int32_t channelId)
631 {
632 TcpDirectChannelInfo info;
633 (void)memset_s(&info, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
634 int32_t ret = TransTdcGetInfoById(channelId, &info);
635 if (ret != SOFTBUS_OK) {
636 TRANS_LOGE(TRANS_SDK, "TransTdcGetInfoById failed, channelId=%{public}d", channelId);
637 return ret;
638 }
639 if (info.detail.fdProtocol != LNN_PROTOCOL_MINTP) {
640 return SOFTBUS_OK;
641 }
642 TimeSyncSocketInfo socketInfo;
643 if (strcpy_s(socketInfo.peerIp, IP_STR_MAX_LEN, info.detail.peerIp) != EOK) {
644 TRANS_LOGE(TRANS_SDK, "peerIp copy failed");
645 return SOFTBUS_STRCPY_ERR;
646 }
647 socketInfo.peerPort = info.detail.peerPort;
648 if (strcpy_s(socketInfo.targetNetworkId, NETWORK_ID_BUF_LEN, info.detail.peerDeviceId) != EOK) {
649 TRANS_LOGE(TRANS_SDK, "targetNetworkId copy failed");
650 return SOFTBUS_STRCPY_ERR;
651 }
652 ret = StopTimeSyncWithSocketInner(info.detail.pkgName, &socketInfo);
653 if (ret != SOFTBUS_OK) {
654 TRANS_LOGE(TRANS_SDK, "StopTimeSync failed, ret=%{public}d", ret);
655 return ret;
656 }
657 TRANS_LOGI(TRANS_SDK, "StopTimeSync success");
658 return SOFTBUS_OK;
659 }
660