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