/* * Copyright (c) 2021-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "client_trans_session_service.h" #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include <unistd.h> #include "anonymizer.h" #include "client_qos_manager.h" #include "client_trans_channel_manager.h" #include "client_trans_file_listener.h" #include "client_trans_session_adapter.h" #include "client_trans_session_manager.h" #include "client_trans_socket_manager.h" #include "dfs_session.h" #include "inner_session.h" #include "securec.h" #include "session_ipc_adapter.h" #include "softbus_adapter_mem.h" #include "softbus_client_frame_manager.h" #include "softbus_def.h" #include "softbus_errcode.h" #include "softbus_feature_config.h" #include "softbus_json_utils.h" #include "softbus_trans_def.h" #include "softbus_utils.h" #include "trans_log.h" #include "trans_server_proxy.h" typedef int (*SessionOptionRead)(int32_t channelId, int32_t type, void* value, uint32_t valueSize); typedef int (*SessionOptionWrite)(int32_t channelId, int32_t type, void* value, uint32_t valueSize); typedef struct { bool canRead; SessionOptionRead readFunc; } SessionOptionItem; typedef struct { int32_t channelType; int32_t businessType; ConfigType configType; } ConfigTypeMap; static bool IsValidSessionId(int sessionId) { if (sessionId <= 0) { TRANS_LOGE(TRANS_SDK, "invalid sessionId=%{public}d", sessionId); return false; } return true; } static bool IsValidListener(const ISessionListener *listener) { if ((listener != NULL) && (listener->OnSessionOpened != NULL) && (listener->OnSessionClosed != NULL)) { return true; } TRANS_LOGE(TRANS_SDK, "invalid ISessionListener"); return false; } static int32_t OpenSessionWithExistSession(int32_t sessionId, bool isEnabled) { if (!isEnabled) { int32_t errCode = SOFTBUS_TRANS_SESSION_OPENING; TRANS_LOGI(TRANS_SDK, "the channel is opening, errCode=%{public}d", errCode); return sessionId; } ISessionListener listener = { 0 }; int32_t ret = ClientGetSessionCallbackById(sessionId, &listener); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get session listener failed, ret=%{public}d", ret); CloseSession(sessionId); return SOFTBUS_TRANS_INVALID_SESSION_ID; } ret = listener.OnSessionOpened(sessionId, SOFTBUS_OK); if (ret != 0) { TRANS_LOGE(TRANS_SDK, "session callback OnSessionOpened failed, ret=%{public}d", ret); CloseSession(sessionId); return SOFTBUS_TRANS_INVALID_SESSION_ID; } return sessionId; } int CreateSessionServer(const char *pkgName, const char *sessionName, const ISessionListener *listener) { if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX - 1) || !IsValidString(sessionName, SESSION_NAME_SIZE_MAX - 1) || !IsValidListener(listener)) { TRANS_LOGW(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } char *tmpName = NULL; Anonymize(sessionName, &tmpName); TRANS_LOGI(TRANS_SDK, "pkgName=%{public}s, sessionName=%{public}s", pkgName, tmpName); AnonymizeFree(tmpName); if (InitSoftBus(pkgName) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "init softbus err"); return SOFTBUS_TRANS_SESSION_ADDPKG_FAILED; } if (CheckPackageName(pkgName) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "invalid pkg name"); return SOFTBUS_INVALID_PKGNAME; } int ret = ClientAddSessionServer(SEC_TYPE_CIPHERTEXT, pkgName, sessionName, listener); if (ret == SOFTBUS_SERVER_NAME_REPEATED) { TRANS_LOGI(TRANS_SDK, "SessionServer is already created in client"); } else if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "add session server err, ret=%{public}d.", ret); return ret; } ret = ServerIpcCreateSessionServer(pkgName, sessionName); if (ret == SOFTBUS_SERVER_NAME_REPEATED) { TRANS_LOGW(TRANS_SDK, "ok, SessionServer is already created in server"); return SOFTBUS_OK; } else if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "createSessionServer failed, ret=%{public}d", ret); (void)ClientDeleteSessionServer(SEC_TYPE_CIPHERTEXT, sessionName); return ret; } TRANS_LOGI(TRANS_SDK, "ok"); return ret; } int RemoveSessionServer(const char *pkgName, const char *sessionName) { if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX - 1) || !IsValidString(sessionName, SESSION_NAME_SIZE_MAX - 1)) { TRANS_LOGW(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } char *tmpName = NULL; Anonymize(sessionName, &tmpName); TRANS_LOGI(TRANS_SDK, "pkgName=%{public}s, sessionName=%{public}s", pkgName, tmpName); int32_t ret = ServerIpcRemoveSessionServer(pkgName, sessionName); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "remove in server failed, ret=%{public}d.", ret); AnonymizeFree(tmpName); return ret; } ret = ClientDeleteSessionServer(SEC_TYPE_CIPHERTEXT, sessionName); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "delete session server failed, sessionName=%{public}s, ret=%{public}d.", tmpName, ret); DeleteFileListener(sessionName); AnonymizeFree(tmpName); return ret; } DeleteFileListener(sessionName); AnonymizeFree(tmpName); TRANS_LOGI(TRANS_SDK, "ok"); return ret; } static int32_t CheckParamIsValid(const char *mySessionName, const char *peerSessionName, const char *peerNetworkId, const char *groupId, const SessionAttribute *attr) { if (!IsValidString(mySessionName, SESSION_NAME_SIZE_MAX - 1)) { char *tmpMyName = NULL; Anonymize(mySessionName, &tmpMyName); TRANS_LOGE(TRANS_SDK, "invalid mySessionName. tmpMyName=%{public}s", tmpMyName); AnonymizeFree(tmpMyName); return SOFTBUS_TRANS_INVALID_SESSION_NAME; } if (!IsValidString(peerSessionName, SESSION_NAME_SIZE_MAX - 1)) { char *tmpPeerName = NULL; Anonymize(peerSessionName, &tmpPeerName); TRANS_LOGE(TRANS_SDK, "invalid peerSessionName. tmpPeerName=%{public}s", tmpPeerName); AnonymizeFree(tmpPeerName); return SOFTBUS_TRANS_INVALID_SESSION_NAME; } if (!IsValidString(peerNetworkId, DEVICE_ID_SIZE_MAX - 1)) { char *tmpPeerNetworkId = NULL; Anonymize(peerNetworkId, &tmpPeerNetworkId); TRANS_LOGE(TRANS_SDK, "invalid peerNetworkId. tmpPeerNetworkId=%{public}s", tmpPeerNetworkId); AnonymizeFree(tmpPeerNetworkId); return SOFTBUS_INVALID_PARAM; } if (attr == NULL) { TRANS_LOGE(TRANS_SDK, "attr is NULL"); return SOFTBUS_INVALID_PARAM; } if (groupId == NULL) { TRANS_LOGE(TRANS_SDK, "groupId is NULL"); return SOFTBUS_INVALID_PARAM; } if (strlen(groupId) >= GROUP_ID_SIZE_MAX) { TRANS_LOGE(TRANS_SDK, "groupId length is invalid"); return SOFTBUS_INVALID_PARAM; } return SOFTBUS_OK; } static void PrintSessionName(const char *mySessionName, const char *peerSessionName) { char *tmpMyName = NULL; char *tmpPeerName = NULL; Anonymize(mySessionName, &tmpMyName); Anonymize(peerSessionName, &tmpPeerName); TRANS_LOGI(TRANS_SDK, "OpenSession: mySessionName=%{public}s, peerSessionName=%{public}s", tmpMyName, tmpPeerName); AnonymizeFree(tmpMyName); AnonymizeFree(tmpPeerName); } static SessionAttribute *BuildParamSessionAttribute(const SessionAttribute *attr) { SessionAttribute *tmpAttr = (SessionAttribute *)SoftBusCalloc(sizeof(SessionAttribute)); if (tmpAttr == NULL) { TRANS_LOGE(TRANS_SDK, "SoftBusCalloc SessionAttribute failed"); return NULL; } if (memcpy_s(tmpAttr, sizeof(SessionAttribute), attr, sizeof(SessionAttribute)) != EOK) { TRANS_LOGE(TRANS_SDK, "memcpy_s SessionAttribute failed"); SoftBusFree(tmpAttr); return NULL; } tmpAttr->fastTransData = NULL; tmpAttr->fastTransDataSize = 0; return tmpAttr; } static void InitSessionParam(const char *mySessionName, const char *peerSessionName, const char *peerNetworkId, const char *groupId, SessionParam *param) { param->sessionName = mySessionName; param->peerSessionName = peerSessionName; param->peerDeviceId = peerNetworkId; param->groupId = groupId; param->isQosLane = false; param->qosCount = 0; param->isAsync = false; param->actionId = INVALID_ACTION_ID; } int OpenSession(const char *mySessionName, const char *peerSessionName, const char *peerNetworkId, const char *groupId, const SessionAttribute *attr) { int32_t ret = CheckParamIsValid(mySessionName, peerSessionName, peerNetworkId, groupId, attr); TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "invalid session name."); PrintSessionName(mySessionName, peerSessionName); SessionAttribute *tmpAttr = BuildParamSessionAttribute(attr); TRANS_CHECK_AND_RETURN_RET_LOGE(tmpAttr != NULL, SOFTBUS_MEM_ERR, TRANS_SDK, "Build SessionAttribute failed."); SessionParam param = { 0 }; InitSessionParam(mySessionName, peerSessionName, peerNetworkId, groupId, ¶m); param.attr = tmpAttr; (void)memset_s(param.qos, sizeof(param.qos), 0, sizeof(param.qos)); int32_t sessionId = INVALID_SESSION_ID; SessionEnableStatus isEnabled = ENABLE_STATUS_INIT; ret = ClientAddSession(¶m, &sessionId, &isEnabled); if (ret != SOFTBUS_OK) { SoftBusFree(tmpAttr); if (ret == SOFTBUS_TRANS_SESSION_REPEATED) { TRANS_LOGI(TRANS_SDK, "session already opened"); return OpenSessionWithExistSession(sessionId, isEnabled); } TRANS_LOGE(TRANS_SDK, "add session err: ret=%{public}d", ret); return ret; } param.sessionId = sessionId; TransInfo transInfo = { 0 }; ret = ServerIpcOpenSession(¶m, &transInfo); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "open session ipc err: ret=%{public}d", ret); SoftBusFree(tmpAttr); (void)ClientDeleteSession(sessionId); return ret; } ret = ClientSetChannelBySessionId(sessionId, &transInfo); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "set channel by sessionId failed, ret=%{public}d", ret); SoftBusFree(tmpAttr); (void)ClientDeleteSession(sessionId); return SOFTBUS_TRANS_SESSION_SET_CHANNEL_FAILED; } TRANS_LOGI(TRANS_SDK, "ok: sessionId=%{public}d, channelId=%{public}d, channelType=%{public}d", sessionId, transInfo.channelId, transInfo.channelType); SoftBusFree(tmpAttr); return sessionId; } static int32_t ConvertAddrStr(const char *addrStr, ConnectionAddr *addrInfo) { TRANS_CHECK_AND_RETURN_RET_LOGE( (addrStr != NULL && addrInfo != NULL), SOFTBUS_INVALID_PARAM, TRANS_SDK, "invalid param"); cJSON *obj = cJSON_Parse(addrStr); TRANS_CHECK_AND_RETURN_RET_LOGE(obj != NULL, SOFTBUS_PARSE_JSON_ERR, TRANS_SDK, "addrStr parse failed."); int32_t port; if (GetJsonObjectStringItem(obj, "ETH_IP", addrInfo->info.ip.ip, IP_STR_MAX_LEN) && GetJsonObjectNumberItem(obj, "ETH_PORT", &port)) { addrInfo->info.ip.port = (uint16_t)port; if (IsValidString(addrInfo->info.ip.ip, IP_STR_MAX_LEN) && addrInfo->info.ip.port > 0) { cJSON_Delete(obj); addrInfo->type = CONNECTION_ADDR_ETH; return SOFTBUS_OK; } } if (GetJsonObjectStringItem(obj, "WIFI_IP", addrInfo->info.ip.ip, IP_STR_MAX_LEN) && GetJsonObjectNumberItem(obj, "WIFI_PORT", &port)) { addrInfo->info.ip.port = (uint16_t)port; if (IsValidString(addrInfo->info.ip.ip, IP_STR_MAX_LEN) && addrInfo->info.ip.port > 0) { cJSON_Delete(obj); addrInfo->type = CONNECTION_ADDR_WLAN; return SOFTBUS_OK; } } if (GetJsonObjectStringItem(obj, "BR_MAC", addrInfo->info.br.brMac, BT_MAC_LEN)) { cJSON_Delete(obj); addrInfo->type = CONNECTION_ADDR_BR; return SOFTBUS_OK; } if (GetJsonObjectStringItem(obj, "BLE_MAC", addrInfo->info.ble.bleMac, BT_MAC_LEN)) { char udidHash[UDID_HASH_LEN] = {0}; if (GetJsonObjectStringItem(obj, "deviceId", udidHash, UDID_HASH_LEN)) { char *tmpUdidHash = NULL; Anonymize(udidHash, &tmpUdidHash); int ret = ConvertHexStringToBytes( (unsigned char *)addrInfo->info.ble.udidHash, UDID_HASH_LEN, udidHash, strlen(udidHash)); TRANS_LOGI(TRANS_SDK, "string to bytes ret=%{public}d, udidHash=%{public}s", ret, AnonymizeWrapper(tmpUdidHash)); AnonymizeFree(tmpUdidHash); } cJSON_Delete(obj); addrInfo->type = CONNECTION_ADDR_BLE; return SOFTBUS_OK; } cJSON_Delete(obj); TRANS_LOGE(TRANS_SDK, "addr convert fail"); return SOFTBUS_PARSE_JSON_ERR; } static int IsValidAddrInfoArr(const ConnectionAddr *addrInfo, int num) { int32_t addrIndex = -1; if (addrInfo == NULL || num <= 0) { return addrIndex; } int32_t wifiIndex = -1; int32_t brIndex = -1; int32_t bleIndex = -1; for (int32_t index = 0; index < num; index++) { if ((addrInfo[index].type == CONNECTION_ADDR_ETH || addrInfo[index].type == CONNECTION_ADDR_WLAN) && wifiIndex < 0) { wifiIndex = index; } if (addrInfo[index].type == CONNECTION_ADDR_BR && brIndex < 0) { brIndex = index; } if (addrInfo[index].type == CONNECTION_ADDR_BLE && bleIndex < 0) { bleIndex = index; } } addrIndex = (wifiIndex >= 0) ? wifiIndex : addrIndex; addrIndex = (addrIndex < 0) ? brIndex : addrIndex; addrIndex = (addrIndex < 0) ? bleIndex : addrIndex; return addrIndex; } int OpenAuthSession(const char *sessionName, const ConnectionAddr *addrInfo, int num, const char *mixAddr) { if (!IsValidString(sessionName, SESSION_NAME_SIZE_MAX - 1)) { TRANS_LOGW(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } TransInfo transInfo; int32_t addrIndex = IsValidAddrInfoArr(addrInfo, num); ConnectionAddr *addr = NULL; ConnectionAddr mix; if (memset_s(&mix, sizeof(ConnectionAddr), 0x0, sizeof(ConnectionAddr)) != EOK) { TRANS_LOGE(TRANS_SDK, "memset_s info fail"); return SOFTBUS_MEM_ERR; } if (addrIndex < 0) { if (ConvertAddrStr(mixAddr, &mix) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "invalid addrInfo param"); return SOFTBUS_INVALID_PARAM; } addr = &mix; } else { addr = (ConnectionAddr *)&addrInfo[addrIndex]; } char *tmpName = NULL; Anonymize(sessionName, &tmpName); TRANS_LOGI(TRANS_SDK, "sessionName=%{public}s", tmpName); AnonymizeFree(tmpName); int32_t sessionId; int32_t ret = ClientAddAuthSession(sessionName, &sessionId); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "add non encrypt session err: ret=%{public}d", ret); return ret; } transInfo.channelId = ServerIpcOpenAuthSession(sessionName, addr); if (addr->type == CONNECTION_ADDR_BR || addr->type == CONNECTION_ADDR_BLE) { transInfo.channelType = CHANNEL_TYPE_PROXY; } else { transInfo.channelType = CHANNEL_TYPE_AUTH; } ret = ClientSetChannelBySessionId(sessionId, &transInfo); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "set channel by sessionId failed, ret=%{public}d", ret); (void)ClientDeleteSession(sessionId); return SOFTBUS_TRANS_SESSION_SET_CHANNEL_FAILED; } TRANS_LOGI(TRANS_SDK, "ok: sessionId=%{public}d, channelId=%{public}d, channelType=%{public}d", sessionId, transInfo.channelId, transInfo.channelType); return sessionId; } void NotifyAuthSuccess(int sessionId) { int32_t channelId = -1; int32_t channelType = -1; TRANS_LOGI(TRANS_SDK, "sessionId=%{public}d", sessionId); int32_t ret = ClientGetChannelBySessionId(sessionId, &channelId, &channelType, NULL); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get channel err, sessionId=%{public}d, ret=%{public}d", sessionId, ret); return; } int32_t isServer = 0; ret = ClientGetSessionIntegerDataById(sessionId, &isServer, KEY_IS_SERVER); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get isServer failed, ret=%{public}d", ret); return; } if (isServer == 1) { TRANS_LOGE(TRANS_SDK, "device is service side, no notification"); return; } TRANS_LOGI(TRANS_SDK, "client side, notify auth success channelId=%{public}d, channelType=%{public}d", channelId, channelType); ret = ServerIpcNotifyAuthSuccess(channelId, channelType); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "ServerIpcNotifyAuthSuccess err channelId=%{public}d, ret=%{public}d", channelId, ret); return; } } static int32_t CheckSessionIsOpened(int32_t sessionId, bool isCancelCheck) { #define SESSION_STATUS_CHECK_MAX_NUM 100 #define SESSION_STATUS_CANCEL_CHECK_MAX_NUM 5 #define SESSION_CHECK_PERIOD 200000 int32_t checkMaxNum = isCancelCheck ? SESSION_STATUS_CANCEL_CHECK_MAX_NUM : SESSION_STATUS_CHECK_MAX_NUM; int32_t i = 0; SessionEnableStatus enableStatus = ENABLE_STATUS_INIT; while (i < checkMaxNum) { if (ClientGetChannelBySessionId(sessionId, NULL, NULL, &enableStatus) != SOFTBUS_OK) { return SOFTBUS_TRANS_SESSION_GET_CHANNEL_FAILED; } if (enableStatus == ENABLE_STATUS_SUCCESS) { TRANS_LOGD(TRANS_SDK, "session is enable"); return SOFTBUS_OK; } if (enableStatus == ENABLE_STATUS_FAILED) { TRANS_LOGE(TRANS_SDK, "socket is failed"); return SOFTBUS_TRANS_SESSION_NO_ENABLE; } usleep(SESSION_CHECK_PERIOD); i++; } TRANS_LOGE(TRANS_SDK, "session open timeout"); return SOFTBUS_TIMOUT; } int OpenSessionSync(const char *mySessionName, const char *peerSessionName, const char *peerNetworkId, const char *groupId, const SessionAttribute *attr) { int ret = CheckParamIsValid(mySessionName, peerSessionName, peerNetworkId, groupId, attr); TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "invalid session name."); PrintSessionName(mySessionName, peerSessionName); SessionParam param = { .sessionName = mySessionName, .peerSessionName = peerSessionName, .peerDeviceId = peerNetworkId, .groupId = groupId, .attr = attr, .isQosLane = false, .qosCount = 0, }; (void)memset_s(param.qos, sizeof(param.qos), 0, sizeof(param.qos)); int32_t sessionId = INVALID_SESSION_ID; SessionEnableStatus isEnabled = ENABLE_STATUS_INIT; ret = ClientAddSession(¶m, &sessionId, &isEnabled); if (ret != SOFTBUS_OK) { if (ret == SOFTBUS_TRANS_SESSION_REPEATED) { TRANS_LOGI(TRANS_SDK, "session already opened"); CheckSessionIsOpened(sessionId, false); return OpenSessionWithExistSession(sessionId, isEnabled); } TRANS_LOGE(TRANS_SDK, "add session err: ret=%{public}d", ret); return ret; } param.isAsync = false; param.sessionId = sessionId; TransInfo transInfo = {0}; ret = ServerIpcOpenSession(¶m, &transInfo); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "open session ipc err: ret=%{public}d", ret); (void)ClientDeleteSession(sessionId); return ret; } ret = ClientSetChannelBySessionId(sessionId, &transInfo); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "set channel by sessionId=%{public}d, ret=%{public}d", sessionId, ret); (void)ClientDeleteSession(sessionId); return SOFTBUS_TRANS_SESSION_SET_CHANNEL_FAILED; } ret = CheckSessionIsOpened(sessionId, false); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "CheckSessionIsOpened err: ret=%{public}d", ret); (void)ClientDeleteSession(sessionId); return SOFTBUS_TRANS_SESSION_NO_ENABLE; } TRANS_LOGI(TRANS_SDK, "ok: sessionId=%{public}d, channelId=%{public}d", sessionId, transInfo.channelId); return sessionId; } void CloseSession(int sessionId) { TRANS_LOGI(TRANS_SDK, "sessionId=%{public}d", sessionId); int32_t channelId = INVALID_CHANNEL_ID; int32_t type = CHANNEL_TYPE_BUTT; int32_t ret; if (!IsValidSessionId(sessionId)) { TRANS_LOGW(TRANS_SDK, "invalid param"); return; } ret = ClientGetChannelBySessionId(sessionId, &channelId, &type, NULL); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get channel by sessionId=%{public}d, ret=%{public}d", sessionId, ret); return; } AddSessionStateClosing(); ret = ClientTransCloseChannel(channelId, type); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "close channel err: ret=%{public}d, channelId=%{public}d, channelType=%{public}d", ret, channelId, type); } ret = ClientDeleteSession(sessionId); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "delete session err: ret=%{public}d", ret); return; } TRANS_LOGD(TRANS_SDK, "ok"); } int GetMySessionName(int sessionId, char *sessionName, unsigned int len) { if (!IsValidSessionId(sessionId) || (sessionName == NULL) || (len > SESSION_NAME_SIZE_MAX)) { TRANS_LOGE(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } TRANS_LOGI(TRANS_SDK, "get client sessionName by sessionId=%{public}d", sessionId); return ClientGetSessionDataById(sessionId, sessionName, len, KEY_SESSION_NAME); } int GetPeerSessionName(int sessionId, char *sessionName, unsigned int len) { if (!IsValidSessionId(sessionId) || (sessionName == NULL) || (len > SESSION_NAME_SIZE_MAX)) { TRANS_LOGE(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } TRANS_LOGI(TRANS_SDK, "get server sessionName by sessionId=%{public}d", sessionId); return ClientGetSessionDataById(sessionId, sessionName, len, KEY_PEER_SESSION_NAME); } int GetPeerDeviceId(int sessionId, char *networkId, unsigned int len) { if (!IsValidSessionId(sessionId) || (networkId == NULL) || (len > SESSION_NAME_SIZE_MAX)) { TRANS_LOGE(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } TRANS_LOGI(TRANS_SDK, "get server deviceId by sessionId=%{public}d", sessionId); return ClientGetSessionDataById(sessionId, networkId, len, KEY_PEER_DEVICE_ID); } int GetSessionSide(int sessionId) { TRANS_LOGI(TRANS_SDK, "get session side by sessionId=%{public}d", sessionId); return ClientGetSessionSide(sessionId); } static bool IsValidFileReceivePath(const char *rootDir) { if (!IsValidString(rootDir, FILE_RECV_ROOT_DIR_SIZE_MAX)) { TRANS_LOGE(TRANS_SDK, "recvPath invalid. recvPath=%{private}s", rootDir); return false; } char *absPath = realpath(rootDir, NULL); if (absPath == NULL) { TRANS_LOGE(TRANS_SDK, "recvPath not exist, recvPath=%{private}s, errno=%{public}d.", rootDir, errno); return false; } SoftBusFree(absPath); return true; } int SetFileReceiveListener(const char *pkgName, const char *sessionName, const IFileReceiveListener *recvListener, const char *rootDir) { if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX - 1) || !IsValidString(sessionName, SESSION_NAME_SIZE_MAX - 1) || !IsValidFileReceivePath(rootDir) || (recvListener == NULL)) { TRANS_LOGW(TRANS_SDK, "set file receive listener invalid param"); return SOFTBUS_INVALID_PARAM; } if (InitSoftBus(pkgName) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "set file receive listener init softbus client error"); return SOFTBUS_TRANS_SESSION_ADDPKG_FAILED; } char *tmpName = NULL; Anonymize(sessionName, &tmpName); TRANS_LOGI(TRANS_SDK, "sessionName=%{public}s", tmpName); AnonymizeFree(tmpName); return TransSetFileReceiveListener(sessionName, recvListener, rootDir); } int SetFileSendListener(const char *pkgName, const char *sessionName, const IFileSendListener *sendListener) { if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX - 1) || !IsValidString(sessionName, SESSION_NAME_SIZE_MAX - 1) || sendListener == NULL) { TRANS_LOGW(TRANS_SDK, "set file send listener invalid param"); return SOFTBUS_INVALID_PARAM; } if (InitSoftBus(pkgName) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "set file send listener init softbus client error"); return SOFTBUS_TRANS_SESSION_ADDPKG_FAILED; } char *tmpName = NULL; Anonymize(sessionName, &tmpName); TRANS_LOGI(TRANS_SDK, "sessionName=%{public}s", tmpName); AnonymizeFree(tmpName); return TransSetFileSendListener(sessionName, sendListener); } static const char *g_busName = "DistributedFileService"; static const char *g_deviceStatusName = "ohos.msdp.device_status"; static int32_t IsValidDFSSession(int32_t sessionId, int32_t *channelId) { char sessionName[SESSION_NAME_SIZE_MAX] = { 0 }; int32_t type; int32_t ret = GetMySessionName(sessionId, sessionName, SESSION_NAME_SIZE_MAX); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get dfs session name failed"); return ret; } if (strncmp(sessionName, g_busName, strlen(g_busName)) != 0 && strncmp(sessionName, g_deviceStatusName, strlen(g_deviceStatusName)) != 0) { TRANS_LOGE(TRANS_SDK, "invalid dfs session name"); return SOFTBUS_TRANS_FUNC_NOT_SUPPORT; } ret = ClientGetChannelBySessionId(sessionId, channelId, &type, NULL); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get channel by sessionId=%{public}d failed, ret=%{public}d", sessionId, ret); return SOFTBUS_TRANS_SESSION_GET_CHANNEL_FAILED; } if (type != CHANNEL_TYPE_TCP_DIRECT) { TRANS_LOGE(TRANS_SDK, "invalid channel type"); return SOFTBUS_TRANS_FUNC_NOT_SUPPORT; } return SOFTBUS_OK; } int32_t GetSessionKey(int32_t sessionId, char *key, unsigned int len) { int32_t channelId; if (!IsValidSessionId(sessionId) || key == NULL || len < SESSION_KEY_LEN) { TRANS_LOGW(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } if (IsValidDFSSession(sessionId, &channelId) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "invalid dfs session"); return SOFTBUS_TRANS_FUNC_NOT_SUPPORT; } return ClientGetSessionKey(channelId, key, len); } int32_t GetSessionHandle(int32_t sessionId, int *handle) { int32_t channelId; if (!IsValidSessionId(sessionId) || handle == NULL) { TRANS_LOGW(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } if (IsValidDFSSession(sessionId, &channelId) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "invalid dfs session"); return SOFTBUS_TRANS_FUNC_NOT_SUPPORT; } return ClientGetHandle(channelId, handle); } int32_t DisableSessionListener(int32_t sessionId) { int32_t channelId; if (!IsValidSessionId(sessionId)) { TRANS_LOGW(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } if (IsValidDFSSession(sessionId, &channelId) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "invalid dfs session"); return SOFTBUS_TRANS_FUNC_NOT_SUPPORT; } return ClientDisableSessionListener(channelId); } int32_t QosReport(int32_t sessionId, int32_t appType, int32_t quality) { if (quality != QOS_IMPROVE && quality != QOS_RECOVER) { TRANS_LOGW(TRANS_SDK, "qos report invalid param"); return SOFTBUS_INVALID_PARAM; } int32_t channelId = INVALID_CHANNEL_ID; int32_t type = CHANNEL_TYPE_BUTT; int32_t ret = ClientGetChannelBySessionId(sessionId, &channelId, &type, NULL); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get channel by sessionId=%{public}d failed, ret=%{public}d.", sessionId, ret); return SOFTBUS_TRANS_SESSION_GET_CHANNEL_FAILED; } if (ClientGetSessionSide(sessionId) != IS_CLIENT) { TRANS_LOGE(TRANS_SDK, "qos report not exist or not client side. sessionId=%{public}d", sessionId); return SOFTBUS_TRANS_INVALID_SESSION_ID; } ret = ClientQosReport(channelId, type, appType, quality); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "qos report failed. sessionId=%{public}d, ret=%{public}d", sessionId, ret); } return ret; } static const ConfigTypeMap g_configTypeMap[] = { {CHANNEL_TYPE_AUTH, BUSINESS_TYPE_BYTE, SOFTBUS_INT_AUTH_MAX_BYTES_LENGTH}, {CHANNEL_TYPE_AUTH, BUSINESS_TYPE_MESSAGE, SOFTBUS_INT_AUTH_MAX_MESSAGE_LENGTH}, {CHANNEL_TYPE_PROXY, BUSINESS_TYPE_BYTE, SOFTBUS_INT_PROXY_MAX_BYTES_LENGTH}, {CHANNEL_TYPE_PROXY, BUSINESS_TYPE_MESSAGE, SOFTBUS_INT_PROXY_MAX_MESSAGE_LENGTH}, {CHANNEL_TYPE_TCP_DIRECT, BUSINESS_TYPE_BYTE, SOFTBUS_INT_MAX_BYTES_LENGTH}, {CHANNEL_TYPE_TCP_DIRECT, BUSINESS_TYPE_MESSAGE, SOFTBUS_INT_MAX_MESSAGE_LENGTH}, }; int32_t GetDefaultConfigType(int32_t channelType, int32_t businessType) { const uint32_t nums = sizeof(g_configTypeMap) / sizeof(ConfigTypeMap); for (uint32_t i = 0; i < nums; i++) { if ((g_configTypeMap[i].channelType == channelType) && (g_configTypeMap[i].businessType == businessType)) { return g_configTypeMap[i].configType; } } return SOFTBUS_CONFIG_TYPE_MAX; } int ReadMaxSendBytesSize(int32_t channelId, int32_t type, void* value, uint32_t valueSize) { if (valueSize != sizeof(uint32_t)) { TRANS_LOGE(TRANS_SDK, "valueSize not match. valueSize=%{public}d", valueSize); return SOFTBUS_INVALID_PARAM; } uint32_t dataConfig = INVALID_DATA_CONFIG; if (ClientGetDataConfigByChannelId(channelId, type, &dataConfig) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get config failed."); return SOFTBUS_GET_CONFIG_VAL_ERR; } (*(uint32_t*)value) = dataConfig; return SOFTBUS_OK; } int ReadMaxSendMessageSize(int32_t channelId, int32_t type, void* value, uint32_t valueSize) { if (value == NULL) { TRANS_LOGE(TRANS_SDK, "param invalid"); return SOFTBUS_INVALID_PARAM; } if (valueSize != sizeof(uint32_t)) { TRANS_LOGE(TRANS_SDK, "valueSize not match. valueSize=%{public}d", valueSize); return SOFTBUS_INVALID_PARAM; } uint32_t dataConfig = INVALID_DATA_CONFIG; if (ClientGetDataConfigByChannelId(channelId, type, &dataConfig) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get config failed."); return SOFTBUS_GET_CONFIG_VAL_ERR; } (*(uint32_t*)value) = dataConfig; return SOFTBUS_OK; } int ReadSessionLinkType(int32_t channelId, int32_t type, void* value, uint32_t valueSize) { if (value == NULL) { TRANS_LOGE(TRANS_SDK, "param invalid"); return SOFTBUS_INVALID_PARAM; } if (valueSize != sizeof(uint32_t)) { TRANS_LOGE(TRANS_SDK, "valueSize not match. valueSize=%{public}d", valueSize); return SOFTBUS_INVALID_PARAM; } int32_t routeType = INVALID_ROUTE_TYPE; if (ClientGetRouteTypeByChannelId(channelId, type, &routeType) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get link type failed."); return SOFTBUS_GET_CONFIG_VAL_ERR; } (*(int32_t*)value) = routeType; return SOFTBUS_OK; } static const SessionOptionItem g_SessionOptionArr[SESSION_OPTION_BUTT] = { {true, ReadMaxSendBytesSize}, {true, ReadMaxSendMessageSize}, {true, ReadSessionLinkType}, }; int GetSessionOption(int sessionId, SessionOption option, void* optionValue, uint32_t valueSize) { if ((option >= SESSION_OPTION_BUTT) || (optionValue == NULL) || (valueSize == 0)) { TRANS_LOGW(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } if (!g_SessionOptionArr[option].canRead) { TRANS_LOGE(TRANS_SDK, "option can not be get. option=%{public}d", option); return SOFTBUS_INVALID_PARAM; } int32_t channelId = INVALID_CHANNEL_ID; int32_t type = CHANNEL_TYPE_BUTT; int32_t ret = ClientGetChannelBySessionId(sessionId, &channelId, &type, NULL); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get channel by sessionId=%{public}d failed, ret=%{public}d.", sessionId, ret); return SOFTBUS_TRANS_SESSION_GET_CHANNEL_FAILED; } return g_SessionOptionArr[option].readFunc(channelId, type, optionValue, valueSize); } bool RemoveAppIdFromSessionName(const char *sessionName, char *newSessionName) { if ((sessionName == NULL) || (newSessionName == NULL)) { TRANS_LOGE(TRANS_SDK, "invalid param"); return false; } const char tag = '-'; const char *posName = strchr(sessionName, tag); if (posName == NULL) { TRANS_LOGE(TRANS_SDK, "sdk not find bundlename"); return false; } const char *posId = strchr(posName + 1, tag); if (posId == NULL) { TRANS_LOGE(TRANS_SDK, "sdk not find appid"); return false; } size_t len = posId - sessionName; if (strncpy_s(newSessionName, SESSION_NAME_SIZE_MAX + 1, sessionName, len) != EOK) { TRANS_LOGE(TRANS_SDK, "copy sessionName failed"); return false; } return true; } int CreateSocket(const char *pkgName, const char *sessionName) { if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX - 1) || !IsValidString(sessionName, SESSION_NAME_SIZE_MAX - 1)) { TRANS_LOGE(TRANS_SDK, "invalid pkgName or sessionName"); return SOFTBUS_INVALID_PARAM; } if (InitSoftBus(pkgName) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "init softbus err"); return SOFTBUS_TRANS_SESSION_ADDPKG_FAILED; } if (CheckPackageName(pkgName) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "invalid pkg name"); return SOFTBUS_INVALID_PKGNAME; } char newSessionName[SESSION_NAME_SIZE_MAX + 1] = {0}; if (strncpy_s(newSessionName, SESSION_NAME_SIZE_MAX + 1, sessionName, strlen(sessionName)) != EOK) { TRANS_LOGE(TRANS_SDK, "copy session name failed"); return SOFTBUS_STRCPY_ERR; } if (CheckIsNormalApp(sessionName)) { if (!RemoveAppIdFromSessionName(sessionName, newSessionName)) { TRANS_LOGE(TRANS_SDK, "invalid bundlename or appId and delete appId failed"); return SOFTBUS_TRANS_NOT_FIND_APPID; } } int32_t ret = ClientAddSocketServer(SEC_TYPE_CIPHERTEXT, pkgName, (const char *)newSessionName); if (ret == SOFTBUS_SERVER_NAME_REPEATED) { TRANS_LOGD(TRANS_SDK, "SocketServer is already created in client"); } else if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "add socket server err, ret=%{public}d", ret); return ret; } ret = ServerIpcCreateSessionServer(pkgName, sessionName); if (ret == SOFTBUS_SERVER_NAME_REPEATED) { TRANS_LOGD(TRANS_SDK, "ok, SocketServer is already created in server"); return SOFTBUS_OK; } else if (ret != SOFTBUS_OK) { SocketServerStateUpdate(newSessionName); TRANS_LOGE(TRANS_SDK, "createSocketServer failed, ret=%{public}d", ret); (void)ClientDeleteSessionServer(SEC_TYPE_CIPHERTEXT, newSessionName); return ret; } TRANS_LOGD(TRANS_SDK, "ok"); return SOFTBUS_OK; } static SessionAttribute *CreateSessionAttributeBySocketInfoTrans(const SocketInfo *info, bool *isEncyptedRawStream) { SessionAttribute *tmpAttr = (SessionAttribute *)SoftBusCalloc(sizeof(SessionAttribute)); if (tmpAttr == NULL) { TRANS_LOGE(TRANS_SDK, "SoftBusCalloc SessionAttribute failed"); return NULL; } *isEncyptedRawStream = false; tmpAttr->fastTransData = NULL; tmpAttr->fastTransDataSize = 0; switch (info->dataType) { case DATA_TYPE_MESSAGE: tmpAttr->dataType = TYPE_MESSAGE; break; case DATA_TYPE_BYTES: tmpAttr->dataType = TYPE_BYTES; break; case DATA_TYPE_FILE: tmpAttr->dataType = TYPE_FILE; break; case DATA_TYPE_RAW_STREAM: case DATA_TYPE_RAW_STREAM_ENCRYPED: tmpAttr->dataType = TYPE_STREAM; tmpAttr->attr.streamAttr.streamType = RAW_STREAM; *isEncyptedRawStream = (info->dataType == DATA_TYPE_RAW_STREAM_ENCRYPED); break; case DATA_TYPE_VIDEO_STREAM: tmpAttr->dataType = TYPE_STREAM; tmpAttr->attr.streamAttr.streamType = COMMON_VIDEO_STREAM; break; case DATA_TYPE_AUDIO_STREAM: tmpAttr->dataType = TYPE_STREAM; tmpAttr->attr.streamAttr.streamType = COMMON_AUDIO_STREAM; break; case DATA_TYPE_SLICE_STREAM: tmpAttr->dataType = TYPE_STREAM; tmpAttr->attr.streamAttr.streamType = VIDEO_SLICE_STREAM; break; default: // The socket used for listening does not require setting the data type break; } return tmpAttr; } int32_t ClientAddSocket(const SocketInfo *info, int32_t *sessionId) { if (info == NULL || sessionId == NULL) { TRANS_LOGE(TRANS_SDK, "ClientAddSocket invalid param"); return SOFTBUS_INVALID_PARAM; } bool isEncyptedRawStream = false; SessionAttribute *tmpAttr = CreateSessionAttributeBySocketInfoTrans(info, &isEncyptedRawStream); if (tmpAttr == NULL) { TRANS_LOGE(TRANS_SDK, "Create SessionAttribute failed"); return SOFTBUS_MALLOC_ERR; } SessionParam param = { .sessionName = info->name != NULL ? info->name : "", .peerSessionName = info->peerName != NULL ? info->peerName : "", .peerDeviceId = info->peerNetworkId != NULL ? info->peerNetworkId : "", .groupId = "reserved", .actionId = INVALID_ACTION_ID, .attr = tmpAttr, }; SessionEnableStatus isEnabled = ENABLE_STATUS_INIT; int32_t ret = ClientAddSocketSession(¶m, isEncyptedRawStream, sessionId, &isEnabled); if (ret != SOFTBUS_OK) { SoftBusFree(tmpAttr); if (ret == SOFTBUS_TRANS_SESSION_REPEATED) { TRANS_LOGI(TRANS_SDK, "socket already create"); return SOFTBUS_OK; } TRANS_LOGE(TRANS_SDK, "add socket err: ret=%{public}d", ret); return ret; } SoftBusFree(tmpAttr); return SOFTBUS_OK; } static bool IsValidSocketListener(const ISocketListener *listener, bool isListenSocket) { if (listener == NULL || listener->OnShutdown == NULL) { TRANS_LOGE(TRANS_SDK, "listener is null or OnShutdown is null"); return false; } if (isListenSocket && listener->OnBind == NULL) { TRANS_LOGE(TRANS_SDK, "no OnBind callback function of listen socket"); return false; } return true; } static bool IsValidAsyncBindSocketListener(const ISocketListener *listener, bool isAsync) { if (isAsync && (listener->OnBind == NULL)) { TRANS_LOGE(TRANS_SDK, "no OnBind callback function of async bind"); return false; } if (isAsync && (listener->OnError == NULL)) { TRANS_LOGE(TRANS_SDK, "no onError callback function of async bind"); return false; } return true; } static int32_t GetMaxIdleTimeout(const QosTV *qos, uint32_t qosCount, uint32_t *maxIdleTimeout) { #define TRANS_DEFAULT_MAX_IDLE_TIMEOUT 0 int32_t tmpIdleTime = 0; int32_t ret = GetQosValue(qos, qosCount, QOS_TYPE_MAX_IDLE_TIMEOUT, &tmpIdleTime, TRANS_DEFAULT_MAX_IDLE_TIMEOUT); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get maximum idle time failed, ret=%{public}d", ret); return ret; } if (tmpIdleTime < 0) { TRANS_LOGE(TRANS_SDK, "invalid maximum idle time, maxIdleTimeout=%{public}d", tmpIdleTime); return SOFTBUS_INVALID_PARAM; } *maxIdleTimeout = (uint32_t)tmpIdleTime; return SOFTBUS_OK; } static int32_t CheckSessionCancelState(int32_t socket) { SocketLifecycleData lifecycle; (void)memset_s(&lifecycle, sizeof(SocketLifecycleData), 0, sizeof(SocketLifecycleData)); int32_t ret = GetSocketLifecycleAndSessionNameBySessionId(socket, NULL, &lifecycle); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get socket state failed, socket=%{public}d failed, ret=%{public}d", socket, ret); return ret; } if (lifecycle.sessionState == SESSION_STATE_CANCELLING) { TRANS_LOGW(TRANS_SDK, "This socket already in cancelling state. socket=%{public}d", socket); int32_t channelId = INVALID_CHANNEL_ID; int32_t type = CHANNEL_TYPE_BUTT; ret = ClientGetChannelBySessionId(socket, &channelId, &type, NULL); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get channel by socket=%{public}d failed, ret=%{public}d", socket, ret); } ret = ClientTransCloseChannel(channelId, type); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "close channel err: ret=%{public}d, channelId=%{public}d, channeType=%{public}d", ret, channelId, type); } return lifecycle.bindErrCode; } return SOFTBUS_OK; } int32_t ClientBind(int32_t socket, const QosTV qos[], uint32_t qosCount, const ISocketListener *listener, bool isAsync) { if (!IsValidSessionId(socket) || !IsValidSocketListener(listener, false) || !IsValidAsyncBindSocketListener(listener, isAsync) || !IsValidQosInfo(qos, qosCount)) { TRANS_LOGE(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } // For rebind, clear the socket state. int32_t ret = ClientSetSocketState(socket, 0, SESSION_ROLE_INIT); TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "init session role failed, ret=%{public}d", ret); ret = SetSessionStateBySessionId(socket, SESSION_STATE_INIT, 0); TRANS_CHECK_AND_RETURN_RET_LOGE( ret == SOFTBUS_OK, ret, TRANS_SDK, "init session state failed, ret=%{public}d", ret); ret = ClientSetListenerBySessionId(socket, listener, false); TRANS_CHECK_AND_RETURN_RET_LOGE( ret == SOFTBUS_OK, ret, TRANS_SDK, "set listener by socket=%{public}d failed, ret=%{public}d", socket, ret); uint32_t maxIdleTimeout = 0; ret = GetMaxIdleTimeout(qos, qosCount, &maxIdleTimeout); TRANS_CHECK_AND_RETURN_RET_LOGE( ret == SOFTBUS_OK, ret, TRANS_SDK, "get maximum idle time failed, ret=%{public}d", ret); ret = SetSessionIsAsyncById(socket, isAsync); TRANS_CHECK_AND_RETURN_RET_LOGE( ret == SOFTBUS_OK, ret, TRANS_SDK, "set session is async failed, ret=%{public}d", ret); TransInfo transInfo; ret = ClientIpcOpenSession(socket, qos, qosCount, &transInfo, isAsync); TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "open session failed, ret=%{public}d", ret); if (!isAsync) { ret = CheckSessionCancelState(socket); TRANS_CHECK_AND_RETURN_RET_LOGE( ret == SOFTBUS_OK, ret, TRANS_SDK, "check session cancel state failed, ret=%{public}d", ret); ret = ClientWaitSyncBind(socket); TRANS_CHECK_AND_RETURN_RET_LOGE( ret == SOFTBUS_OK, ret, TRANS_SDK, "ClientWaitSyncBind err, ret=%{public}d", ret); } ret = ClientSetSocketState(socket, maxIdleTimeout, SESSION_ROLE_CLIENT); TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "set session role failed, ret=%{public}d", ret); if (!isAsync) { (void)ClientGetChannelBySessionId(socket, &(transInfo.channelId), &(transInfo.channelType), NULL); TRANS_LOGI(TRANS_SDK, "Bind ok: socket=%{public}d, channelId=%{public}d, channelType=%{public}d", socket, transInfo.channelId, transInfo.channelType); } else { TRANS_LOGI(TRANS_SDK, "Bind async ok: socket=%{public}d", socket); } return SOFTBUS_OK; } int32_t ClientListen(int32_t socket, const QosTV qos[], uint32_t qosCount, const ISocketListener *listener) { if (!IsValidSocketListener(listener, true) || !IsValidQosInfo(qos, qosCount)) { TRANS_LOGE(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } int32_t ret = ClientSetListenerBySessionId(socket, listener, true); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "set listener by socket=%{public}d failed. ret=%{public}d", socket, ret); return ret; } uint32_t maxIdleTimeout = 0; ret = GetMaxIdleTimeout(qos, qosCount, &maxIdleTimeout); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get maximum idle time failed, ret=%{public}d", ret); return ret; } ret = ClientSetSocketState(socket, maxIdleTimeout, SESSION_ROLE_SERVER); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "set session role failed. ret=%{public}d", ret); return ret; } TRANS_LOGD(TRANS_SDK, "Listen ok: socket=%{public}d", socket); return SOFTBUS_OK; } void ClientShutdown(int32_t socket, int32_t cancelReason) { if (!IsValidSessionId(socket)) { TRANS_LOGE(TRANS_SDK, "invalid param"); return; } SocketLifecycleData lifecycle; (void)memset_s(&lifecycle, sizeof(SocketLifecycleData), 0, sizeof(SocketLifecycleData)); char sessioName[SESSION_NAME_SIZE_MAX] = { 0 }; int32_t ret = GetSocketLifecycleAndSessionNameBySessionId(socket, sessioName, &lifecycle); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get socket state failed, socket=%{public}d failed, ret=%{public}d", socket, ret); return; } if (lifecycle.sessionState == SESSION_STATE_CANCELLING) { TRANS_LOGW(TRANS_SDK, "This socket already in cancelling state. socket=%{public}d", socket); } SetSessionStateBySessionId(socket, SESSION_STATE_CANCELLING, cancelReason); if (lifecycle.sessionState == SESSION_STATE_INIT) { TRANS_LOGI(TRANS_SDK, "This socket state is init, socket=%{public}d", socket); } else if (lifecycle.sessionState == SESSION_STATE_OPENING) { TRANS_LOGI(TRANS_SDK, "This socket state is opening, socket=%{public}d", socket); int32_t ret = ServerIpcCloseChannel(sessioName, socket, CHANNEL_TYPE_UNDEFINED); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "Call sa delete socket failed: ret=%{public}d", ret); } ret = ClientSignalSyncBind(socket, 0); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "sync signal bind failed, ret=%{public}d, socket=%{public}d", ret, socket); } } else if (lifecycle.sessionState == SESSION_STATE_OPENED || lifecycle.sessionState == SESSION_STATE_CALLBACK_FINISHED) { if (lifecycle.sessionState == SESSION_STATE_OPENED) { TRANS_LOGI(TRANS_SDK, "This socket state is opened, socket=%{public}d", socket); CheckSessionIsOpened(socket, true); } TRANS_LOGI(TRANS_SDK, "This socket state is callback finish, socket=%{public}d", socket); int32_t channelId = INVALID_CHANNEL_ID; int32_t type = CHANNEL_TYPE_BUTT; ret = ClientGetChannelBySessionId(socket, &channelId, &type, NULL); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get channel by socket=%{public}d failed, ret=%{public}d", socket, ret); } else { AddSessionStateClosing(); } ret = ClientTransCloseChannel(channelId, type); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "close channel err: ret=%{public}d, channelId=%{public}d, channeType=%{public}d", ret, channelId, type); } if (lifecycle.sessionState == SESSION_STATE_OPENED) { (void)ClientSignalSyncBind(socket, cancelReason); } } if (cancelReason == SOFTBUS_TRANS_STOP_BIND_BY_TIMEOUT) { SetSessionInitInfoById(socket); TRANS_LOGI(TRANS_SDK, "Bind timeout Shutdown ok, no delete socket: socket=%{public}d", socket); return; } (void)ClientDeleteSocketSession(socket); TRANS_LOGI(TRANS_SDK, "Shutdown ok: socket=%{public}d", socket); } int32_t GetSocketMtuSize(int32_t socket, uint32_t *mtuSize) { if (!IsValidSessionId(socket) || mtuSize == NULL) { TRANS_LOGE(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } int32_t channelId = INVALID_CHANNEL_ID; int32_t type = CHANNEL_TYPE_BUTT; SessionEnableStatus enableStatus = ENABLE_STATUS_INIT; int32_t ret = ClientGetChannelBySessionId(socket, &channelId, &type, &enableStatus); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get channel by socket=%{public}d failed, ret=%{public}d.", socket, ret); return ret; } if (enableStatus != ENABLE_STATUS_SUCCESS) { TRANS_LOGI(TRANS_SDK, "socket not enable"); return SOFTBUS_TRANS_SESSION_NO_ENABLE; } uint32_t dataConfig = INVALID_DATA_CONFIG; if (ClientGetDataConfigByChannelId(channelId, type, &dataConfig) != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "get config by channelId=%{public}d failed", channelId); return SOFTBUS_GET_CONFIG_VAL_ERR; } *mtuSize = dataConfig; TRANS_LOGI(TRANS_SDK, "get mtuSize success, socket=%{public}d, mtu=%{public}" PRIu32, socket, *mtuSize); return SOFTBUS_OK; } int32_t ClientDfsBind(int32_t socket, const ISocketListener *listener) { if (!IsValidSessionId(socket) || !IsValidSocketListener(listener, false)) { TRANS_LOGE(TRANS_SDK, "invalid param"); return SOFTBUS_INVALID_PARAM; } int32_t ret = ClientSetListenerBySessionId(socket, listener, false); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "set listener by socket=%{public}d failed, ret=%{public}d", socket, ret); return ret; } ret = SetSessionIsAsyncById(socket, false); TRANS_CHECK_AND_RETURN_RET_LOGE( ret == SOFTBUS_OK, ret, TRANS_SDK, "set session is async failed, ret=%{public}d", ret); TransInfo transInfo; ret = ClientDfsIpcOpenSession(socket, &transInfo); if (ret != SOFTBUS_OK) { TRANS_LOGE(TRANS_SDK, "open session failed, ret=%{public}d", ret); return ret; } ret = ClientSetChannelBySessionId(socket, &transInfo); TRANS_CHECK_AND_RETURN_RET_LOGE( ret == SOFTBUS_OK, ret, TRANS_SDK, "set channel by socket=%{public}d failed, ret=%{public}d", socket, ret); ret = SetSessionStateBySessionId(socket, SESSION_STATE_OPENED, 0); TRANS_CHECK_AND_RETURN_RET_LOGE( ret == SOFTBUS_OK, ret, TRANS_SDK, "set session state failed socket=%{public}d, ret=%{public}d", socket, ret); ret = ClientWaitSyncBind(socket); TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "ClientWaitSyncBind err, ret=%{public}d", ret); ret = ClientSetSocketState(socket, 0, SESSION_ROLE_CLIENT); TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "set session role failed, ret=%{public}d", ret); TRANS_LOGI(TRANS_SDK, "DfsBind ok: socket=%{public}d, channelId=%{public}d, channelType=%{public}d", socket, transInfo.channelId, transInfo.channelType); return SOFTBUS_OK; }