• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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