!90 add dfile for dsoftbus

Merge pull request !90 from liubb_0516/master
This commit is contained in:
openharmony_ci 2021-07-26 13:48:07 +00:00 committed by Gitee
commit 976bc4bcf4
20 changed files with 911 additions and 22 deletions

View File

@ -33,6 +33,7 @@ extern "C" {
#define DEVICE_ID_SIZE_MAX 65
#define GROUP_ID_SIZE_MAX 65
#define AUTH_STATE_SIZE_MAX 65
#define FILE_RECV_ROOT_DIR_SIZE_MAX 256
#define MAX_DEV_INFO_VALUE_LEN 65
#define MAX_CAPABILITY_LEN 33

View File

@ -81,6 +81,8 @@ static AppInfo *GetAppInfo(const char *mySessionName, const char *peerSessionNam
if (flags == TYPE_STREAM) {
appInfo->businessType = BUSINESS_TYPE_STREAM;
appInfo->streamType = RAW_STREAM;
} else if (flags == TYPE_FILE) {
appInfo->businessType = BUSINESS_TYPE_FILE;
}
if (TransGetUidAndPid(mySessionName, &appInfo->myData.uid, &appInfo->myData.pid) != SOFTBUS_OK) {
goto EXIT_ERR;

View File

@ -196,6 +196,19 @@ typedef struct {
void (*OnStreamReceived)(int sessionId, const StreamData *data, const StreamData *ext, const FrameInfo *param);
} ISessionListener;
typedef struct {
int (*OnReceiveFileStarted)(int sessionId, const char *files, int fileCnt);
int (*OnReceiveFileProcess)(int sessionId, const char *firstFile, uint64_t bytesUpload, uint64_t bytesTotal);
void (*OnReceiveFileFinished)(int sessionId, const char *files, int fileCnt);
void (*OnFileTransError)(int sessionId);
} IFileReceiveListener;
typedef struct {
int (*OnSendFileProcess)(int sessionId, uint64_t bytesUpload, uint64_t bytesTotal);
int (*OnSendFileFinished)(int sessionId, const char *firstFile);
void (*OnFileTransError)(int sessionId);
} IFileSendListener;
/**
* @brief Creates a session server based on a package name and session name.
*
@ -318,6 +331,12 @@ int GetPeerSessionName(int sessionId, char *sessionName, unsigned int len);
*/
int GetPeerDeviceId(int sessionId, char *devId, unsigned int len);
int SetFileReceiveListener(const char *pkgName, const char *sessionName,
const IFileReceiveListener *recvListener, const char *rootDir);
int SetFileSendListener(const char *pkgName, const char *sessionName, const IFileSendListener *sendListener);
int SendFile(int sessionId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt);
#ifdef __cplusplus
}
#endif

View File

@ -80,7 +80,7 @@ if (defined(ohos_lite)) {
include_dirs = common_include
sources = common_src
public_configs = [ ":trans_session_manager_sdk_interface" ]
deps = [
public_deps = [
"$dsoftbus_root_path/core/adapter/kernel:softbus_adapter_kernel",
"$dsoftbus_root_path/core/common/utils:softbus_utils",
"$dsoftbus_sdk_path/transmission/ipc:dsoftbus_trans_ipc_proxy_sdk",

View File

@ -31,6 +31,7 @@ typedef struct {
const void *data, uint32_t len, SessionPktType type);
void (*OnStreamReceived)(int32_t channelId, int32_t channelType,
const StreamData *data, const StreamData *ext, const FrameInfo *param);
int32_t (*OnGetSessionId)(int32_t channelId, int32_t channelType, int32_t *sessionId);
} IClientSessionCallBack;
IClientSessionCallBack *GetClientSessionCb(void);

View File

@ -87,4 +87,26 @@ int SendStream(int sessionId, const StreamData *data, const StreamData *ext, con
}
return ClientTransChannelSendStream(channelId, type, data, ext, param);
}
int SendFile(int sessionId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt)
{
if ((sFileList == NULL) || (fileCnt == 0)) {
LOG_ERR("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);
if (ret != SOFTBUS_OK) {
LOG_ERR("get channel failed");
return ret;
}
if (type != CHANNEL_TYPE_UDP) {
LOG_INFO("invalid channel type");
return SOFTBUS_INVALID_PARAM;
}
return ClientTransChannelSendFile(channelId, sFileList, dFileList, fileCnt);
}

View File

@ -211,6 +211,7 @@ IClientSessionCallBack *GetClientSessionCb(void)
g_sessionCb.OnSessionOpenFailed = TransOnSessionOpenFailed;
g_sessionCb.OnDataReceived = TransOnDataReceived;
g_sessionCb.OnStreamReceived = TransOnOnStreamRecevied;
g_sessionCb.OnGetSessionId = ClientGetSessionIdByChannelId;
return &g_sessionCb;
}

View File

@ -122,6 +122,7 @@ int RemoveSessionServer(const char *pkgName, const char *sessionName)
if (ret != SOFTBUS_OK) {
LOG_ERR("delete session server [%s] failed", sessionName);
}
TransDeleteFileListener(sessionName);
LOG_INFO("RemoveSessionServer ok: ret=%d", ret);
return ret;
}
@ -314,3 +315,32 @@ int GetPeerDeviceId(int sessionId, char *devId, unsigned int len)
return ClientGetSessionDataById(sessionId, devId, len, KEY_PEER_DEVICE_ID);
}
int SetFileReceiveListener(const char *pkgName, const char *sessionName,
const IFileReceiveListener *recvListener, const char *rootDir)
{
if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX) || !IsValidString(sessionName, SESSION_NAME_SIZE_MAX) ||
!IsValidString(rootDir, FILE_RECV_ROOT_DIR_SIZE_MAX) || recvListener == NULL) {
LOG_ERR("set file receive listener invalid param");
return SOFTBUS_INVALID_PARAM;
}
if (InitSoftBus(pkgName) != SOFTBUS_OK) {
LOG_ERR("set file receive listener init softbus client error");
return SOFTBUS_ERR;
}
return TransSetFileReceiveListener(sessionName, recvListener, rootDir);
}
int SetFileSendListener(const char *pkgName, const char *sessionName, const IFileSendListener *sendListener)
{
if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX) || !IsValidString(sessionName, SESSION_NAME_SIZE_MAX) ||
sendListener == NULL) {
LOG_ERR("set file send listener invalid param");
return SOFTBUS_INVALID_PARAM;
}
if (InitSoftBus(pkgName) != SOFTBUS_OK) {
LOG_ERR("set file send listener init softbus client error");
return SOFTBUS_ERR;
}
return TransSetFileSendListener(sessionName, sendListener);
}

View File

@ -35,6 +35,9 @@ int32_t ClientTransChannelSendMessage(int32_t channelId, int32_t type, const voi
int32_t ClientTransChannelSendStream(int32_t channelId, int32_t type, const StreamData *data, const StreamData *ext,
const FrameInfo *param);
int32_t ClientTransChannelSendFile(int32_t channelId, const char *sFileList[],
const char *dFileList[], uint32_t fileCnt);
#ifdef __cplusplus
}
#endif

View File

@ -134,4 +134,10 @@ int32_t ClientTransChannelSendStream(int32_t channelId, int32_t type, const Stre
return SOFTBUS_ERR;
}
return ret;
}
int32_t ClientTransChannelSendFile(int32_t channelId, const char *sFileList[],
const char *dFileList[], uint32_t fileCnt)
{
return TransUdpChannelSendFile(channelId, sFileList, dFileList, fileCnt);
}

View File

@ -21,6 +21,9 @@ if (enable_trans_udp == true) {
common_src = [
"common/src/client_trans_udp_manager.c",
"stream/src/client_trans_stream.c",
"file/src/client_trans_file_listener.c",
"file/src/client_trans_file.c",
"file/src/file_adapter.c",
]
} else {
common_src = [ "common/src/client_trans_udp_virtual.c" ]
@ -60,6 +63,11 @@ if (defined(ohos_lite)) {
"$dsoftbus_core_path/common/include",
"$dsoftbus_root_path/sdk/transmission/session/include",
"stream/include",
"file/include",
"$dsoftbus_root_path/components/nstackx_enhanced/nstackx_core/dfile/interface",
"$dsoftbus_root_path/components/nstackx_enhanced/nstackx_util/interface",
"//third_party/bounds_checking_function/include",
"$dsoftbus_root_path/core/connection/interface",
]
cflags = [
"-Wall",
@ -72,8 +80,12 @@ if (defined(ohos_lite)) {
deps = [
"stream/adaptor:dsoftbus_trans_dstream",
"//third_party/bounds_checking_function:libsec_shared",
"$dsoftbus_root_path/core/connection/common:conn_common",
]
deps += common_deps
public_deps = [
"$dsoftbus_root_path/components/nstackx_enhanced:nstackx",
]
}
}
}
@ -87,6 +99,8 @@ if (defined(ohos_lite)) {
"$dsoftbus_root_path/sdk/transmission/session/include",
"$dsoftbus_root_path/sdk/transmission/trans_channel/udp/stream/include",
"$dsoftbus_root_path/core/adapter/kernel/include",
"file/include",
"$dsoftbus_root_path/core/connection/interface",
]
sources = common_src
public_configs = [ ":trans_udp_channel_sdk_interface" ]

View File

@ -28,12 +28,31 @@ extern "C" {
typedef struct {
void (*OnStreamReceived)(int32_t channelId, const StreamData *data, const StreamData *ext, const FrameInfo *param);
void (*OnFileReceived)(void);
int32_t (*OnFileGetSessionId)(int32_t channelId, int32_t *sessionId);
void (*OnMessageReceived)(void);
void (*OnUdpChannelOpened)(int32_t channelId);
void (*OnUdpChannelClosed)(int32_t channelId);
} UdpChannelMgrCb;
typedef struct {
bool isServer;
int32_t peerUid;
int32_t peerPid;
char mySessionName[SESSION_NAME_SIZE_MAX];
char peerSessionName[SESSION_NAME_SIZE_MAX];
char peerDeviceId[DEVICE_ID_SIZE_MAX];
char groupId[GROUP_ID_SIZE_MAX];
} sessionNeed;
typedef struct {
ListNode node;
int32_t channelId;
int32_t dfileId;
int32_t businessType;
bool isEnable;
sessionNeed info;
} UdpChannel;
int32_t ClientTransUdpMgrInit(IClientSessionCallBack *callback);
void ClientTransUdpMgrDeinit(void);
@ -45,6 +64,10 @@ int32_t TransCloseUdpChannel(int32_t channelId);
int32_t TransUdpChannelSendStream(int32_t channelId, const StreamData *data, const StreamData *ext,
const FrameInfo *param);
int32_t TransUdpChannelSendFile(int32_t channelId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt);
int32_t TransGetUdpChannelByFileId(int32_t dfileId, UdpChannel *udpChannel);
#ifdef __cplusplus
}
#endif

View File

@ -16,6 +16,7 @@
#include "client_trans_udp_manager.h"
#include <stdbool.h>
#include "client_trans_file.h"
#include "client_trans_stream.h"
#include "securec.h"
#include "softbus_errcode.h"
@ -26,24 +27,6 @@
#define MAX_UDP_CHANNEL 10
typedef struct {
bool isServer;
int32_t peerUid;
int32_t peerPid;
char mySessionName[SESSION_NAME_SIZE_MAX];
char peerSessionName[SESSION_NAME_SIZE_MAX];
char peerDeviceId[DEVICE_ID_SIZE_MAX];
char groupId[GROUP_ID_SIZE_MAX];
} sessionNeed;
typedef struct {
ListNode node;
int32_t channelId;
int32_t businessType;
bool isEnable;
sessionNeed info;
} UdpChannel;
static SoftBusList *g_udpChannelMgr = NULL;
static IClientSessionCallBack *g_sessionCb = NULL;
@ -180,6 +163,9 @@ static void OnUdpChannelOpened(int32_t channelId)
case BUSINESS_TYPE_STREAM:
type = TYPE_STREAM;
break;
case BUSINESS_TYPE_FILE:
type = TYPE_FILE;
break;
default:
LOG_ERR("unsupport business type.");
return;
@ -205,6 +191,7 @@ static UdpChannel *ConvertChannelInfoToUdpChannel(const char *sessionName, const
}
newChannel->businessType = channel->businessType;
newChannel->channelId = channel->channelId;
newChannel->dfileId = -1;
newChannel->isEnable = false;
newChannel->info.isServer = channel->isServer;
newChannel->info.peerPid = channel->peerPid;
@ -246,9 +233,19 @@ int32_t TransOnUdpChannelOpened(const char *sessionName, const ChannelInfo *chan
ret = TransOnstreamChannelOpened(channel, udpPort);
if (ret != SOFTBUS_OK) {
(void)TransDeleteUdpChannel(newChannel->channelId);
LOG_ERR("on stream channel opened failed.");
LOG_ERR("on stream channel open failed.");
}
break;
case BUSINESS_TYPE_FILE:
ret = TransOnFileChannelOpened(channel, udpPort);
if (ret < SOFTBUS_OK) {
(void)TransDeleteUdpChannel(newChannel->channelId);
LOG_ERR("on file channel open failed.");
return SOFTBUS_ERR;
}
newChannel->dfileId = ret;
ret = SOFTBUS_OK;
break;
default:
LOG_ERR("unsupport businessType.");
break;
@ -289,6 +286,7 @@ static int32_t CloseUdpChannel(int32_t channelId, bool isActive)
if (ClosePeerUdpChannel(channelId) != SOFTBUS_OK) {
LOG_ERR("trans close peer udp channel failed.");
(void)TransCloseStreamChannel(channelId);
TransCloseFileChannel(channel.dfileId);
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
@ -300,6 +298,9 @@ static int32_t CloseUdpChannel(int32_t channelId, bool isActive)
return SOFTBUS_ERR;
}
break;
case BUSINESS_TYPE_FILE:
TransCloseFileChannel(channel.dfileId);
break;
default:
LOG_ERR("unsupport business type.");
return SOFTBUS_ERR;
@ -344,10 +345,15 @@ static void OnStreamReceived(int32_t channelId, const StreamData *data, const St
g_sessionCb->OnStreamReceived(channelId, CHANNEL_TYPE_UDP, data, ext, param);
}
static int32_t OnFileGetSessionId(int32_t channelId, int32_t *sessionId)
{
return g_sessionCb->OnGetSessionId(channelId, CHANNEL_TYPE_UDP, sessionId);
}
static UdpChannelMgrCb g_udpChannelCb = {
.OnUdpChannelOpened = OnUdpChannelOpened,
.OnUdpChannelClosed = OnUdpChannelClosed,
.OnFileReceived = NULL,
.OnFileGetSessionId = OnFileGetSessionId,
.OnMessageReceived = NULL,
.OnStreamReceived = OnStreamReceived,
};
@ -360,6 +366,8 @@ int32_t ClientTransUdpMgrInit(IClientSessionCallBack *callback)
}
g_sessionCb = callback;
RegisterStreamCb(&g_udpChannelCb);
TransFileInit();
RegisterFileCb(&g_udpChannelCb);
g_udpChannelMgr = CreateSoftBusList();
if (g_udpChannelMgr == NULL) {
LOG_ERR("create udp channel manager list failed.");
@ -375,6 +383,7 @@ void ClientTransUdpMgrDeinit(void)
return;
}
UnregisterStreamCb();
RegisterFileCb(NULL);
if (pthread_mutex_lock(&g_udpChannelMgr->lock) != 0) {
LOG_ERR("lock failed");
return;
@ -388,5 +397,48 @@ void ClientTransUdpMgrDeinit(void)
(void)pthread_mutex_unlock(&g_udpChannelMgr->lock);
DestroySoftBusList(g_udpChannelMgr);
g_udpChannelMgr = NULL;
TransFileDeinit();
LOG_INFO("trans udp channel manager deinit success.");
}
int32_t TransUdpChannelSendFile(int32_t channelId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt)
{
UdpChannel channel = {0};
if (TransGetUdpChannel(channelId, &channel) != SOFTBUS_OK) {
return SOFTBUS_ERR;
}
if (!channel.isEnable || channel.dfileId < 0) {
LOG_ERR("udp channel is not enable.");
return SOFTBUS_ERR;
}
return TransSendFile(channel.dfileId, sFileList, dFileList, fileCnt);
}
int32_t TransGetUdpChannelByFileId(int32_t dfileId, UdpChannel *udpChannel)
{
if (g_udpChannelMgr == NULL) {
LOG_ERR("udp channel manager hasn't initialized.");
return SOFTBUS_ERR;
}
if (pthread_mutex_lock(&(g_udpChannelMgr->lock)) != 0) {
LOG_ERR("lock failed");
return SOFTBUS_LOCK_ERR;
}
UdpChannel *channelNode = NULL;
LIST_FOR_EACH_ENTRY(channelNode, &(g_udpChannelMgr->list), UdpChannel, node) {
if (channelNode->dfileId == dfileId) {
if (memcpy_s(udpChannel, sizeof(UdpChannel), channelNode, sizeof(UdpChannel)) != EOK) {
LOG_ERR("memcpy_s failed.");
(void)pthread_mutex_unlock(&(g_udpChannelMgr->lock));
return SOFTBUS_MEM_ERR;
}
(void)pthread_mutex_unlock(&(g_udpChannelMgr->lock));
return SOFTBUS_OK;
}
}
(void)pthread_mutex_unlock(&(g_udpChannelMgr->lock));
return SOFTBUS_ERR;
}

View File

@ -14,6 +14,8 @@
*/
#include "client_trans_udp_manager.h"
#include "client_trans_file_listener.h"
#include "softbus_errcode.h"
int32_t ClientTransUdpMgrInit(IClientSessionCallBack *callback)
@ -56,4 +58,33 @@ int32_t TransUdpChannelSendStream(int32_t channelId, const StreamData *data, con
{
(void)channelId;
return SOFTBUS_FUNC_NOT_SUPPORT;
}
int32_t TransUdpChannelSendFile(int32_t channelId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt)
{
(void)channelId;
return SOFTBUS_FUNC_NOT_SUPPORT;
}
int32_t TransGetUdpChannelByFileId(int32_t dfileId, UdpChannel *udpChannel)
{
return SOFTBUS_FUNC_NOT_SUPPORT;
}
void TransDeleteFileListener(const char *sessionName) {}
int32_t TransSetFileReceiveListener(const char *sessionName,
const IFileReceiveListener *recvListener, const char *rootDir)
{
return SOFTBUS_FUNC_NOT_SUPPORT;
}
int32_t TransSetFileSendListener(const char *sessionName, const IFileSendListener *sendListener)
{
return SOFTBUS_FUNC_NOT_SUPPORT;
}
int32_t TransGetFileListener(const char *sessionName, FileListener *fileListener)
{
return SOFTBUS_FUNC_NOT_SUPPORT;
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef CLIENT_TRANS_FILE_H
#define CLIENT_TRANS_FILE_H
#include "client_trans_udp_manager.h"
#include "softbus_def.h"
#ifdef __cplusplus
extern "C" {
#endif
void RegisterFileCb(const UdpChannelMgrCb *fileCb);
int32_t TransOnFileChannelOpened(const ChannelInfo *channel, int32_t *filePort);
void TransCloseFileChannel(int32_t dfileId);
int32_t TransDeleteFileNode(int32_t channelId);
int32_t TransSendFile(int32_t channelId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt);
#ifdef __cplusplus
}
#endif
#endif // CLIENT_TRANS_FILE_H

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef CLIENT_TRANS_FILE_LISTENER_H
#define CLIENT_TRANS_FILE_LISTENER_H
#include "session.h"
#include "softbus_def.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
ListNode node;
char mySessionName[SESSION_NAME_SIZE_MAX];
IFileSendListener sendListener;
IFileReceiveListener recvListener;
char rootDir[FILE_RECV_ROOT_DIR_SIZE_MAX];
} FileListener;
int TransFileInit();
void TransFileDeinit();
int32_t TransSetFileReceiveListener(const char *sessionName,
const IFileReceiveListener *recvListener, const char *rootDir);
int32_t TransSetFileSendListener(const char *sessionName, const IFileSendListener *sendListener);
int32_t TransGetFileListener(const char *sessionName, FileListener *fileListener);
void TransDeleteFileListener(const char *sessionName);
#ifdef __cplusplus
}
#endif
#endif // CLIENT_TRANS_FILE_LISTENER_H

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef NSTACKX_DFILE_ADAPTER_H
#define NSTACKX_DFILE_ADAPTER_H
#include <stdint.h>
#include "session.h"
#include "nstackx_dfile.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t StartNStackXDFileServer(const char *myIp, const uint8_t *key,
uint32_t keyLen, DFileMsgReceiver msgReceiver, int32_t *filePort);
int32_t StartNStackXDFileClient(const char *peerIp, int32_t peerPort, const uint8_t *key,
uint32_t keyLen, DFileMsgReceiver msgReceiver);
#ifdef __cplusplus
}
#endif
#endif // NSTACKX_DFILE_ADAPTER_H

View File

@ -0,0 +1,218 @@
/*
* Copyright (c) 2021 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_file.h"
#include <securec.h>
#include "client_trans_file_listener.h"
#include "file_adapter.h"
#include "nstackx_dfile.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "softbus_mem_interface.h"
#include "softbus_utils.h"
#define DEFAULT_KEY_LENGTH 16
static const UdpChannelMgrCb *g_udpChannelMgrCb = NULL;
static const ChannelInfo *g_channel = NULL;
static void FileSendListener(const UdpChannel *udpChannel, DFileMsgType msgType, const DFileMsg *msgData)
{
FileListener fileListener = {0};
if (TransGetFileListener(udpChannel->info.peerSessionName, &fileListener) != SOFTBUS_OK) {
LOG_ERR("get file listener failed.");
return;
}
int32_t sessionId = -1;
if (g_udpChannelMgrCb->OnFileGetSessionId(udpChannel->channelId, &sessionId) != SOFTBUS_OK) {
LOG_ERR("get sessionId by channelId failed.");
return;
}
switch (msgType) {
case DFILE_ON_FILE_SEND_SUCCESS:
if (fileListener.sendListener.OnSendFileFinished != NULL) {
fileListener.sendListener.OnSendFileFinished(sessionId, msgData->fileList.files[0]);
}
break;
case DFILE_ON_FILE_SEND_FAIL:
if (fileListener.sendListener.OnFileTransError != NULL) {
fileListener.sendListener.OnFileTransError(sessionId);
}
break;
case DFILE_ON_TRANS_IN_PROGRESS:
if (fileListener.sendListener.OnSendFileProcess != NULL) {
uint64_t bytesUpload = msgData->transferUpdate.bytesTransferred;
uint64_t bytesTotal = msgData->transferUpdate.totalBytes;
fileListener.sendListener.OnSendFileProcess(sessionId, bytesUpload, bytesTotal);
}
break;
default:
break;
}
}
static void FileReceiveListener(const UdpChannel *udpChannel, DFileMsgType msgType, const DFileMsg *msgData)
{
FileListener fileListener = {0};
if (TransGetFileListener(udpChannel->info.peerSessionName, &fileListener) != SOFTBUS_OK) {
LOG_ERR("get file listener failed.");
return;
}
int32_t sessionId = -1;
if (g_udpChannelMgrCb->OnFileGetSessionId(udpChannel->channelId, &sessionId) != SOFTBUS_OK) {
LOG_ERR("get sessionId by channelId failed.");
return;
}
const char *firstFile = msgData->fileList.files[0];
uint32_t fileNum = msgData->fileList.fileNum;
switch (msgType) {
case DFILE_ON_FILE_LIST_RECEIVED:
if (fileListener.recvListener.OnReceiveFileStarted != NULL) {
fileListener.recvListener.OnReceiveFileStarted(sessionId, firstFile, fileNum);
}
break;
case DFILE_ON_FILE_RECEIVE_SUCCESS:
if (fileListener.recvListener.OnReceiveFileFinished != NULL) {
fileListener.recvListener.OnReceiveFileFinished(sessionId, firstFile, fileNum);
}
break;
case DFILE_ON_FILE_RECEIVE_FAIL:
if (fileListener.recvListener.OnFileTransError != NULL) {
fileListener.recvListener.OnFileTransError(sessionId);
}
break;
case DFILE_ON_TRANS_IN_PROGRESS:
if (fileListener.recvListener.OnReceiveFileProcess != NULL) {
uint64_t bytesUpload = msgData->transferUpdate.bytesTransferred;
uint64_t bytesTotal = msgData->transferUpdate.totalBytes;
fileListener.recvListener.OnReceiveFileProcess(sessionId, firstFile, bytesUpload, bytesTotal);
}
break;
default:
break;
}
}
static void DFileListener(int32_t dfileId, DFileMsgType msgType, const DFileMsg *msgData)
{
if (msgData == NULL) {
return;
}
UdpChannel udpChannel = {0};
if (TransGetUdpChannelByFileId(dfileId, &udpChannel) != SOFTBUS_OK) {
LOG_ERR("get udp channel by fileId failed.");
return;
}
bool isClient = false;
switch (msgType) {
case DFILE_ON_CONNECT_SUCCESS:
g_udpChannelMgrCb->OnUdpChannelOpened(udpChannel.channelId);
isClient = true;
break;
case DFILE_ON_FILE_LIST_RECEIVED:
case DFILE_ON_FILE_RECEIVE_SUCCESS:
case DFILE_ON_FILE_RECEIVE_FAIL:
FileReceiveListener(&udpChannel, msgType, msgData);
break;
case DFILE_ON_FILE_SEND_SUCCESS:
case DFILE_ON_FILE_SEND_FAIL:
FileSendListener(&udpChannel, msgType, msgData);
break;
case DFILE_ON_TRANS_IN_PROGRESS:
if (isClient) {
FileSendListener(&udpChannel, msgType, msgData);
} else {
FileReceiveListener(&udpChannel, msgType, msgData);
}
break;
default:
break;
}
}
int32_t TransOnFileChannelOpened(const ChannelInfo *channel, int32_t *filePort)
{
if (channel == NULL || filePort == NULL) {
LOG_ERR("invalid param.");
return SOFTBUS_INVALID_PARAM;
}
int32_t fileSession;
(void)NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_UDP_GSO | NSTACKX_CAPS_WLAN_CATAGORY, NSTACKX_WLAN_CAT_TCP);
if (channel->isServer) {
FileListener fileListener = {0};
if (TransGetFileListener(channel->peerSessionName, &fileListener) != SOFTBUS_OK) {
LOG_ERR("get file listener failed");
return SOFTBUS_ERR;
}
fileSession = StartNStackXDFileServer(channel->myIp, channel->sessionKey,
DEFAULT_KEY_LENGTH, DFileListener, filePort);
if (fileSession < 0) {
LOG_ERR("start file channel as server failed");
return SOFTBUS_ERR;
}
if (NSTACKX_DFileSetStoragePath(fileSession, fileListener.rootDir) != SOFTBUS_OK) {
LOG_ERR("set storage path failed");
return SOFTBUS_ERR;
}
g_udpChannelMgrCb->OnUdpChannelOpened(channel->channelId);
} else {
fileSession = StartNStackXDFileClient(channel->peerIp, channel->peerPort,
channel->sessionKey, DEFAULT_KEY_LENGTH, DFileListener);
if (fileSession < 0) {
LOG_ERR("start file channel as client failed");
return SOFTBUS_ERR;
}
}
return fileSession;
}
void TransCloseFileChannel(int32_t dfileId)
{
NSTACKX_DFileClose(dfileId);
UdpChannel udpChannel = {0};
if (TransGetUdpChannelByFileId(dfileId, &udpChannel) != SOFTBUS_OK) {
LOG_ERR("get udp channel by fileId failed.");
return;
}
g_udpChannelMgrCb->OnUdpChannelClosed(udpChannel.channelId);
}
void RegisterFileCb(const UdpChannelMgrCb *fileCb)
{
if (fileCb == NULL) {
g_udpChannelMgrCb = NULL;
return;
}
if (g_udpChannelMgrCb != NULL) {
return;
}
g_udpChannelMgrCb = fileCb;
}
int32_t TransSendFile(int32_t sessionId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt)
{
if (dFileList == NULL) {
return NSTACKX_DFileSendFiles(sessionId, sFileList, fileCnt, NULL);
}
return NSTACKX_DFileSendFilesWithRemotePath(sessionId, sFileList, dFileList, fileCnt, NULL);
}

View File

@ -0,0 +1,206 @@
/*
* Copyright (c) 2021 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_file_listener.h"
#include <securec.h>
#include "softbus_def.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "softbus_mem_interface.h"
#include "softbus_utils.h"
static SoftBusList *g_fileListener = NULL;
int TransFileInit()
{
if (g_fileListener != NULL) {
LOG_INFO("file listener has initialized.");
return SOFTBUS_OK;
}
g_fileListener = CreateSoftBusList();
if (g_fileListener == NULL) {
LOG_ERR("create file listener list failed.");
return SOFTBUS_MALLOC_ERR;
}
return SOFTBUS_OK;
}
void TransFileDeinit(void)
{
if (g_fileListener == NULL) {
return;
}
if (pthread_mutex_lock(&(g_fileListener->lock)) != 0) {
LOG_ERR("file listener deinit lock failed");
return;
}
FileListener *fileNode = NULL;
LIST_FOR_EACH_ENTRY(fileNode, &(g_fileListener->list), FileListener, node) {
ListDelete(&(fileNode->node));
SoftBusFree(fileNode);
}
(void)pthread_mutex_unlock(&(g_fileListener->lock));
DestroySoftBusList(g_fileListener);
g_fileListener = NULL;
}
int32_t TransSetFileReceiveListener(const char *sessionName,
const IFileReceiveListener *recvListener, const char *rootDir)
{
if (g_fileListener == NULL) {
LOG_ERR("file listener hasn't initialized.");
return SOFTBUS_ERR;
}
if (pthread_mutex_lock(&(g_fileListener->lock)) != 0) {
LOG_ERR("file receive listener lock failed");
return SOFTBUS_LOCK_ERR;
}
FileListener *fileNode = NULL;
bool exist = false;
LIST_FOR_EACH_ENTRY(fileNode, &(g_fileListener->list), FileListener, node) {
if (strcmp(fileNode->mySessionName, sessionName) == 0) {
exist = true;
break;
}
}
if (exist) {
if (strcpy_s(fileNode->rootDir, FILE_RECV_ROOT_DIR_SIZE_MAX, rootDir) != EOK ||
memcpy_s(&(fileNode->recvListener), sizeof(IFileReceiveListener),
recvListener, sizeof(IFileReceiveListener)) != EOK) {
(void)pthread_mutex_unlock(&(g_fileListener->lock));
LOG_ERR("update file receive listener failed");
return SOFTBUS_ERR;
}
(void)pthread_mutex_unlock(&(g_fileListener->lock));
LOG_INFO("update file receive listener success");
return SOFTBUS_OK;
}
fileNode = (FileListener *)SoftBusCalloc(sizeof(FileListener));
if (fileNode == NULL) {
(void)pthread_mutex_unlock(&(g_fileListener->lock));
LOG_ERR("file receive listener calloc failed");
return SOFTBUS_MALLOC_ERR;
}
if (strcpy_s(fileNode->mySessionName, SESSION_NAME_SIZE_MAX, sessionName) != EOK ||
strcpy_s(fileNode->rootDir, FILE_RECV_ROOT_DIR_SIZE_MAX, rootDir) != EOK ||
memcpy_s(&(fileNode->recvListener), sizeof(IFileReceiveListener),
recvListener, sizeof(IFileReceiveListener)) != EOK) {
LOG_ERR("file node copy failed.");
SoftBusFree(fileNode);
(void)pthread_mutex_unlock(&(g_fileListener->lock));
return SOFTBUS_ERR;
}
ListAdd(&(g_fileListener->list), &(fileNode->node));
(void)pthread_mutex_unlock(&(g_fileListener->lock));
return SOFTBUS_OK;
}
int32_t TransSetFileSendListener(const char *sessionName, const IFileSendListener *sendListener)
{
if (g_fileListener == NULL) {
LOG_ERR("file listener hasn't initialized.");
return SOFTBUS_ERR;
}
if (pthread_mutex_lock(&(g_fileListener->lock)) != 0) {
LOG_ERR("file send listener lock failed");
return SOFTBUS_LOCK_ERR;
}
FileListener *fileNode = NULL;
bool exist = false;
LIST_FOR_EACH_ENTRY(fileNode, &(g_fileListener->list), FileListener, node) {
if (strcmp(fileNode->mySessionName, sessionName) == 0) {
exist = true;
break;
}
}
if (exist) {
if (memcpy_s(&(fileNode->sendListener), sizeof(IFileSendListener),
sendListener, sizeof(IFileSendListener)) != EOK) {
(void)pthread_mutex_unlock(&(g_fileListener->lock));
LOG_ERR("update file send listener failed");
return SOFTBUS_ERR;
}
(void)pthread_mutex_unlock(&(g_fileListener->lock));
LOG_INFO("update file send listener success");
return SOFTBUS_OK;
}
fileNode = (FileListener *)SoftBusCalloc(sizeof(FileListener));
if (fileNode == NULL) {
(void)pthread_mutex_unlock(&(g_fileListener->lock));
LOG_ERR("file send listener calloc failed");
return SOFTBUS_MALLOC_ERR;
}
if (strcpy_s(fileNode->mySessionName, SESSION_NAME_SIZE_MAX, sessionName) != EOK ||
memcpy_s(&(fileNode->sendListener), sizeof(IFileSendListener),
sendListener, sizeof(IFileSendListener)) != EOK) {
LOG_ERR("file node copy failed.");
SoftBusFree(fileNode);
(void)pthread_mutex_unlock(&(g_fileListener->lock));
return SOFTBUS_ERR;
}
ListAdd(&(g_fileListener->list), &(fileNode->node));
(void)pthread_mutex_unlock(&(g_fileListener->lock));
return SOFTBUS_OK;
}
int32_t TransGetFileListener(const char *sessionName, FileListener *fileListener)
{
if (g_fileListener == NULL) {
LOG_ERR("file listener hasn't initialized.");
return SOFTBUS_ERR;
}
if (pthread_mutex_lock(&(g_fileListener->lock)) != 0) {
LOG_ERR("file get listener lock failed");
return SOFTBUS_LOCK_ERR;
}
FileListener *fileNode = NULL;
LIST_FOR_EACH_ENTRY(fileNode, &(g_fileListener->list), FileListener, node) {
if (strcmp(fileNode->mySessionName, sessionName) == 0) {
if (memcpy_s(fileListener, sizeof(FileListener), fileNode, sizeof(FileListener)) != EOK) {
LOG_ERR("memcpy_s failed.");
(void)pthread_mutex_unlock(&(g_fileListener->lock));
return SOFTBUS_ERR;
}
(void)pthread_mutex_unlock(&(g_fileListener->lock));
return SOFTBUS_OK;
}
}
(void)pthread_mutex_unlock(&(g_fileListener->lock));
return SOFTBUS_ERR;
}
void TransDeleteFileListener(const char *sessionName)
{
if (g_fileListener == NULL) {
LOG_ERR("file listener hasn't initialized.");
return;
}
if (pthread_mutex_lock(&(g_fileListener->lock)) != 0) {
LOG_ERR("file delete lock failed");
return;
}
FileListener *fileNode = NULL;
LIST_FOR_EACH_ENTRY(fileNode, &(g_fileListener->list), FileListener, node) {
if (strcmp(fileNode->mySessionName, sessionName) == 0) {
SoftBusFree(fileNode);
break;
}
}
(void)pthread_mutex_unlock(&(g_fileListener->lock));
}

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) 2021 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 "file_adapter.h"
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <securec.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "softbus_tcp_socket.h"
static int SetReuseAddr(int fd, int on)
{
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (rc != 0) {
LOG_ERR("set SO_REUSEADDR : %{public}s.", strerror(errno));
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
static int SetReusePort(int fd, int on)
{
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
if (rc != 0) {
LOG_ERR("set SO_REUSEPORT : %{public}s.", strerror(errno));
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
static int OpenTcpServer(const char *ip, int port)
{
struct sockaddr_in addr;
(void)memset_s(&addr, sizeof(addr), 0, sizeof(addr));
errno = 0;
int rc = inet_pton(AF_INET, ip, &addr.sin_addr);
if (rc <= 0) {
LOG_ERR("rc=%d:%s", rc, strerror(errno));
return SOFTBUS_ERR;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
errno = 0;
int fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
if (fd < 0) {
LOG_ERR("%s", strerror(errno));
return SOFTBUS_ERR;
}
(void)SetReuseAddr(fd, 1);
(void)SetReusePort(fd, 1);
errno = 0;
rc = TEMP_FAILURE_RETRY(bind(fd, (struct sockaddr *)&addr, sizeof(addr)));
if (rc < 0) {
LOG_ERR("rc=%d:%s", rc, strerror(errno));
TcpShutDown(fd);
return SOFTBUS_ERR;
}
return fd;
}
int32_t StartNStackXDFileServer(const char *myIP, const uint8_t *key,
uint32_t keyLen, DFileMsgReceiver msgReceiver, int32_t *filePort)
{
if (myIP == NULL) {
LOG_ERR("invalid param.");
return SOFTBUS_INVALID_PARAM;
}
int fd = OpenTcpServer(myIP, 0);
if (fd < 0) {
LOG_ERR("failed to start tcp server for getting port");
return SOFTBUS_ERR;
}
int port = GetTcpSockPort(fd);
if (port < 0) {
LOG_ERR("failed to get port from tcp socket");
TcpShutDown(fd);
return SOFTBUS_ERR;
}
*filePort = port;
struct sockaddr_in localAddr;
(void)memset_s(&localAddr, sizeof(localAddr), 0, sizeof(localAddr));
localAddr.sin_family = AF_INET;
localAddr.sin_port = port;
localAddr.sin_addr.s_addr = ntohl(inet_addr(myIP));
socklen_t addrLen = sizeof(struct sockaddr_in);
int sessionId = NSTACKX_DFileServer(&localAddr, addrLen, key, keyLen, msgReceiver);
TcpShutDown(fd);
if (sessionId < 0) {
LOG_ERR("failed to start dfile server.");
return SOFTBUS_ERR;
}
return sessionId;
}
int32_t StartNStackXDFileClient(const char *peerIp, int32_t peerPort, const uint8_t *key,
uint32_t keyLen, DFileMsgReceiver msgReceiver)
{
if (peerIp == NULL) {
LOG_ERR("invalid param.");
return SOFTBUS_INVALID_PARAM;
}
struct sockaddr_in localAddr;
(void)memset_s(&localAddr, sizeof(localAddr), 0, sizeof(localAddr));
localAddr.sin_family = AF_INET;
localAddr.sin_port = peerPort;
localAddr.sin_addr.s_addr = ntohl(inet_addr(peerIp));
socklen_t addrLen = sizeof(struct sockaddr_in);
int32_t sessionId = NSTACKX_DFileClient(&localAddr, addrLen, key, keyLen, msgReceiver);
if (sessionId < 0) {
LOG_ERR("failed to start dfile client");
return SOFTBUS_ERR;
}
return sessionId;
}