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 }