• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-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_socket_manager.h"
17 
18 #include <securec.h>
19 
20 #include "anonymizer.h"
21 #include "client_bus_center_manager.h"
22 #include "client_trans_channel_manager.h"
23 #include "client_trans_file_listener.h"
24 #include "client_trans_proxy_file_manager.h"
25 #include "client_trans_tcp_direct_manager.h"
26 #include "client_trans_udp_manager.h"
27 #include "softbus_adapter_mem.h"
28 #include "softbus_adapter_timer.h"
29 #include "softbus_app_info.h"
30 #include "softbus_def.h"
31 #include "softbus_error_code.h"
32 #include "softbus_socket.h"
33 #include "softbus_utils.h"
34 #include "trans_log.h"
35 #include "trans_server_proxy.h"
36 
37 #define NETWORK_ID_LEN 7
38 #define GET_ROUTE_TYPE(type) ((uint32_t)(type) & 0xff)
39 #define GET_CONN_TYPE(type) (((uint32_t)(type) >> 8) & 0xff)
40 #define SENDBYTES_TIMEOUT_S 20
41 
42 #define DISTRIBUTED_DATA_SESSION "distributeddata-default"
43 static IFeatureAbilityRelationChecker *g_relationChecker = NULL;
44 static SoftBusList *g_clientDataSeqInfoList = NULL;
45 
LockClientDataSeqInfoList()46 int32_t LockClientDataSeqInfoList()
47 {
48     if (g_clientDataSeqInfoList == NULL) {
49         TRANS_LOGE(TRANS_INIT, "g_clientDataSeqInfoList not init");
50         return SOFTBUS_TRANS_DATA_SEQ_INFO_NO_INIT;
51     }
52     int32_t ret = SoftBusMutexLock(&(g_clientDataSeqInfoList->lock));
53     if (ret != SOFTBUS_OK) {
54         return SOFTBUS_LOCK_ERR;
55     }
56     return SOFTBUS_OK;
57 }
58 
UnlockClientDataSeqInfoList()59 void UnlockClientDataSeqInfoList()
60 {
61     (void)SoftBusMutexUnlock(&(g_clientDataSeqInfoList->lock));
62 }
63 
TransDataSeqInfoListInit(void)64 int TransDataSeqInfoListInit(void)
65 {
66     g_clientDataSeqInfoList = CreateSoftBusList();
67     if (g_clientDataSeqInfoList == NULL) {
68         TRANS_LOGE(TRANS_INIT, "g_clientDataSeqInfoList not init");
69         return SOFTBUS_TRANS_DATA_SEQ_INFO_NO_INIT;
70     }
71     return SOFTBUS_OK;
72 }
73 
TransDataSeqInfoListDeinit(void)74 void TransDataSeqInfoListDeinit(void)
75 {
76     DestroySoftBusList(g_clientDataSeqInfoList);
77     g_clientDataSeqInfoList = NULL;
78 }
79 
IsValidSessionParam(const SessionParam * param)80 bool IsValidSessionParam(const SessionParam *param)
81 {
82     if ((param == NULL) ||
83         (param->sessionName == NULL) ||
84         (param->peerSessionName == NULL) ||
85         (param->peerDeviceId == NULL) ||
86         (param->groupId == NULL) ||
87         (param->attr == NULL)) {
88         return false;
89     }
90     return true;
91 }
92 
CreateNewSession(const SessionParam * param)93 SessionInfo *CreateNewSession(const SessionParam *param)
94 {
95     if (param == NULL) {
96         TRANS_LOGE(TRANS_SDK, "param is null");
97         return NULL;
98     }
99     SessionInfo *session = (SessionInfo*)SoftBusCalloc(sizeof(SessionInfo));
100     if (session == NULL) {
101         TRANS_LOGE(TRANS_SDK, "calloc failed");
102         return NULL;
103     }
104 
105     if (strcpy_s(session->info.peerSessionName, SESSION_NAME_SIZE_MAX, param->peerSessionName) != EOK ||
106         strcpy_s(session->info.peerDeviceId, DEVICE_ID_SIZE_MAX, param->peerDeviceId) != EOK ||
107         strcpy_s(session->info.groupId, GROUP_ID_SIZE_MAX, param->groupId) != EOK ||
108         memcpy_s(session->linkType, sizeof(param->attr->linkType), param->attr->linkType,
109             sizeof(param->attr->linkType)) != EOK) {
110         TRANS_LOGE(TRANS_SDK, "strcpy failed");
111         SoftBusFree(session);
112         return NULL;
113     }
114 
115     session->sessionId = INVALID_SESSION_ID;
116     session->channelId = INVALID_CHANNEL_ID;
117     session->channelType = CHANNEL_TYPE_BUTT;
118     session->isServer = false;
119     session->role = SESSION_ROLE_INIT;
120     session->enableStatus = ENABLE_STATUS_INIT;
121     session->info.flag = param->attr->dataType;
122     session->isEncrypt = true;
123     session->isAsync = false;
124     session->lifecycle.sessionState = SESSION_STATE_INIT;
125     session->actionId = param->actionId;
126     return session;
127 }
128 
CreateDestroySessionNode(SessionInfo * sessionNode,const ClientSessionServer * server)129 NO_SANITIZE("cfi") DestroySessionInfo *CreateDestroySessionNode(SessionInfo *sessionNode,
130     const ClientSessionServer *server)
131 {
132     if (sessionNode == NULL || server == NULL) {
133         TRANS_LOGE(TRANS_SDK, "invalid param.");
134         return NULL;
135     }
136     DestroySessionInfo *destroyNode = (DestroySessionInfo *)SoftBusCalloc(sizeof(DestroySessionInfo));
137     if (destroyNode == NULL) {
138         TRANS_LOGE(TRANS_SDK, "destroyList malloc fail.");
139         return NULL;
140     }
141     destroyNode->sessionId = sessionNode->sessionId;
142     destroyNode->channelId = sessionNode->channelId;
143     destroyNode->channelType = sessionNode->channelType;
144     destroyNode->isAsync = sessionNode->isAsync;
145     if (!sessionNode->lifecycle.condIsWaiting) {
146         (void)SoftBusCondDestroy(&(sessionNode->lifecycle.callbackCond));
147     } else {
148         (void)SoftBusCondSignal(&(sessionNode->lifecycle.callbackCond)); // destroy in CheckSessionEnableStatus
149         TRANS_LOGI(TRANS_SDK, "sessionId=%{public}d condition is waiting", sessionNode->sessionId);
150     }
151     if (memcpy_s(destroyNode->sessionName, SESSION_NAME_SIZE_MAX, server->sessionName, SESSION_NAME_SIZE_MAX) != EOK) {
152         TRANS_LOGE(TRANS_SDK, "memcpy_s sessionName fail.");
153         SoftBusFree(destroyNode);
154         return NULL;
155     }
156     if (memcpy_s(destroyNode->pkgName, PKG_NAME_SIZE_MAX, server->pkgName, PKG_NAME_SIZE_MAX) != EOK) {
157         TRANS_LOGE(TRANS_SDK, "memcpy_s pkgName fail.");
158         SoftBusFree(destroyNode);
159         return NULL;
160     }
161     if (server->listener.isSocketListener == false) {
162         destroyNode->OnSessionClosed = server->listener.session.OnSessionClosed;
163     } else {
164         destroyNode->OnShutdown = sessionNode->isServer ? server->listener.socketServer.OnShutdown :
165             server->listener.socketClient.OnShutdown;
166     }
167     return destroyNode;
168 }
169 
ClientDestroySession(const ListNode * destroyList,ShutdownReason reason)170 NO_SANITIZE("cfi") void ClientDestroySession(const ListNode *destroyList, ShutdownReason reason)
171 {
172     if (destroyList == NULL) {
173         TRANS_LOGE(TRANS_SDK, "invalid param.");
174         return;
175     }
176     if (IsListEmpty(destroyList)) {
177         TRANS_LOGD(TRANS_SDK, "destroyList is empty fail.");
178         return;
179     }
180     DestroySessionInfo *destroyNode = NULL;
181     DestroySessionInfo *destroyNodeNext = NULL;
182     TRANS_LOGD(TRANS_SDK, "enter.");
183     LIST_FOR_EACH_ENTRY_SAFE(destroyNode, destroyNodeNext, destroyList, DestroySessionInfo, node) {
184         int32_t id = destroyNode->sessionId;
185         (void)ClientDeleteRecvFileList(id);
186         (void)ClientTransCloseChannel(destroyNode->channelId, destroyNode->channelType, id);
187         if (destroyNode->OnSessionClosed != NULL) {
188             destroyNode->OnSessionClosed(id);
189         } else if (destroyNode->OnShutdown != NULL) {
190             destroyNode->OnShutdown(id, reason);
191             (void)TryDeleteEmptySessionServer(destroyNode->pkgName, destroyNode->sessionName);
192         }
193         if ((!destroyNode->isAsync) && destroyNode->lifecycle.sessionState == SESSION_STATE_CANCELLING) {
194             (void)SoftBusCondSignal(&(destroyNode->lifecycle.callbackCond));
195         }
196         ListDelete(&(destroyNode->node));
197         SoftBusFree(destroyNode);
198     }
199     TRANS_LOGD(TRANS_SDK, "ok");
200 }
201 
DestroyClientSessionServer(ClientSessionServer * server,ListNode * destroyList)202 void DestroyClientSessionServer(ClientSessionServer *server, ListNode *destroyList)
203 {
204     if (server == NULL || destroyList == NULL) {
205         TRANS_LOGW(TRANS_SDK, "invalid param");
206         return;
207     }
208 
209     if (!IsListEmpty(&(server->sessionList))) {
210         SessionInfo *sessionNode = NULL;
211         SessionInfo *sessionNodeNext = NULL;
212         LIST_FOR_EACH_ENTRY_SAFE(sessionNode, sessionNodeNext, &(server->sessionList), SessionInfo, node) {
213             DestroySessionInfo *destroyNode = CreateDestroySessionNode(sessionNode, server);
214             if (destroyNode == NULL) {
215                 continue;
216             }
217             DestroySessionId();
218             ListDelete(&sessionNode->node);
219             ListAdd(destroyList, &(destroyNode->node));
220             SoftBusFree(sessionNode);
221         }
222     }
223 
224     ListDelete(&(server->node));
225     char *tmpName = NULL;
226     Anonymize(server->sessionName, &tmpName);
227     TRANS_LOGI(TRANS_SDK, "destroy session server sessionName=%{public}s", AnonymizeWrapper(tmpName));
228     AnonymizeFree(tmpName);
229     SoftBusFree(server);
230 }
231 
GetNewSessionServer(SoftBusSecType type,const char * sessionName,const char * pkgName,const ISessionListener * listener)232 ClientSessionServer *GetNewSessionServer(SoftBusSecType type, const char *sessionName,
233     const char *pkgName, const ISessionListener *listener)
234 {
235     if (sessionName == NULL || pkgName == NULL || listener == NULL) {
236         TRANS_LOGW(TRANS_SDK, "invalid param");
237         return NULL;
238     }
239     ClientSessionServer *server = (ClientSessionServer *)SoftBusCalloc(sizeof(ClientSessionServer));
240     if (server == NULL) {
241         return NULL;
242     }
243     server->type = type;
244     if (strcpy_s(server->pkgName, sizeof(server->pkgName), pkgName) != EOK) {
245         goto EXIT_ERR;
246     }
247     if (strcpy_s(server->sessionName, sizeof(server->sessionName), sessionName) != EOK) {
248         goto EXIT_ERR;
249     }
250     if (memcpy_s(&server->listener.session, sizeof(ISessionListener), listener, sizeof(ISessionListener)) != EOK) {
251         goto EXIT_ERR;
252     }
253     server->listener.isSocketListener = false;
254     server->isSrvEncryptedRawStream = false;
255 
256     ListInit(&server->node);
257     ListInit(&server->sessionList);
258     return server;
259 
260 EXIT_ERR:
261     if (server != NULL) {
262         SoftBusFree(server);
263     }
264     return NULL;
265 }
266 
CreateNonEncryptSessionInfo(const char * sessionName)267 SessionInfo *CreateNonEncryptSessionInfo(const char *sessionName)
268 {
269     if (sessionName == NULL) {
270         TRANS_LOGW(TRANS_SDK, "Invalid param");
271         return NULL;
272     }
273     if (!IsValidString(sessionName, SESSION_NAME_SIZE_MAX - 1)) {
274         TRANS_LOGW(TRANS_SDK, "Invalid param");
275         return NULL;
276     }
277     SessionInfo *session = (SessionInfo *)SoftBusCalloc(sizeof(SessionInfo));
278     if (session == NULL) {
279         return NULL;
280     }
281     session->channelType = CHANNEL_TYPE_AUTH;
282     session->isEncrypt = false;
283     session->actionId = INVALID_ACTION_ID;
284     if (strcpy_s(session->info.peerSessionName, SESSION_NAME_SIZE_MAX, sessionName) != EOK) {
285         SoftBusFree(session);
286         return NULL;
287     }
288     return session;
289 }
290 
ClientTransGetTdcIp(int32_t channelId,char * myIp,int32_t ipLen)291 static int32_t ClientTransGetTdcIp(int32_t channelId, char *myIp, int32_t ipLen)
292 {
293     TcpDirectChannelInfo channel;
294     if (TransTdcGetInfoById(channelId, &channel) != SOFTBUS_OK) {
295         TRANS_LOGE(TRANS_SDK, "not found Tdc channel by channelId=%{public}d", channelId);
296         return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
297     }
298 
299     if (strcpy_s(myIp, ipLen, channel.detail.myIp) != EOK) {
300         TRANS_LOGE(TRANS_SDK, "strcpy_s ip failed, len=%{public}zu", strlen(channel.detail.myIp));
301         return SOFTBUS_STRCPY_ERR;
302     }
303 
304     return SOFTBUS_OK;
305 }
306 
ClientTransGetUdpIp(int32_t channelId,char * myIp,int32_t ipLen)307 static int32_t ClientTransGetUdpIp(int32_t channelId, char *myIp, int32_t ipLen)
308 {
309     UdpChannel channel;
310     if (TransGetUdpChannel(channelId, &channel) != SOFTBUS_OK) {
311         TRANS_LOGE(TRANS_SDK, "not found Udp channel by channelId=%{public}d", channelId);
312         return SOFTBUS_TRANS_UDP_CHANNEL_NOT_FOUND;
313     }
314 
315     if (strcpy_s(myIp, ipLen, channel.info.myIp) != EOK) {
316         TRANS_LOGE(TRANS_SDK, "strcpy_s ip failed, len=%{public}zu", strlen(channel.info.myIp));
317         return SOFTBUS_STRCPY_ERR;
318     }
319 
320     return SOFTBUS_OK;
321 }
322 
323 // determine connection type based on IP
ClientTransCheckHmlIp(const char * ip)324 static bool ClientTransCheckHmlIp(const char *ip)
325 {
326     if (IsHmlIpAddr(ip)) {
327         return true;
328     }
329 
330     return false;
331 }
332 
333 static const char *g_dmHandleAgingSessionName[] = {
334     "ohos.distributedhardware.devicemanager.resident",
335     "com.huawei.devicemanager.resident",
336     "com.huawei.devicemanager.dynamic",
337 };
338 
CheckDMHandleAgingSession(const char * sessionName,const SessionInfo * sessionNode)339 static bool CheckDMHandleAgingSession(const char *sessionName, const SessionInfo *sessionNode)
340 {
341     if (sessionNode->channelType != CHANNEL_TYPE_AUTH) {
342         return false;
343     }
344     const int len = sizeof(g_dmHandleAgingSessionName) / sizeof(g_dmHandleAgingSessionName[0]);
345     for (int i = 0; i < len; i++) {
346         if (strcmp(sessionName, g_dmHandleAgingSessionName[i]) == 0) {
347             TRANS_LOGI(TRANS_SDK, "device management handles aging sessions and keeps opening the session");
348             return true;
349         }
350     }
351     return false;
352 }
353 
354 // determine connection type based on IP, delete session when connection type and parameter connType are consistent
ClientTransCheckNeedDel(const char * name,SessionInfo * sessionNode,int32_t routeType,int32_t connType)355 static bool ClientTransCheckNeedDel(const char *name, SessionInfo *sessionNode, int32_t routeType, int32_t connType)
356 {
357     if (connType == TRANS_CONN_ALL) {
358         if (routeType != ROUTE_TYPE_ALL && sessionNode->routeType != routeType) {
359             return false;
360         }
361 
362         if (CheckDMHandleAgingSession(name, sessionNode)) {
363             return false;
364         }
365         return true;
366     }
367     /*
368     * only when the function OnWifiDirectDeviceOffLine is called can reach this else branch,
369     * and routeType is WIFI_P2P, the connType is hml or p2p
370     */
371     if (sessionNode->routeType != routeType) {
372         return false;
373     }
374 
375     char myIp[IP_LEN] = {0};
376     if (sessionNode->channelType == CHANNEL_TYPE_UDP) {
377         if (ClientTransGetUdpIp(sessionNode->channelId, myIp, sizeof(myIp)) != SOFTBUS_OK) {
378             return false;
379         }
380     } else if (sessionNode->channelType == CHANNEL_TYPE_TCP_DIRECT) {
381         if (ClientTransGetTdcIp(sessionNode->channelId, myIp, sizeof(myIp)) != SOFTBUS_OK) {
382             return false;
383         }
384     } else if (sessionNode->channelType == CHANNEL_TYPE_AUTH) {
385         TRANS_LOGI(TRANS_SDK, "check channelType=%{public}d", sessionNode->channelType);
386         return true;
387     } else {
388         TRANS_LOGW(TRANS_SDK, "check channelType=%{public}d", sessionNode->channelType);
389         return false;
390     }
391 
392     bool isHml = ClientTransCheckHmlIp(myIp);
393     if (connType == TRANS_CONN_HML && isHml) {
394         return true;
395     } else if (connType == TRANS_CONN_P2P && !isHml) {
396         return true;
397     }
398 
399     return false;
400 }
401 
DestroyAllClientSession(const ClientSessionServer * server,ListNode * destroyList)402 void DestroyAllClientSession(const ClientSessionServer *server, ListNode *destroyList)
403 {
404     if (server == NULL || destroyList == NULL) {
405         TRANS_LOGE(TRANS_SDK, "invalid param.");
406         return;
407     }
408     SessionInfo *sessionNode = NULL;
409     SessionInfo *sessionNodeNext = NULL;
410     LIST_FOR_EACH_ENTRY_SAFE(sessionNode, sessionNodeNext, &(server->sessionList), SessionInfo, node) {
411         TRANS_LOGI(TRANS_SDK, "channelId=%{public}d, channelType=%{public}d, routeType=%{public}d",
412             sessionNode->channelId, sessionNode->channelType, sessionNode->routeType);
413         DestroySessionInfo *destroyNode = CreateDestroySessionNode(sessionNode, server);
414         if (destroyNode == NULL) {
415             continue;
416         }
417         if (sessionNode->channelType == CHANNEL_TYPE_UDP && sessionNode->businessType == BUSINESS_TYPE_FILE) {
418             ClientEmitFileEvent(sessionNode->channelId);
419         }
420         DestroySessionId();
421         ListDelete(&sessionNode->node);
422         ListAdd(destroyList, &(destroyNode->node));
423         SoftBusFree(sessionNode);
424     }
425 }
426 
DestroyClientSessionByNetworkId(const ClientSessionServer * server,const char * networkId,int32_t type,ListNode * destroyList)427 void DestroyClientSessionByNetworkId(const ClientSessionServer *server,
428     const char *networkId, int32_t type, ListNode *destroyList)
429 {
430     if (server == NULL || networkId == NULL || destroyList == NULL) {
431         TRANS_LOGE(TRANS_SDK, "invalid param.");
432         return;
433     }
434     SessionInfo *sessionNode = NULL;
435     SessionInfo *sessionNodeNext = NULL;
436     // connType is set only in function OnWifiDirectDeviceOffLine, others is TRANS_CONN_ALL, and routeType is WIFI_P2P
437     int32_t routeType = (int32_t)GET_ROUTE_TYPE(type);
438     int32_t connType = (int32_t)GET_CONN_TYPE(type);
439 
440     LIST_FOR_EACH_ENTRY_SAFE(sessionNode, sessionNodeNext, &(server->sessionList), SessionInfo, node) {
441         if (strcmp(sessionNode->info.peerDeviceId, networkId) != 0) {
442             continue;
443         }
444 
445         if (!ClientTransCheckNeedDel(server->sessionName, sessionNode, routeType, connType)) {
446             continue;
447         }
448 
449         TRANS_LOGI(TRANS_SDK, "channelId=%{public}d, channelType=%{public}d, routeType=%{public}d, type=%{public}d",
450             sessionNode->channelId, sessionNode->channelType, sessionNode->routeType, type);
451         DestroySessionInfo *destroyNode = CreateDestroySessionNode(sessionNode, server);
452         if (destroyNode == NULL) {
453             continue;
454         }
455         /*
456          * When the channel type is UDP and the business type is file, trigger DFILE_ON_CLEAR_POLICY_FILE_LIST event
457          * before cleaning up sessionNode.
458          */
459         if (sessionNode->channelType == CHANNEL_TYPE_UDP && sessionNode->businessType == BUSINESS_TYPE_FILE) {
460             ClientEmitFileEvent(sessionNode->channelId);
461         }
462         DestroySessionId();
463         ListDelete(&sessionNode->node);
464         ListAdd(destroyList, &(destroyNode->node));
465         SoftBusFree(sessionNode);
466     }
467 }
468 
CreateSessionServerInfoNode(const ClientSessionServer * clientSessionServer)469 SessionServerInfo *CreateSessionServerInfoNode(const ClientSessionServer *clientSessionServer)
470 {
471     if (clientSessionServer == NULL) {
472         TRANS_LOGE(TRANS_SDK, "invalid param.");
473         return NULL;
474     }
475 
476     SessionServerInfo *infoNode = (SessionServerInfo *)SoftBusCalloc(sizeof(SessionServerInfo));
477     if (infoNode == NULL) {
478         TRANS_LOGE(TRANS_SDK, "failed to malloc SessionServerInfo.");
479         return NULL;
480     }
481 
482     if (strcpy_s(infoNode->pkgName, PKG_NAME_SIZE_MAX, clientSessionServer->pkgName) != EOK) {
483         SoftBusFree(infoNode);
484         TRANS_LOGE(TRANS_SDK, "failed to strcpy pkgName.");
485         return NULL;
486     }
487 
488     if (strcpy_s(infoNode->sessionName, SESSION_NAME_SIZE_MAX, clientSessionServer->sessionName) != EOK) {
489         SoftBusFree(infoNode);
490         TRANS_LOGE(TRANS_SDK, "failed to strcpy sessionName.");
491         return NULL;
492     }
493 
494     return infoNode;
495 }
496 
GetNewSocketServer(SoftBusSecType type,const char * sessionName,const char * pkgName)497 ClientSessionServer *GetNewSocketServer(SoftBusSecType type, const char *sessionName, const char *pkgName)
498 {
499     if (sessionName == NULL || pkgName == NULL) {
500         TRANS_LOGE(TRANS_SDK, "invalid param.");
501         return NULL;
502     }
503     ClientSessionServer *server = (ClientSessionServer *)SoftBusCalloc(sizeof(ClientSessionServer));
504     if (server == NULL) {
505         return NULL;
506     }
507     server->type = type;
508     if (strcpy_s(server->pkgName, sizeof(server->pkgName), pkgName) != EOK) {
509         goto EXIT_ERR;
510     }
511     if (strcpy_s(server->sessionName, sizeof(server->sessionName), sessionName) != EOK) {
512         goto EXIT_ERR;
513     }
514     server->sessionAddingCnt++;
515     server->isSrvEncryptedRawStream = false;
516     ListInit(&server->node);
517     ListInit(&server->sessionList);
518     return server;
519 
520 EXIT_ERR:
521     if (server != NULL) {
522         SoftBusFree(server);
523     }
524     return NULL;
525 }
526 
IsDistributedDataSession(const char * sessionName)527 bool IsDistributedDataSession(const char *sessionName)
528 {
529     if (sessionName == NULL) {
530         TRANS_LOGE(TRANS_SDK, "invalid param.");
531         return false;
532     }
533     uint32_t distributedDataSessionLen = strlen(DISTRIBUTED_DATA_SESSION);
534     if (strlen(sessionName) < distributedDataSessionLen ||
535         strncmp(sessionName, DISTRIBUTED_DATA_SESSION, distributedDataSessionLen) != 0) {
536         return false;
537     }
538     return true;
539 }
540 
IsDifferentDataType(const SessionInfo * sessionInfo,int dataType,bool isEncyptedRawStream)541 bool IsDifferentDataType(const SessionInfo *sessionInfo, int dataType, bool isEncyptedRawStream)
542 {
543     if (sessionInfo == NULL) {
544         TRANS_LOGE(TRANS_SDK, "invalid param.");
545         return false;
546     }
547     if (sessionInfo->info.flag != dataType) {
548         return true;
549     }
550 
551     if (dataType != RAW_STREAM) {
552         return false;
553     }
554 
555     return sessionInfo->isEncyptedRawStream != isEncyptedRawStream;
556 }
557 
ClientInitSession(SessionInfo * session,const SessionParam * param)558 static void ClientInitSession(SessionInfo *session, const SessionParam *param)
559 {
560     session->sessionId = INVALID_SESSION_ID;
561     session->channelId = INVALID_CHANNEL_ID;
562     session->channelType = CHANNEL_TYPE_BUTT;
563     session->isServer = false;
564     session->role = SESSION_ROLE_INIT;
565     session->enableStatus = ENABLE_STATUS_INIT;
566     session->info.flag = param->attr->dataType;
567     session->info.streamType = param->attr->attr.streamAttr.streamType;
568     session->isEncrypt = true;
569     session->isAsync = false;
570     session->lifecycle.sessionState = SESSION_STATE_INIT;
571     session->lifecycle.condIsWaiting = false;
572     session->actionId = param->actionId;
573 }
574 
CreateNewSocketSession(const SessionParam * param)575 SessionInfo *CreateNewSocketSession(const SessionParam *param)
576 {
577     if (param == NULL) {
578         TRANS_LOGE(TRANS_SDK, "invalid param.");
579         return NULL;
580     }
581     SessionInfo *session = (SessionInfo *)SoftBusCalloc(sizeof(SessionInfo));
582     if (session == NULL) {
583         TRANS_LOGE(TRANS_SDK, "calloc failed");
584         return NULL;
585     }
586 
587     if (param->peerSessionName != NULL &&
588         strcpy_s(session->info.peerSessionName, SESSION_NAME_SIZE_MAX, param->peerSessionName) != EOK) {
589         char *anonySessionName = NULL;
590         Anonymize(param->peerSessionName, &anonySessionName);
591         TRANS_LOGI(TRANS_SDK, "strcpy peerName failed, peerName=%{public}s, peerNameLen=%{public}zu",
592             AnonymizeWrapper(anonySessionName), strlen(param->peerSessionName));
593         AnonymizeFree(anonySessionName);
594         SoftBusFree(session);
595         return NULL;
596     }
597 
598     if (param->peerDeviceId != NULL &&
599         strcpy_s(session->info.peerDeviceId, DEVICE_ID_SIZE_MAX, param->peerDeviceId) != EOK) {
600         char *anonyNetworkId = NULL;
601         Anonymize(param->peerDeviceId, &anonyNetworkId);
602         TRANS_LOGI(TRANS_SDK, "strcpy peerDeviceId failed, peerDeviceId=%{public}s, peerDeviceIdLen=%{public}zu",
603             AnonymizeWrapper(anonyNetworkId), strlen(param->peerDeviceId));
604         AnonymizeFree(anonyNetworkId);
605         SoftBusFree(session);
606         return NULL;
607     }
608 
609     if (strcpy_s(session->info.groupId, GROUP_ID_SIZE_MAX, param->groupId) != EOK ||
610         memcpy_s(session->linkType, sizeof(param->attr->linkType), param->attr->linkType,
611             sizeof(param->attr->linkType)) != EOK) {
612         TRANS_LOGE(TRANS_SDK, "strcpy failed");
613         SoftBusFree(session);
614         return NULL;
615     }
616 
617     if (SoftBusCondInit(&session->lifecycle.callbackCond) != SOFTBUS_OK) {
618         SoftBusFree(session);
619         TRANS_LOGE(TRANS_SDK, "callbackCond Init failed");
620         return NULL;
621     }
622 
623     ClientInitSession(session, param);
624     return session;
625 }
626 
CheckBindSocketInfo(const SessionInfo * session)627 int32_t CheckBindSocketInfo(const SessionInfo *session)
628 {
629     if (session == NULL) {
630         TRANS_LOGE(TRANS_SDK, "invalid param.");
631         return SOFTBUS_INVALID_PARAM;
632     }
633     if (!IsValidString(session->info.peerSessionName, SESSION_NAME_SIZE_MAX - 1) ||
634         !IsValidString(session->info.peerDeviceId, DEVICE_ID_SIZE_MAX - 1)) {
635         char *anonySessionName = NULL;
636         char *anonyNetworkId = NULL;
637         Anonymize(session->info.peerSessionName, &anonySessionName);
638         Anonymize(session->info.peerDeviceId, &anonyNetworkId);
639         TRANS_LOGI(TRANS_SDK, "invalid peerName=%{public}s, peerNameLen=%{public}zu, peerNetworkId=%{public}s, "
640             "peerNetworkIdLen=%{public}zu", AnonymizeWrapper(anonySessionName), strlen(session->info.peerSessionName),
641             AnonymizeWrapper(anonyNetworkId), strlen(session->info.peerDeviceId));
642         AnonymizeFree(anonyNetworkId);
643         AnonymizeFree(anonySessionName);
644         return SOFTBUS_INVALID_PARAM;
645     }
646 
647     if (session->info.flag < TYPE_MESSAGE || session->info.flag >= TYPE_BUTT) {
648         TRANS_LOGE(TRANS_SDK, "invalid dataType");
649         return SOFTBUS_INVALID_PARAM;
650     }
651 
652     return SOFTBUS_OK;
653 }
654 
FillSessionParam(SessionParam * param,SessionAttribute * tmpAttr,ClientSessionServer * serverNode,SessionInfo * sessionNode)655 void FillSessionParam(SessionParam *param, SessionAttribute *tmpAttr,
656     ClientSessionServer *serverNode, SessionInfo *sessionNode)
657 {
658     if (param == NULL || tmpAttr == NULL || serverNode == NULL || sessionNode == NULL) {
659         TRANS_LOGE(TRANS_SDK, "invalid param.");
660         return;
661     }
662     tmpAttr->fastTransData = NULL;
663     tmpAttr->fastTransDataSize = 0;
664     tmpAttr->dataType = sessionNode->info.flag;
665     tmpAttr->attr.streamAttr.streamType = sessionNode->info.streamType;
666     tmpAttr->linkTypeNum = 0;
667     param->sessionName = serverNode->sessionName;
668     param->peerSessionName = sessionNode->info.peerSessionName;
669     param->peerDeviceId = sessionNode->info.peerDeviceId;
670     param->groupId = "reserved";
671     param->attr = tmpAttr;
672     param->isQosLane = true;
673     param->actionId = sessionNode->actionId;
674     param->isLowLatency = sessionNode->isLowLatency;
675     param->flowInfo.flowSize = sessionNode->flowInfo.flowSize;
676     param->flowInfo.sessionType = sessionNode->flowInfo.sessionType;
677     param->flowInfo.flowQosType = sessionNode->flowInfo.flowQosType;
678 }
679 
ClientConvertRetVal(int32_t socket,int32_t * retOut)680 void ClientConvertRetVal(int32_t socket, int32_t *retOut)
681 {
682     if (retOut == NULL) {
683         TRANS_LOGE(TRANS_SDK, "invalid param.");
684         return;
685     }
686     SocketLifecycleData lifecycle;
687     (void)memset_s(&lifecycle, sizeof(SocketLifecycleData), 0, sizeof(SocketLifecycleData));
688     int32_t ret = GetSocketLifecycleAndSessionNameBySessionId(socket, NULL, &lifecycle);
689     if (ret != SOFTBUS_OK) {
690         TRANS_LOGE(TRANS_SDK, "get info fail, socket=%{public}d", socket);
691         return;
692     }
693 
694     if (lifecycle.bindErrCode == SOFTBUS_OK) {
695         TRANS_LOGE(TRANS_SDK, "bindErrCode is SOFTBUS_OK, socket=%{public}d", socket);
696         return;
697     }
698 
699     if (lifecycle.bindErrCode == SOFTBUS_TRANS_STOP_BIND_BY_TIMEOUT) {
700         *retOut = SOFTBUS_TRANS_REQUEST_LANE_TIMEOUT;
701         return;
702     }
703     *retOut = lifecycle.bindErrCode;
704 }
705 
ClientCleanUpIdleTimeoutSocket(const ListNode * destroyList)706 void ClientCleanUpIdleTimeoutSocket(const ListNode *destroyList)
707 {
708     if (destroyList == NULL || IsListEmpty(destroyList)) {
709         TRANS_LOGD(TRANS_SDK, "destroyList is empty.");
710         return;
711     }
712     DestroySessionInfo *destroyNode = NULL;
713     DestroySessionInfo *destroyNodeNext = NULL;
714     LIST_FOR_EACH_ENTRY_SAFE(destroyNode, destroyNodeNext, destroyList, DestroySessionInfo, node) {
715         int32_t id = destroyNode->sessionId;
716         (void)ClientDeleteRecvFileList(id);
717         (void)ClientTransCloseChannel(destroyNode->channelId, destroyNode->channelType, id);
718         TRANS_LOGI(TRANS_SDK, "session is idle, sessionId=%{public}d", id);
719         if (destroyNode->OnShutdown != NULL) {
720             destroyNode->OnShutdown(id, SHUTDOWN_REASON_TIMEOUT);
721             (void)TryDeleteEmptySessionServer(destroyNode->pkgName, destroyNode->sessionName);
722         }
723         ListDelete(&(destroyNode->node));
724         SoftBusFree(destroyNode);
725     }
726     TRANS_LOGD(TRANS_SDK, "ok");
727 }
728 
ClientCheckWaitTimeOut(const ClientSessionServer * serverNode,SessionInfo * sessionNode,int32_t waitOutSocket[],uint32_t capacity,uint32_t * num)729 void ClientCheckWaitTimeOut(const ClientSessionServer *serverNode, SessionInfo *sessionNode,
730     int32_t waitOutSocket[], uint32_t capacity, uint32_t *num)
731 {
732     if (serverNode == NULL || sessionNode == NULL || waitOutSocket == NULL || num == NULL) {
733         TRANS_LOGE(TRANS_SDK, "invalid param.");
734         return;
735     }
736     if (sessionNode->enableStatus == ENABLE_STATUS_SUCCESS && !IsRawAuthSession(serverNode->sessionName)) {
737         return;
738     }
739 
740     sessionNode->lifecycle.waitTime += TIMER_TIMEOUT;
741     if (sessionNode->lifecycle.maxWaitTime == 0 ||
742         sessionNode->lifecycle.waitTime <= sessionNode->lifecycle.maxWaitTime) {
743         TRANS_LOGD(TRANS_SDK, "no wait timeout, socket=%{public}d", sessionNode->sessionId);
744         return;
745     }
746 
747     TRANS_LOGW(TRANS_SDK, "bind time out socket=%{public}d", sessionNode->sessionId);
748     // stop check time out
749     sessionNode->lifecycle.maxWaitTime = 0;
750 
751     uint32_t tmpNum = *num;
752     if (tmpNum == UINT32_MAX || tmpNum + 1 > capacity) {
753         TRANS_LOGE(TRANS_SDK, "socket num invalid tmpNum=%{public}u, capacity=%{public}u", tmpNum, capacity);
754         return;
755     }
756     waitOutSocket[tmpNum] = sessionNode->sessionId;
757     *num = tmpNum + 1;
758 }
759 
CleanUpTimeoutAuthSession(int32_t sessionId)760 static bool CleanUpTimeoutAuthSession(int32_t sessionId)
761 {
762     SocketLifecycleData lifecycle;
763     (void)memset_s(&lifecycle, sizeof(SocketLifecycleData), 0, sizeof(SocketLifecycleData));
764     char sessionName[SESSION_NAME_SIZE_MAX] = { 0 };
765     int32_t ret = GetSocketLifecycleAndSessionNameBySessionId(sessionId, sessionName, &lifecycle);
766     if (ret != SOFTBUS_OK) {
767         TRANS_LOGE(TRANS_SDK, "Get sessionId=%{public}d name failed, ret=%{public}d", sessionId, ret);
768         return false;
769     }
770 
771     if (!IsRawAuthSession(sessionName)) {
772         return false;
773     }
774 
775     TRANS_LOGI(TRANS_SDK, "sessionId=%{public}d is idle timeout.", sessionId);
776     CloseSession(sessionId);
777     return true;
778 }
779 
ClientCleanUpWaitTimeoutSocket(int32_t waitOutSocket[],uint32_t waitOutNum)780 void ClientCleanUpWaitTimeoutSocket(int32_t waitOutSocket[], uint32_t waitOutNum)
781 {
782     if (waitOutSocket == NULL) {
783         TRANS_LOGE(TRANS_SDK, "invalid param.");
784         return;
785     }
786     bool tmpIsServer = false;
787     SessionListenerAdapter callback = { 0 };
788     for (uint32_t i = 0; i < waitOutNum; ++i) {
789         TRANS_LOGI(TRANS_SDK, "time out shutdown socket=%{public}d", waitOutSocket[i]);
790         SessionEnableStatus enableStatus = ENABLE_STATUS_INIT;
791         int32_t ret = ClientGetChannelBySessionId(waitOutSocket[i], NULL, NULL, &enableStatus);
792         if (ret != SOFTBUS_OK) {
793             TRANS_LOGI(TRANS_SDK, "socket get channel failed, socket=%{public}d", waitOutSocket[i]);
794             continue;
795         }
796         if (enableStatus == ENABLE_STATUS_SUCCESS) {
797             if (CleanUpTimeoutAuthSession(waitOutSocket[i])) {
798                 continue;
799             }
800             TRANS_LOGI(TRANS_SDK, "socket has enabled, need not shutdown, socket=%{public}d", waitOutSocket[i]);
801             continue;
802         }
803         ClientGetSessionCallbackAdapterById(waitOutSocket[i], &callback, &tmpIsServer);
804         if (callback.socketClient.OnError != NULL) {
805             (void)callback.socketClient.OnError(waitOutSocket[i], SOFTBUS_TRANS_STOP_BIND_BY_TIMEOUT);
806         }
807         ClientShutdown(waitOutSocket[i], SOFTBUS_TRANS_STOP_BIND_BY_TIMEOUT);
808     }
809 }
810 
ClientUpdateIdleTimeout(const ClientSessionServer * serverNode,SessionInfo * sessionNode,ListNode * destroyList)811 void ClientUpdateIdleTimeout(const ClientSessionServer *serverNode, SessionInfo *sessionNode, ListNode *destroyList)
812 {
813     if (serverNode == NULL || sessionNode == NULL || destroyList == NULL) {
814         TRANS_LOGE(TRANS_SDK, "invalid param.");
815         return;
816     }
817     if (sessionNode->role != SESSION_ROLE_CLIENT || sessionNode->enableStatus != ENABLE_STATUS_SUCCESS) {
818         return;
819     }
820 
821     sessionNode->timeout += TIMER_TIMEOUT;
822     if (sessionNode->maxIdleTime == 0 || sessionNode->timeout <= sessionNode->maxIdleTime) {
823         return;
824     }
825 
826     DestroySessionInfo *destroyNode = CreateDestroySessionNode(sessionNode, serverNode);
827     if (destroyNode == NULL) {
828         TRANS_LOGE(TRANS_SDK, "failed to create destory session Node, sessionId=%{public}d", sessionNode->sessionId);
829         return;
830     }
831     ListAdd(destroyList, &(destroyNode->node));
832     DestroySessionId();
833     ListDelete(&sessionNode->node);
834     SoftBusFree(sessionNode);
835 }
836 
ReCreateSessionServerToServer(ListNode * sessionServerInfoList)837 int32_t ReCreateSessionServerToServer(ListNode *sessionServerInfoList)
838 {
839     TRANS_LOGD(TRANS_SDK, "enter.");
840     if (sessionServerInfoList == NULL) {
841         TRANS_LOGE(TRANS_INIT, "session server list not init");
842         return SOFTBUS_INVALID_PARAM;
843     }
844 
845     SessionServerInfo *infoNode = NULL;
846     SessionServerInfo *infoNodeNext = NULL;
847     char *tmpName = NULL;
848     LIST_FOR_EACH_ENTRY_SAFE(infoNode, infoNodeNext, sessionServerInfoList, SessionServerInfo, node) {
849         uint64_t timestamp = SoftBusGetSysTimeMs();
850         int32_t ret = ServerIpcCreateSessionServer(infoNode->pkgName, infoNode->sessionName, timestamp);
851         Anonymize(infoNode->sessionName, &tmpName);
852         TRANS_LOGI(TRANS_SDK, "sessionName=%{public}s, pkgName=%{public}s, ret=%{public}d",
853             AnonymizeWrapper(tmpName), infoNode->pkgName, ret);
854         AnonymizeFree(tmpName);
855         ListDelete(&infoNode->node);
856         SoftBusFree(infoNode);
857     }
858 
859     TRANS_LOGI(TRANS_SDK, "ok");
860     return SOFTBUS_OK;
861 }
862 
FillDfsSocketParam(SessionParam * param,SessionAttribute * tmpAttr,ClientSessionServer * serverNode,SessionInfo * sessionNode)863 void FillDfsSocketParam(
864     SessionParam *param, SessionAttribute *tmpAttr, ClientSessionServer *serverNode, SessionInfo *sessionNode)
865 {
866     if (param == NULL || tmpAttr == NULL || serverNode == NULL || sessionNode == NULL) {
867         TRANS_LOGE(TRANS_SDK, "invalid param.");
868         return;
869     }
870     tmpAttr->fastTransData = NULL;
871     tmpAttr->fastTransDataSize = 0;
872     tmpAttr->dataType = sessionNode->info.flag;
873     tmpAttr->attr.streamAttr.streamType = sessionNode->info.streamType;
874     // 2 means has two linkType
875     tmpAttr->linkTypeNum = 2;
876     tmpAttr->linkType[0] = LINK_TYPE_WIFI_WLAN_5G;
877     tmpAttr->linkType[1] = LINK_TYPE_WIFI_WLAN_2G;
878     param->sessionName = serverNode->sessionName;
879     param->peerSessionName = sessionNode->info.peerSessionName;
880     param->peerDeviceId = sessionNode->info.peerDeviceId;
881     param->groupId = "reserved";
882     param->attr = tmpAttr;
883     param->isQosLane = false;
884     param->qosCount = 0;
885     (void)memset_s(param->qos, sizeof(param->qos), 0, sizeof(param->qos));
886     param->isAsync = false;
887 }
888 
GetQosValue(const QosTV * qos,uint32_t qosCount,QosType type,int32_t * value,int32_t defVal)889 int32_t GetQosValue(const QosTV *qos, uint32_t qosCount, QosType type, int32_t *value, int32_t defVal)
890 {
891     if (!IsValidQosInfo(qos, qosCount) || value == NULL) {
892         TRANS_LOGE(TRANS_SDK, "invalid param");
893         return SOFTBUS_INVALID_PARAM;
894     }
895 
896     if (qos == NULL || qosCount == 0) {
897         TRANS_LOGW(TRANS_SDK, "no qos info, use defVal");
898         *value = defVal;
899         return SOFTBUS_OK;
900     }
901 
902     for (uint32_t i = 0; i < qosCount; i++) {
903         if (qos[i].qos != type) {
904             continue;
905         }
906         *value = qos[i].value;
907         return SOFTBUS_OK;
908     }
909     *value = defVal;
910     return SOFTBUS_OK;
911 }
912 
ClientGrantPermission(int uid,int pid,const char * busName)913 int32_t ClientGrantPermission(int uid, int pid, const char *busName)
914 {
915     if (uid < 0 || pid < 0 || busName == NULL) {
916         TRANS_LOGW(TRANS_SDK, "invalid parameter");
917         return SOFTBUS_INVALID_PARAM;
918     }
919     char *tmpName = NULL;
920     Anonymize(busName, &tmpName);
921     TRANS_LOGI(TRANS_SDK, "sessionName=%{public}s", AnonymizeWrapper(tmpName));
922     AnonymizeFree(tmpName);
923     int32_t ret = ServerIpcGrantPermission(uid, pid, busName);
924     if (ret != SOFTBUS_OK) {
925         TRANS_LOGE(TRANS_SDK, "server grant permission failed, ret=%{public}d", ret);
926     }
927     return ret;
928 }
929 
ClientRemovePermission(const char * busName)930 int32_t ClientRemovePermission(const char *busName)
931 {
932     if (busName == NULL) {
933         TRANS_LOGW(TRANS_SDK, "invalid parameter");
934         return SOFTBUS_INVALID_PARAM;
935     }
936     char *tmpName = NULL;
937     Anonymize(busName, &tmpName);
938     TRANS_LOGI(TRANS_SDK, "sessionName=%{public}s", AnonymizeWrapper(tmpName));
939     AnonymizeFree(tmpName);
940     int32_t ret = ServerIpcRemovePermission(busName);
941     if (ret != SOFTBUS_OK) {
942         TRANS_LOGE(TRANS_SDK, "server remove permission failed, ret=%{public}d", ret);
943     }
944     return ret;
945 }
946 
ClientDeletePagingSession(int32_t sessionId)947 int32_t ClientDeletePagingSession(int32_t sessionId)
948 {
949     if (sessionId <= 0) {
950         TRANS_LOGE(TRANS_SDK, "invalid sessionId=%{public}d", sessionId);
951         return SOFTBUS_INVALID_PARAM;
952     }
953 
954     char pkgName[PKG_NAME_SIZE_MAX] = { 0 };
955     char sessionName[SESSION_NAME_SIZE_MAX] = { 0 };
956     int32_t ret = DeletePagingSession(sessionId, pkgName, sessionName);
957     if (ret != SOFTBUS_OK) {
958         TRANS_LOGE(TRANS_SDK, "failed delete session");
959         return ret;
960     }
961 
962     (void)TryDeleteEmptySessionServer(pkgName, sessionName);
963     return SOFTBUS_OK;
964 }
965 
ClientDeleteSocketSession(int32_t sessionId)966 int32_t ClientDeleteSocketSession(int32_t sessionId)
967 {
968     if (sessionId <= 0) {
969         TRANS_LOGE(TRANS_SDK, "Invalid sessionId=%{public}d", sessionId);
970         return SOFTBUS_INVALID_PARAM;
971     }
972 
973     char pkgName[PKG_NAME_SIZE_MAX] = { 0 };
974     char sessionName[SESSION_NAME_SIZE_MAX] = { 0 };
975     int32_t ret = DeleteSocketSession(sessionId, pkgName, sessionName);
976     if (ret != SOFTBUS_OK) {
977         TRANS_LOGE(TRANS_SDK, "failed delete session");
978         return ret;
979     }
980 
981     ret = TryDeleteEmptySessionServer(pkgName, sessionName);
982     if (ret != SOFTBUS_OK) {
983         TRANS_LOGE(TRANS_SDK, "delete empty session server failed, ret=%{public}d", ret);
984         return ret;
985     }
986     return SOFTBUS_OK;
987 }
988 
PrivilegeDestroyAllClientSession(const ClientSessionServer * server,ListNode * destroyList,const char * peerNetworkId)989 void PrivilegeDestroyAllClientSession(
990     const ClientSessionServer *server, ListNode *destroyList, const char *peerNetworkId)
991 {
992     if (server == NULL || destroyList == NULL || peerNetworkId == NULL) {
993         TRANS_LOGE(TRANS_SDK, "invalid param.");
994         return;
995     }
996     SessionInfo *sessionNode = NULL;
997     SessionInfo *sessionNodeNext = NULL;
998     LIST_FOR_EACH_ENTRY_SAFE(sessionNode, sessionNodeNext, &(server->sessionList), SessionInfo, node) {
999         if (strlen(peerNetworkId) != 0 && strcmp(sessionNode->info.peerDeviceId, peerNetworkId) != 0) {
1000             continue;
1001         }
1002         if (sessionNode->isServer) {
1003             continue;
1004         }
1005         TRANS_LOGI(TRANS_SDK, "channelId=%{public}d, channelType=%{public}d, routeType=%{public}d",
1006             sessionNode->channelId, sessionNode->channelType, sessionNode->routeType);
1007         DestroySessionInfo *destroyNode = CreateDestroySessionNode(sessionNode, server);
1008         if (destroyNode == NULL) {
1009             continue;
1010         }
1011         if (sessionNode->channelType == CHANNEL_TYPE_UDP && sessionNode->businessType == BUSINESS_TYPE_FILE) {
1012             ClientEmitFileEvent(sessionNode->channelId);
1013         }
1014         DestroySessionId();
1015         ListDelete(&sessionNode->node);
1016         ListAdd(destroyList, &(destroyNode->node));
1017         SoftBusFree(sessionNode);
1018     }
1019 }
1020 
ClientRegisterRelationChecker(IFeatureAbilityRelationChecker * relationChecker)1021 int32_t ClientRegisterRelationChecker(IFeatureAbilityRelationChecker *relationChecker)
1022 {
1023     if (relationChecker == NULL) {
1024         TRANS_LOGE(TRANS_SDK, "invalid parameter.");
1025         return SOFTBUS_INVALID_PARAM;
1026     }
1027     if (g_relationChecker == NULL) {
1028         g_relationChecker = (IFeatureAbilityRelationChecker *)SoftBusCalloc(sizeof(IFeatureAbilityRelationChecker));
1029         if (g_relationChecker == NULL) {
1030             TRANS_LOGE(TRANS_SDK, "malloc failed.");
1031             return SOFTBUS_MALLOC_ERR;
1032         }
1033     } else {
1034         TRANS_LOGI(TRANS_SDK, "overwrite relation checker.");
1035     }
1036     int32_t ret = memcpy_s(g_relationChecker, sizeof(IFeatureAbilityRelationChecker),
1037         relationChecker, sizeof(IFeatureAbilityRelationChecker));
1038     if (ret != EOK) {
1039         TRANS_LOGE(TRANS_SDK, "memcpy_s relationChecker failed, ret=%{public}d", ret);
1040         return SOFTBUS_MEM_ERR;
1041     }
1042     TRANS_LOGI(TRANS_SDK, "register relation checker success.");
1043     return SOFTBUS_OK;
1044 }
1045 
PrintCollabInfo(const CollabInfo * info,char * role)1046 static void PrintCollabInfo(const CollabInfo *info, char *role)
1047 {
1048     char *tmpDeviceId = NULL;
1049     char *tmpAccountId = NULL;
1050     Anonymize(info->deviceId, &tmpDeviceId);
1051     Anonymize(info->accountId, &tmpAccountId);
1052     TRANS_LOGI(TRANS_SDK, "%{public}s deviceId=%{public}s", role, AnonymizeWrapper(tmpDeviceId));
1053     AnonymizeFree(tmpDeviceId);
1054     TRANS_LOGI(TRANS_SDK, "%{public}s userId=%{public}d", role, info->userId);
1055     TRANS_LOGI(TRANS_SDK, "%{public}s pid=%{public}d", role, info->pid);
1056     TRANS_LOGI(TRANS_SDK, "%{public}s accountId=%{public}s", role, AnonymizeWrapper(tmpAccountId));
1057     TRANS_LOGI(TRANS_SDK, "%{public}s tokenId=%{public}" PRIu64, role, info->tokenId);
1058 }
1059 
ClientTransCheckCollabRelation(const CollabInfo * sourceInfo,const CollabInfo * sinkInfo,int32_t channelId,int32_t channelType)1060 int32_t ClientTransCheckCollabRelation(
1061     const CollabInfo *sourceInfo, const CollabInfo *sinkInfo, int32_t channelId, int32_t channelType)
1062 {
1063     if (sourceInfo == NULL || sinkInfo == NULL) {
1064         TRANS_LOGE(TRANS_SDK, "invalid parameter.");
1065         return SOFTBUS_INVALID_PARAM;
1066     }
1067     if (g_relationChecker == NULL || g_relationChecker->CheckCollabRelation == NULL) {
1068         TRANS_LOGE(TRANS_SDK, "extern checker is null or not registered.");
1069         return SOFTBUS_NO_INIT;
1070     }
1071     int32_t ret = g_relationChecker->CheckCollabRelation(sourceInfo, sinkInfo);
1072     if (ret != SOFTBUS_OK) {
1073         TRANS_LOGE(TRANS_SDK,
1074             "channelId=%{public}d check collaboration relation fail, ret=%{public}d", channelId, ret);
1075         PrintCollabInfo(sourceInfo, (char *)"source");
1076         PrintCollabInfo(sinkInfo, (char *)"sink");
1077         return SOFTBUS_TRANS_CHECK_RELATION_FAIL;
1078     }
1079     TRANS_LOGI(TRANS_SDK, "check collaboration relation success.");
1080     return SOFTBUS_OK;
1081 }
1082 
DestroyRelationChecker(void)1083 void DestroyRelationChecker(void)
1084 {
1085     if (g_relationChecker == NULL) {
1086         return;
1087     }
1088     SoftBusFree(g_relationChecker);
1089     g_relationChecker= NULL;
1090 }
1091 
DataSeqInfoListAddItem(uint32_t dataSeq,int32_t channelId,int32_t socketId,int32_t channelType)1092 int32_t DataSeqInfoListAddItem(uint32_t dataSeq, int32_t channelId, int32_t socketId, int32_t channelType)
1093 {
1094     int32_t ret = LockClientDataSeqInfoList();
1095     if (ret != SOFTBUS_OK) {
1096         TRANS_LOGE(TRANS_SDK, "lock failed");
1097         return ret;
1098     }
1099     DataSeqInfo *exitItem = NULL;
1100     LIST_FOR_EACH_ENTRY(exitItem, &(g_clientDataSeqInfoList->list), DataSeqInfo, node) {
1101         if (exitItem->channelId == channelId && exitItem->seq == (int32_t)dataSeq) {
1102             TRANS_LOGI(TRANS_SDK, "DataSeqInfo add already exist, channelId=%{public}d", channelId);
1103             UnlockClientDataSeqInfoList();
1104             return SOFTBUS_OK;
1105         }
1106     }
1107     int32_t businessType;
1108     (void)ClientGetChannelBusinessTypeByChannelId(channelId, &businessType);
1109     DataSeqInfo *item = (DataSeqInfo *)SoftBusCalloc(sizeof(DataSeqInfo));
1110     TRANS_CHECK_AND_RETURN_RET_LOGE(item != NULL, SOFTBUS_MALLOC_ERR, TRANS_CTRL, "calloc failed");
1111     item->channelId = channelId;
1112     item->seq = (int32_t)dataSeq;
1113     item->socketId = socketId;
1114     item->channelType = channelType;
1115     item->isMessage = (businessType == BUSINESS_TYPE_D2D_MESSAGE) ? true :false;
1116     ListInit(&item->node);
1117     ListAdd(&(g_clientDataSeqInfoList->list), &(item->node));
1118     TRANS_LOGI(TRANS_SDK, "add DataSeqInfo success, channelId=%{public}d, dataSeq=%{public}u", channelId, dataSeq);
1119     UnlockClientDataSeqInfoList();
1120     return SOFTBUS_OK;
1121 }
1122 
DeleteDataSeqInfoList(uint32_t dataSeq,int32_t channelId)1123 int32_t DeleteDataSeqInfoList(uint32_t dataSeq, int32_t channelId)
1124 {
1125     int32_t ret = LockClientDataSeqInfoList();
1126     if (ret != SOFTBUS_OK) {
1127         TRANS_LOGE(TRANS_SDK, "lock failed");
1128         return ret;
1129     }
1130     DataSeqInfo *item = NULL;
1131     DataSeqInfo *nextItem = NULL;
1132     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &(g_clientDataSeqInfoList->list), DataSeqInfo, node) {
1133         if (item->channelId == channelId && item->seq == (int32_t)dataSeq) {
1134             ListDelete(&(item->node));
1135             SoftBusFree(item);
1136             TRANS_LOGD(TRANS_SDK, "delete DataSeqInfo success, channelId=%{public}d, dataSeq=%{public}u",
1137                 channelId, dataSeq);
1138             UnlockClientDataSeqInfoList();
1139             return SOFTBUS_OK;
1140         }
1141     }
1142     TRANS_LOGD(TRANS_SDK, "dataSeqInfoList not found, channelId=%{public}d, dataSeq=%{public}u", channelId, dataSeq);
1143     UnlockClientDataSeqInfoList();
1144     return SOFTBUS_TRANS_DATA_SEQ_INFO_NOT_FOUND;
1145 }
1146 
TransOnBindSentProc(ListNode * timeoutItemList)1147 static void TransOnBindSentProc(ListNode *timeoutItemList)
1148 {
1149     if (timeoutItemList == NULL) {
1150         TRANS_LOGE(TRANS_SDK, "invalid param.");
1151         return;
1152     }
1153     DataSeqInfo *item = NULL;
1154     DataSeqInfo *nextItem = NULL;
1155     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, timeoutItemList, DataSeqInfo, node) {
1156         SessionListenerAdapter sessionCallback;
1157         (void)memset_s(&sessionCallback, sizeof(SessionListenerAdapter), 0, sizeof(SessionListenerAdapter));
1158         bool isServer = false;
1159         int32_t ret = ClientGetSessionCallbackAdapterById(item->socketId, &sessionCallback, &isServer);
1160         if (ret != SOFTBUS_OK) {
1161             TRANS_LOGE(TRANS_SDK, "get session callback failed, socket=%{public}d", item->socketId);
1162             ListDelete(&(item->node));
1163             SoftBusFree(item);
1164             continue;
1165         }
1166         if (item->isMessage) {
1167             if (sessionCallback.socketClient.OnMessageSent == NULL) {
1168                 TRANS_LOGE(TRANS_SDK, "OnMessageSent not implement");
1169                 continue;
1170             }
1171             sessionCallback.socketClient.OnMessageSent(item->socketId, item->seq, SOFTBUS_TRANS_ASYNC_SEND_TIMEOUT);
1172         } else {
1173             if (sessionCallback.socketClient.OnBytesSent == NULL) {
1174                 TRANS_LOGE(TRANS_SDK, "OnBytesSent not implement");
1175                 continue;
1176             }
1177             sessionCallback.socketClient.OnBytesSent(item->socketId, item->seq, SOFTBUS_TRANS_ASYNC_SEND_TIMEOUT);
1178         }
1179         TRANS_LOGI(TRANS_SDK, "async sendbytes recv ack timeout, socket=%{public}d, dataSeq=%{public}u",
1180             item->socketId, item->seq);
1181         ListDelete(&(item->node));
1182         SoftBusFree(item);
1183     }
1184 }
1185 
TransAsyncSendBytesTimeoutProc(void)1186 void TransAsyncSendBytesTimeoutProc(void)
1187 {
1188     if (LockClientDataSeqInfoList() != SOFTBUS_OK) {
1189         TRANS_LOGE(TRANS_SDK, "lock failed");
1190         return;
1191     }
1192     ListNode timeoutItemList;
1193     ListInit(&timeoutItemList);
1194     DataSeqInfo *item = NULL;
1195     DataSeqInfo *nextItem = NULL;
1196     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &(g_clientDataSeqInfoList->list), DataSeqInfo, node) {
1197         item->timeout++;
1198         if (item->timeout > SENDBYTES_TIMEOUT_S) {
1199             DataSeqInfo *timeoutItem = (DataSeqInfo *)SoftBusCalloc(sizeof(DataSeqInfo));
1200             if (timeoutItem == NULL) {
1201                 TRANS_LOGE(TRANS_SDK, "timeoutItem calloc fail");
1202                 continue;
1203             }
1204             timeoutItem->socketId = item->socketId;
1205             timeoutItem->seq = item->seq;
1206             timeoutItem->isMessage = item->isMessage;
1207             ListDelete(&(item->node));
1208             ListAdd(&timeoutItemList, &(timeoutItem->node));
1209             SoftBusFree(item);
1210         }
1211     }
1212     UnlockClientDataSeqInfoList();
1213     (void)TransOnBindSentProc(&timeoutItemList);
1214 }