add br sendfile

Signed-off-by: zourongchun <zourongchun@huawei.com>
This commit is contained in:
zourongchun 2022-02-22 10:21:49 +08:00
parent 98182159b8
commit 34e13f843e
19 changed files with 1139 additions and 46 deletions

View File

@ -55,7 +55,8 @@ static bool g_isRegCb = false;
static void WrapperStateChangeCallback(const int transport, const int status)
{
LOG_INFO("WrapperStateChangeCallback");
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "WrapperStateChangeCallback, transport=%d, status=%d",
transport, status);
int listenerId;
int st = ConvertBtState(transport, (BtStatus)status);
for (listenerId = 0; listenerId < STATE_LISTENER_MAX_NUM; listenerId++) {
@ -67,8 +68,40 @@ static void WrapperStateChangeCallback(const int transport, const int status)
}
}
static void WrapperPairRequestedCallback(const BdAddr *bdAddr, int transport)
{
if (bdAddr == NULL) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "WrapperPairRequestedCallback addr is null");
return ;
}
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "WrapperStateChangeCallback, addr=%02X:%02X:***%02X, transport=%d\n",
bdAddr->addr[MAC_FIRST_INDEX], bdAddr->addr[MAC_ONE_INDEX], bdAddr->addr[MAC_FIVE_INDEX], transport);
if (PairRequestReply(bdAddr, transport, true) != true) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "PairRequestReply error");
}
}
static void WrapperPairConfirmedCallback(const BdAddr *bdAddr, int transport, int reqType, int number)
{
if (bdAddr == NULL) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "WrapperPairConfirmedCallback addr is null");
return ;
}
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO,
"WrapperPairConfirmedCallback, addr=%02X:%02X:***%02X, transport=%d, reqType:%d, number:%d\n",
bdAddr->addr[MAC_FIRST_INDEX], bdAddr->addr[MAC_ONE_INDEX], bdAddr->addr[MAC_FIVE_INDEX],
transport, reqType, number);
if (SetDevicePairingConfirmation(bdAddr, transport, true) != true) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "SetDevicePairingConfirmation error");
}
}
static BtGapCallBacks g_softbusGapCb = {
.stateChangeCallback = WrapperStateChangeCallback
.stateChangeCallback = WrapperStateChangeCallback,
.pairRequestedCallback = WrapperPairRequestedCallback,
.pairConfirmedCallback = WrapperPairConfirmedCallback
};
static int RegisterListenerCallback(void)

View File

@ -33,6 +33,10 @@ extern "C" {
#define BLE_DISABLE 0
#define BLE_ENABLE 1
#define MAC_FIRST_INDEX 0
#define MAC_ONE_INDEX 1
#define MAC_FIVE_INDEX 5
typedef enum {
SOFTBUS_BT_STATUS_SUCCESS = 0x00,
SOFTBUS_BT_STATUS_FAIL,

View File

@ -51,7 +51,7 @@ GetLaneByType g_linkLaneTable[LINK_TYPE_MAX + 1] = {
static bool IsSupportUdp(LnnLaneProperty prop)
{
if (prop == LNN_FILE_LANE || prop == LNN_STREAM_LANE) {
if (prop == LNN_STREAM_LANE) {
return true;
} else {
return false;
@ -112,7 +112,7 @@ int32_t LnnGetRightLane(const char *netWorkId, int32_t pid, LnnLaneProperty prop
static bool IsProxyPort(LnnLaneProperty prop, LnnLaneLinkType type)
{
if (prop == LNN_MESSAGE_LANE) {
if (prop == LNN_MESSAGE_LANE || prop == LNN_FILE_LANE) {
return true;
}
return false;

View File

@ -77,6 +77,11 @@ enum {
typedef enum {
TRANS_SESSION_BYTES = 0,
TRANS_SESSION_MESSAGE,
TRANS_SESSION_FILE_FIRST_FRAME = 3,
TRANS_SESSION_FILE_ONGOINE_FRAME,
TRANS_SESSION_FILE_LAST_FRAME,
TRANS_SESSION_FILE_ONLYONE_FRAME,
TRANS_SESSION_FILE_ALLFILE_SENT,
} SessionPktType;
typedef enum {

View File

@ -45,6 +45,7 @@ typedef enum {
SOFTBUS_TCP_DIRECTCHANNEL_TIMER_FUN,
SOFTBUS_UDP_CHANNEL_TIMER_FUN,
SOFTBUS_TIME_SYNC_TIMER_FUN,
SOFTBUS_PROXY_SENDFILE_TIMER_FUN,
SOFTBUS_MAX_TIMER_FUN_NUM
} SoftBusTimerFunEnum;

View File

@ -17,7 +17,7 @@
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "sys_mgr_client.h"
extern "C" int32_t IsValidPkgName(int32_t uid, const char *pkgName)
{

View File

@ -23,6 +23,7 @@
#include "softbus_adapter_mem.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "sys_mgr_client.h"
#include "system_ability_definition.h"
namespace {

View File

@ -36,7 +36,7 @@
#endif
#define CONN_RFCOM_SEND_MAX_LEN 990
#define CONN_BR_RECEIVE_MAX_LEN 10
#define CONN_BR_RECEIVE_MAX_LEN 20
#define CONN_TCP_MAX_LENGTH 3072
#define CONN_TCP_MAX_CONN_NUM 30
#define CONN_TCP_TIME_OUT 100

View File

@ -1157,13 +1157,15 @@ static void UpdateLocalBtMac(void)
static void StateChangedCallback(int32_t listenerId, int32_t status)
{
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "StateChanged id: %d, status: %d", listenerId, status);
g_brEnable = status;
LocalListenerInfo info;
info.type = CONNECT_BR;
if (status == SOFTBUS_BR_STATE_TURN_ON) {
g_brEnable = status;
UpdateLocalBtMac();
(void)StartLocalListening(&info);
} else if (status == SOFTBUS_BR_STATE_TURN_OFF) {
g_brEnable = status;
(void)StopLocalListening(&info);
}
}

View File

@ -48,6 +48,42 @@ static int32_t ReceivedHeadCheck(BrConnectionInfo *conn)
return SOFTBUS_OK;
}
static char *BrRecvDataParse(BrConnectionInfo *conn, int32_t *outLen)
{
if (ReceivedHeadCheck(conn) != SOFTBUS_OK) {
return NULL;
}
int32_t bufLen = conn->recvPos;
ConnPktHead *head = (ConnPktHead *)(conn->recvBuf);
int32_t packLen = head->len + sizeof(ConnPktHead);
if (bufLen < packLen) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "not a complete package, continue");
return NULL;
}
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "[BrTransRead] a complete package packLen: %d", packLen);
char *dataCopy = SoftBusMalloc(packLen);
if (dataCopy == NULL) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "[BrTransRead] SoftBusMalloc failed");
return NULL;
}
if (memcpy_s(dataCopy, packLen, conn->recvBuf, packLen) != EOK) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "[BrTransRead] memcpy_s failed");
SoftBusFree(dataCopy);
return NULL;
}
if (bufLen > packLen &&
memmove_s(conn->recvBuf, conn->recvSize, conn->recvBuf + packLen, bufLen - packLen) != EOK) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "[BrTransRead] memmove_s failed");
SoftBusFree(dataCopy);
return NULL;
}
conn->recvPos = bufLen - packLen;
*outLen = packLen;
return dataCopy;
}
int32_t BrTransReadOneFrame(uint32_t connectionId, const SppSocketDriver *sppDriver, int32_t clientId, char **outBuf)
{
BrConnectionInfo *conn = GetConnectionRef(connectionId);
@ -57,6 +93,13 @@ int32_t BrTransReadOneFrame(uint32_t connectionId, const SppSocketDriver *sppDri
int32_t recvLen;
int32_t bufLen;
while (1) {
int32_t packLen;
char *dataBuf = BrRecvDataParse(conn, &packLen);
if (dataBuf != NULL) {
*outBuf = dataBuf;
ReleaseConnectionRef(conn);
return packLen;
}
if (conn->recvSize - conn->recvPos > 0) {
recvLen = sppDriver->Read(clientId, conn->recvBuf + conn->recvPos, conn->recvSize - conn->recvPos);
if (recvLen == BR_READ_SOCKET_CLOSED) {
@ -70,35 +113,12 @@ int32_t BrTransReadOneFrame(uint32_t connectionId, const SppSocketDriver *sppDri
}
conn->recvPos += recvLen;
}
if (ReceivedHeadCheck(conn) != SOFTBUS_OK) {
continue;
dataBuf = BrRecvDataParse(conn, &packLen);
if (dataBuf != NULL) {
*outBuf = dataBuf;
ReleaseConnectionRef(conn);
return packLen;
}
bufLen = conn->recvPos;
ConnPktHead *head = (ConnPktHead *)(conn->recvBuf);
int32_t packLen = head->len + sizeof(ConnPktHead);
if (bufLen < packLen) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "not a complete package, continue");
continue;
}
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "[BrTransRead] a complete package packLen: %d", packLen);
char *dataCopy = SoftBusMalloc(packLen);
if (dataCopy == NULL || memcpy_s(dataCopy, packLen, conn->recvBuf, packLen) != EOK) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "[BrTransRead] memcpy_s failed");
SoftBusFree(dataCopy);
continue;
}
if (bufLen > packLen &&
memmove_s(conn->recvBuf, conn->recvSize, conn->recvBuf + packLen, bufLen - packLen) != EOK) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "[BrTransRead] memmove_s failed");
SoftBusFree(dataCopy);
continue;
}
conn->recvPos = bufLen - packLen;
*outBuf = dataCopy;
ReleaseConnectionRef(conn);
return packLen;
}
}
@ -195,7 +215,7 @@ char *BrPackRequestOrResponse(int32_t requestOrResponse, int32_t delta, int32_t
head.flag = 0;
head.len = strlen(data) + 1;
if (memcpy_s(buf, dataLen, (void *)&head, headSize)) {
if (memcpy_s(buf, dataLen, (void *)&head, headSize) != EOK) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "memcpy_s head error");
cJSON_free(data);
SoftBusFree(buf);

View File

@ -96,7 +96,7 @@ static AppInfo *GetAppInfo(const SessionParam *param)
if (TransGetUidAndPid(param->sessionName, &appInfo->myData.uid, &appInfo->myData.pid) != SOFTBUS_OK) {
goto EXIT_ERR;
}
if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, appInfo->myData.deviceId,
if (LnnGetLocalStrInfo(STRING_KEY_UUID, appInfo->myData.deviceId,
sizeof(appInfo->myData.deviceId)) != SOFTBUS_OK) {
goto EXIT_ERR;
}
@ -322,7 +322,7 @@ static AppInfo *GetAuthAppInfo(const char *mySessionName)
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "GetAuthAppInfo GetUidAndPid failed");
goto EXIT_ERR;
}
if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, appInfo->myData.deviceId,
if (LnnGetLocalStrInfo(STRING_KEY_UUID, appInfo->myData.deviceId,
sizeof(appInfo->myData.deviceId)) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "GetAuthAppInfo get deviceId failed");
goto EXIT_ERR;

View File

@ -1063,6 +1063,10 @@ int32_t TransProxyManagerInit(const IServerChannelCallBack *cb)
return SOFTBUS_ERR;
}
if (TransSliceManagerInit() != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Trans slice manager init failed");
}
if (SoftbusGetConfig(SOFTBUS_INT_AUTH_MAX_BYTES_LENGTH,
(unsigned char*)&g_authMaxByteBufSize, sizeof(g_authMaxByteBufSize)) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "get auth proxy channel max bytes length fail");
@ -1107,6 +1111,7 @@ int32_t TransProxyGetNameByChanId(int32_t chanId, char *pkgName, char *sessionNa
void TransProxyManagerDeinit(void)
{
TransSliceManagerDeInit();
(void)RegisterTimeoutCallback(SOFTBUS_PROXYCHANNEL_TIMER_FUN, NULL);
PendingDeinit(PENDING_TYPE_PROXY);
}

View File

@ -83,7 +83,7 @@ int32_t ProxyTypeToProxyIndex(ProxyPacketType packetType)
case PROXY_FLAG_BYTES:
return PROXY_CHANNEL_PRORITY_BYTES;
default:
return PROXY_CHANNEL_PRORITY_BYTES;
return PROXY_CHANNEL_PRORITY_FILE;
}
}
@ -94,6 +94,16 @@ ProxyPacketType SessionTypeToPacketType(SessionPktType sessionType)
return PROXY_FLAG_BYTES;
case TRANS_SESSION_MESSAGE:
return PROXY_FLAG_MESSAGE;
case TRANS_SESSION_FILE_FIRST_FRAME:
return PROXY_FILE_FIRST_FRAME;
case TRANS_SESSION_FILE_ONGOINE_FRAME:
return PROXY_FILE_ONGOINE_FRAME;
case TRANS_SESSION_FILE_LAST_FRAME:
return PROXY_FILE_LAST_FRAME;
case TRANS_SESSION_FILE_ONLYONE_FRAME:
return PROXY_FILE_ONLYONE_FRAME;
case TRANS_SESSION_FILE_ALLFILE_SENT:
return PROXY_FILE_ALLFILE_SENT;
default:
return PROXY_FLAG_BYTES;
}
@ -484,6 +494,28 @@ static void TransProxySendSessionAck(int32_t channelId, int32_t seq)
}
}
static SessionPktType PacketTypeToSessionType(ProxyPacketType pktType)
{
switch (pktType) {
case PROXY_FLAG_BYTES:
return TRANS_SESSION_BYTES;
case PROXY_FLAG_MESSAGE:
return TRANS_SESSION_MESSAGE;
case PROXY_FILE_FIRST_FRAME:
return TRANS_SESSION_FILE_FIRST_FRAME;
case PROXY_FILE_ONGOINE_FRAME:
return TRANS_SESSION_FILE_ONGOINE_FRAME;
case PROXY_FILE_LAST_FRAME:
return TRANS_SESSION_FILE_LAST_FRAME;
case PROXY_FILE_ONLYONE_FRAME:
return TRANS_SESSION_FILE_ONLYONE_FRAME;
case PROXY_FILE_ALLFILE_SENT:
return TRANS_SESSION_FILE_ALLFILE_SENT;
default:
return PROXY_FLAG_BYTES;
}
}
int32_t TransProxyNotifySession(const char *pkgName, int32_t channelId, ProxyPacketType flags, int32_t seq,
const char *data, uint32_t len)
{
@ -498,6 +530,12 @@ int32_t TransProxyNotifySession(const char *pkgName, int32_t channelId, ProxyPac
return NotifyClientMsgReceived(pkgName, channelId, data, len, TRANS_SESSION_MESSAGE);
case PROXY_FLAG_ACK:
return TransProxyProcSendMsgAck(channelId, data, len);
case PROXY_FILE_FIRST_FRAME:
case PROXY_FILE_ONGOINE_FRAME:
case PROXY_FILE_LAST_FRAME:
case PROXY_FILE_ONLYONE_FRAME:
case PROXY_FILE_ALLFILE_SENT:
return NotifyClientMsgReceived(pkgName, channelId, data, len, PacketTypeToSessionType(flags));
default:
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "invalid flags(%d)", flags);
return SOFTBUS_INVALID_PARAM;

View File

@ -113,12 +113,10 @@ int SendFile(int sessionId, const char *sFileList[], const char *dFileList[], ui
if (ClientGetChannelBySessionId(sessionId, &channelId, &type, &isEnable) != SOFTBUS_OK) {
return SOFTBUS_TRANS_INVALID_SESSION_ID;
}
if (type != CHANNEL_TYPE_UDP) {
return SOFTBUS_TRANS_INVALID_SESSION_ID;
}
if (isEnable != true) {
return SOFTBUS_TRANS_SESSION_OPENING;
}
return ClientTransChannelSendFile(channelId, sFileList, dFileList, fileCnt);
return ClientTransChannelSendFile(channelId, type, sFileList, dFileList, fileCnt);
}

View File

@ -17,6 +17,7 @@
#include <securec.h>
#include "client_trans_proxy_manager.h"
#include "client_trans_session_manager.h"
#include "softbus_adapter_mem.h"
#include "softbus_errcode.h"
@ -187,6 +188,41 @@ int32_t TransOnDataReceived(int32_t channelId, int32_t channelType,
listener.OnMessageReceived(sessionId, data, len);
}
break;
case TRANS_SESSION_FILE_FIRST_FRAME:
case TRANS_SESSION_FILE_ONGOINE_FRAME:
case TRANS_SESSION_FILE_LAST_FRAME:
case TRANS_SESSION_FILE_ONLYONE_FRAME:
case TRANS_SESSION_FILE_ALLFILE_SENT:
if (channelType == CHANNEL_TYPE_PROXY) {
char sessionName[SESSION_NAME_SIZE_MAX] = {0};
if (ClientGetSessionDataById(sessionId, sessionName, SESSION_NAME_SIZE_MAX, KEY_PEER_SESSION_NAME)
!= SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get peer session name failed");
return SOFTBUS_ERR;
}
FileListener fileListener;
memset_s(&fileListener, sizeof(fileListener), 0, sizeof(fileListener));
if (TransGetFileListener(sessionName, &fileListener) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get file listener failed");
return SOFTBUS_ERR;
}
if (type == TRANS_SESSION_FILE_ALLFILE_SENT) {
ret = ProcessFileListData(sessionId, fileListener, data, len);
if (ret != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "process filelist data failed");
return SOFTBUS_ERR;
}
} else {
ret = ProcessFileFrameData(sessionId, fileListener, data, len, type);
if (ret != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "process fileframe data failed");
return SOFTBUS_ERR;
}
}
}
break;
default:
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "unknown session type");
return SOFTBUS_ERR;

View File

@ -36,7 +36,7 @@ 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 StreamFrameInfo *param);
int32_t ClientTransChannelSendFile(int32_t channelId, const char *sFileList[],
int32_t ClientTransChannelSendFile(int32_t channelId, int32_t type, const char *sFileList[],
const char *dFileList[], uint32_t fileCnt);
void DeleteFileListener(const char *sessionName);

View File

@ -153,7 +153,22 @@ int32_t ClientTransChannelSendStream(int32_t channelId, int32_t type, const Stre
int32_t ClientTransChannelSendFile(int32_t channelId, const char *sFileList[],
const char *dFileList[], uint32_t fileCnt)
{
return TransUdpChannelSendFile(channelId, sFileList, dFileList, fileCnt);
int32_t ret = SOFTBUS_OK;
switch (type) {
case CHANNEL_TYPE_UDP : {
ret = TransUdpChannelSendFile(channelId, sFileList, dFileList, fileCnt);
break;
}
case CHANNEL_TYPE_PROXY : {
ret = TransProxyChannelSendFile(channelId, sFileList, dFileList, fileCnt);
break;
}
default : {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "unsupport channel type");
return SOFTBUS_ERR;
}
}
return ret;
}
void DeleteFileListener(const char *sessionName)

View File

@ -16,6 +16,7 @@
#ifndef CLIENT_TRANS_PROXY_CHANNEL_H
#define CLIENT_TRANS_PROXY_CHANNEL_H
#include "client_trans_file_listener.h"
#include "client_trans_session_callback.h"
#include "softbus_def.h"
@ -23,6 +24,66 @@
extern "C" {
#endif
#ifdef __linux__
#define MAX_FILE_NUM 1
#else
#define MAX_FILE_NUM 1
#endif
#define MAX_FILE_PATH_NAME_LEN (256)
//#define MAX_PATH_LEN 256
#define MAX_REMOTE_PATH_LEN (512)
#define FRAME_DATA_SEQ_OFFSET (4)
#define PROXY_MAX_PACKET_SIZE (1 * 1024)
#define MAX_FILE_SIZE (0x500000) /* 5M */
#define PATH_SEPARATOR '/'
#define DEFAULT_NEW_PATH_AUTHORITY (0750)
#define INVALID_NODE_INDEX (-1)
#define INVALID_FD (-1)
typedef struct {
uint32_t seqCount;
SoftBusMutex lock;
uint32_t seqLockInitFlag;
}SendFileInfo;
typedef struct {
uint8_t *buffer;
uint32_t bufferSize;
}FileListBuffer;
typedef struct {
int32_t frameType;
int32_t frameLength;
uint8_t *data;
} FileFrame;
typedef enum {
NODE_IDLE,
NODE_BUSY,
NODE_ERR,
} RecvFileNodeStatus;
typedef struct {
int32_t index;
uint32_t seq;
int32_t fileFd;
int32_t fileStatus;/*0: idle 1:busy*/
uint64_t fileOffset;
int32_t timeOut;
char filePath[MAX_REMOTE_PATH_LEN];
}SingleFileInfo;
typedef struct {
SoftBusMutex lock;
int32_t curIndex;
int32_t sessionId;
FileListener fileListener;
SingleFileInfo recvFileInfo[MAX_FILE_NUM];
}RecvFileInfo;
int32_t ClinetTransProxyInit(const IClientSessionCallBack *cb);
int32_t ClientTransProxyOnChannelOpened(const char *sessionName, const ChannelInfo *channel);
@ -40,6 +101,14 @@ int32_t TransProxyChannelSendBytes(int32_t channelId, const void *data, uint32_t
int32_t TransProxyChannelSendMessage(int32_t channelId, const void *data, uint32_t len);
int32_t TransProxyChannelSendFile(int32_t channelId, const char *sFileList[], const char *dFileList[],
uint32_t fileCnt);
int32_t ProcessFileFrameData(int32_t sessionId, FileListener fileListener, const char *data, int32_t len,
int32_t type);
int32_t ProcessFileListData(int32_t sessionId, FileListener fileListener, const char *data, int32_t len);
#ifdef __cplusplus
}
#endif

View File

@ -14,16 +14,40 @@
*/
#include "client_trans_proxy_manager.h"
#include "client_trans_session_manager.h"
#include <errno.h>
#include <fcntl.h>
#include <securec.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "client_trans_session_manager.h"
#include "client_trans_tcp_direct_message.h"
#include "softbus_adapter_mem.h"
#include "softbus_adapter_timer.h"
#include "softbus_conn_interface.h"
#include "softbus_errcode.h"
#include "softbus_feature_config.h"
#include "softbus_log.h"
#include "softbus_utils.h"
#include "trans_server_proxy.h"
static IClientSessionCallBack g_sessionCb;
static uint32_t g_authMaxByteBufSize;
static uint32_t g_authMaxMessageBufSize;
static SendFileInfo g_sendFileInfo = {
.seqCount = 0,
.seqLockInitFlag = false,
};
static RecvFileInfo g_recvFileInfo = {
//.lock
.curIndex = 0,
.sessionId = 0,
};
static void ProxyFileTransTimerProc(void);
int32_t ClinetTransProxyInit(const IClientSessionCallBack *cb)
{
@ -32,6 +56,11 @@ int32_t ClinetTransProxyInit(const IClientSessionCallBack *cb)
}
g_sessionCb = *cb;
if (RegisterTimeoutCallback(SOFTBUS_PROXY_SENDFILE_TIMER_FUN, ProxyFileTransTimerProc) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "register sendfile timer fail");
}
if (SoftbusGetConfig(SOFTBUS_INT_AUTH_MAX_BYTES_LENGTH,
(unsigned char*)&g_authMaxByteBufSize, sizeof(g_authMaxByteBufSize)) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "get auth proxy channel max bytes length fail");
@ -146,3 +175,840 @@ int32_t TransProxyChannelSendMessage(int32_t channelId, const void *data, uint32
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send msg: channelId=%d, ret=%d", channelId, ret);
return ret;
}
static int32_t GetIdleIndexNode(int32_t *index)
{
if (index == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "input index is null");
return SOFTBUS_ERR;
}
int32_t i;
for (i = 0; i < MAX_FILE_NUM; i ++) {
if (g_recvFileInfo.recvFileInfo[i].fileStatus == NODE_IDLE) {
*index = i;
return SOFTBUS_OK;
}
}
if (i == MAX_FILE_NUM) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "there is no idle node");
*index = INVALID_NODE_INDEX;
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
int32_t GetRecvFileInfoBySeq(uint32_t seq, SingleFileInfo *fileInfo)
{
if (fileInfo == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fd is null");
return SOFTBUS_ERR;
}
int32_t i;
for (i = 0; i < MAX_FILE_NUM; i ++) {
if (g_recvFileInfo.recvFileInfo[i].seq == seq) {
fileInfo->index = g_recvFileInfo.recvFileInfo[i].index;
fileInfo->seq = seq;
fileInfo->fileFd = g_recvFileInfo.recvFileInfo[i].fileFd;
fileInfo->fileStatus = g_recvFileInfo.recvFileInfo[i].fileStatus;
fileInfo->fileOffset = g_recvFileInfo.recvFileInfo[i].fileOffset;
memcpy_s(fileInfo->filePath, MAX_REMOTE_PATH_LEN, g_recvFileInfo.recvFileInfo[i].filePath,
MAX_REMOTE_PATH_LEN);
return SOFTBUS_OK;
}
}
if (i == MAX_FILE_NUM) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "there is no match seq to get");
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
int32_t RemoveFromRecvListBySeq(uint32_t seq)
{
int32_t i;
for (i = 0; i < MAX_FILE_NUM; i ++) {
if (g_recvFileInfo.recvFileInfo[i].seq == seq) {
g_recvFileInfo.curIndex = 0;
g_recvFileInfo.recvFileInfo[i].index = 0;
g_recvFileInfo.recvFileInfo[i].seq = 0;
g_recvFileInfo.recvFileInfo[i].fileFd = INVALID_FD;
g_recvFileInfo.recvFileInfo[i].fileStatus = NODE_IDLE;
g_recvFileInfo.recvFileInfo[i].fileOffset = 0;
g_recvFileInfo.recvFileInfo[i].timeOut = 0;
memset_s(g_recvFileInfo.recvFileInfo[i].filePath, MAX_REMOTE_PATH_LEN, 0, MAX_REMOTE_PATH_LEN);
memset_s(&g_recvFileInfo.fileListener, sizeof(FileListener), 0, sizeof(FileListener));
return SOFTBUS_OK;
}
}
if (i == MAX_FILE_NUM) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "there is no match seq ti clear");
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
int32_t PutToRecvList(int32_t fd, uint32_t seq, const char *destFilePath, FileListener fileListener,
int32_t sessionId)
{
if (destFilePath == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "destFilePath is null");
return SOFTBUS_ERR;
}
int index = 0;
if (GetIdleIndexNode(&index) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "GetIdleIndexNode fail");
return SOFTBUS_ERR;
}
g_recvFileInfo.sessionId = sessionId;
g_recvFileInfo.curIndex = index;
g_recvFileInfo.recvFileInfo[index].index = index;
g_recvFileInfo.recvFileInfo[index].seq = seq;
g_recvFileInfo.recvFileInfo[index].fileFd = fd;
g_recvFileInfo.recvFileInfo[index].fileStatus = NODE_BUSY;
g_recvFileInfo.recvFileInfo[index].fileOffset = 0;
g_recvFileInfo.recvFileInfo[index].timeOut = 0;
memcpy_s(g_recvFileInfo.recvFileInfo[index].filePath, MAX_REMOTE_PATH_LEN, destFilePath, MAX_REMOTE_PATH_LEN);
memcpy_s(&g_recvFileInfo.fileListener, sizeof(FileListener), &fileListener, sizeof(FileListener));
return SOFTBUS_OK;
}
int32_t UpdateRecvInfo(SingleFileInfo fileInfo)
{
int index = fileInfo.index;
if (index > MAX_FILE_NUM) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fileInfo.index is large than MAX_FILE_NUM");
return SOFTBUS_ERR;
}
g_recvFileInfo.sessionId = 0;
g_recvFileInfo.curIndex = index;
g_recvFileInfo.recvFileInfo[index].index = fileInfo.index;
g_recvFileInfo.recvFileInfo[index].seq = fileInfo.seq;
g_recvFileInfo.recvFileInfo[index].fileFd = fileInfo.fileFd;
g_recvFileInfo.recvFileInfo[index].fileStatus = fileInfo.fileStatus;
g_recvFileInfo.recvFileInfo[index].fileOffset = fileInfo.fileOffset;
g_recvFileInfo.recvFileInfo[index].timeOut = fileInfo.timeOut;
memcpy_s(g_recvFileInfo.recvFileInfo[index].filePath, MAX_REMOTE_PATH_LEN, fileInfo.filePath,
MAX_REMOTE_PATH_LEN);
return SOFTBUS_OK;
}
static bool IsValidFileString(const char *str[], uint32_t fileNum, size_t maxLen)
{
if (str == NULL || fileNum == 0) {
return false;
}
for (uint32_t i = 0; i < fileNum; i++) {
if (str[i] == NULL) {
return false;
}
size_t len = strlen(str[i]);
if (len == 0 || len > (maxLen - 1) {
return false;
}
}
return true;
}
static int32_t FrameIndexToType(uint64_t index, uint64_t frameNumber)
{
if (index == 0) {
return FILE_FIRST_FRAME;
}
if ((index == 1) && (frameNumber == 2)) {
return FILE_ONGOINE_FRAME;
}
if (index == (frameNumber - 1)) {
return FILE_LAST_FRAME;
}
return FILE_ONGOINE_FRAME;
}
static int32_t ProxyChannelSendFileStream(int32_t channelId, const char *data, uint32_t len, int32_t type)
{
#define FILE_RETRY_DELAY_TIME (100)
#define FILE_RETRY_COUNT (3)
int32_t retry = FILE_RETRY_COUNT;
int32_t ret;
while(retry) {
ret = ServerIpcSendMessage(channelId, CHANNEL_TYPE_PROXY, data, len, type);
if (ret == SOFTBUS_CONNECTION_ERR_SENDQUEUE_FULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "send queue full %d", ret);
SoftBusSleepMs(FILE_RETRY_DELAY_TIME);
retry--;
continue;
}
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send msg(%d): type=%d, ret=%d", channelId, type, ret);
return ret;
}
return ret;
}
static int32_t FrameTypeToSessionType(int32_t type)
{
switch (type) {
case FILE_FIRST_FRAME:
return TRANS_SESSION_FILE_FIRST_FRAME;
case FILE_ONGOINE_FRAME:
return TRANS_SESSION_FILE_ONGOINE_FRAME;
case FILE_LAST_FRAME:
return TRANS_SESSION_FILE_LAST_FRAME;
case FILE_ONLYONE_FRAME:
return TRANS_SESSION_FILE_ONLYONE_FRAME;
case FILE_ALLFILE_SENT:
return TRANS_SESSION_FILE_ALLFILE_SENT;
default:
return SOFTBUS_ERR;
}
}
static void ProxyFileTransTimerProc(void) {
#define FILE_TRANS_TIMEOUT (30)
if (SoftBusMutexLock(&g_recvFileInfo.lock) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock file timer failed");
return;
}
int32_t index = g_recvFileInfo.curIndex;
if (index >= MAX_FILE_NUM) {
SoftBusMutexUnlock(&g_recvFileInfo.lock);
return;
}
int32_t status = g_recvFileInfo.recvFileInfo[index].fileStatus;
int32_t timeOut = g_recvFileInfo.recvFileInfo[index].timeOut;
if (status == NODE_BUSY) {
if (timeOut >= FILE_TRANS_TIMEOUT) {
g_recvFileInfo.recvFileInfo[index].fileStatus = NODE_ERR;
g_recvFileInfo.recvFileInfo[index].timeOut = 0;
close(g_recvFileInfo.recvFileInfo[index].fileFd);
remove(g_recvFileInfo.recvFileInfo[index].filePath);
if (g_recvFileInfo.fileListener.recvListener.OnFileTransError != NULL) {
g_recvFileInfo.fileListener.recvListener.OnFileTransError(g_recvFileInfo.sessionId);
}
} else {
g_recvFileInfo.recvFileInfo[index].timeOut++;
}
}
SoftBusMutexUnlock(&g_recvFileInfo.lock);
return;
}
int32_t FileToFrameAndSendFile(int32_t channelId, const char *sourceFile,const char *destFile)
{
uint64_t fileSize = -1;
struct stat statbuff;
if (stat(sourceFile, &statbuff) < 0) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "stat file fail");
return SOFTBUS_FILE_ERR;
} else {
fileSize = statbuff.st_size;
}
if (fileSize > MAX_FILE_SIZE) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "file is too large");
return SOFTBUS_FILE_ERR;
};
int32_t fd = open(sourceFile, O_RDONLY);
if (fd < 0) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "open file fail");
return SOFTBUS_FILE_ERR;
}
uint32_t seq = channelId;
if (PROXY_MAX_PACKET_SIZE <= FRAME_DATA_SEQ_OFFSET) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "stat file fail");
return SOFTBUS_ERR;
}
uint64_t frameDataSize = PROXY_MAX_PACKET_SIZE - FRAME_DATA_SEQ_OFFSET;
uint64_t frameNum = fileSize / frameDataSize;
if ((fileSize % frameDataSize) != 0) {
frameNum ++;
}
// add 1 means reserve frame to send destFile string
frameNum ++;
FileFrame fileFrame;
uint8_t *buffer = (uint8_t *)SoftBusCalloc(PROXY_MAX_PACKET_SIZE);
if (buffer == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "malloc send file buffer failed");
return SOFTBUS_ERR;
}
uint64_t fileOffset = 0;
uint64_t remainedSendSize = fileSize;
for (uint64_t index = 0; index < frameNum; index ++) {
fileFrame.frameType = FrameIndexToType(index, frameNum);
fileFrame.data = buffer;
memcpy_s(fileFrame.data, FRAME_DATA_SEQ_OFFSET, (char *)&seq, FRAME_DATA_SEQ_OFFSET);
if (index == 0) {
uint32_t destFileNameSize = strlen(destFile) + 1;
memcpy_s(fileFrame.data + FRAME_DATA_SEQ_OFFSET, destFileNameSize, destFile, destFileNameSize);
fileFrame.frameLength = FRAME_DATA_SEQ_OFFSET + destFileNameSize;
} else {
int32_t len = 0;
uint64_t readLength = (remainedSendSize < frameDataSize) ? remainedSendSize : frameDataSize;
len = pread(fd, fileFrame.data + FRAME_DATA_SEQ_OFFSET, readLength, fileOffset);
if (len >= 0) {
fileOffset += readLength;
fileFrame.frameLength = readLength + FRAME_DATA_SEQ_OFFSET;
remainedSendSize -= readLength;
} else {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "pread src file failed");
SoftBusFree(fileFrame.data);
return SOFTBUS_ERR;
}
}
// send one frame
int32_t type = FrameTypeToSessionType(fileFrame.frameType);
if (type == SOFTBUS_ERR) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "Frame Type To Session Type fail %d", fileFrame.frameType);
SoftBusFree(fileFrame.data);
return SOFTBUS_ERR;
}
int32_t ret = ProxyChannelSendFileStream(channelId, (char *)fileFrame.data, fileFrame.frameLength, type);
if (ret != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "conn send buf fail %d", ret);
SoftBusFree(fileFrame.data);
return ret;
}
// clear data buffer
memset_s(fileFrame.data, PROXY_MAX_PACKET_SIZE, 0, PROXY_MAX_PACKET_SIZE);
SoftBusSleepMs(50);
}
SoftBusFree(fileFrame.data);
return SOFTBUS_OK;
}
char *GetDestFilePath(FileFrame fileFrame)
{
if (fileFrame.frameLength <= FRAME_DATA_SEQ_OFFSET) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "CreateFileFromFrame framelength less then offset");
return NULL;
}
int32_t filePathSize = fileFrame.frameLength - FRAME_DATA_SEQ_OFFSET;
if (filePathSize > MAX_REMOTE_PATH_LEN) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath is too long");
return NULL;
}
char *filePath = (char *)SoftBusCalloc(filePathSize);
if (filePath == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc filePath failed");
return NULL;
}
memcpy_s(filePath, filePathSize, fileFrame.data + FRAME_DATA_SEQ_OFFSET,
fileFrame.frameLength - FRAME_DATA_SEQ_OFFSET);
return filePath;
}
int32_t GetDestFileFrameSeq(FileFrame fileFrame, uint32_t *seq)
{
if (seq == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "seq is null");
return SOFTBUS_ERR;
}
if (fileFrame.frameLength <= FRAME_DATA_SEQ_OFFSET) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "CreateFileFromFrame framelength less then offset");
return SOFTBUS_ERR;
}
memcpy_s(seq, FRAME_DATA_SEQ_OFFSET, fileFrame.data, FRAME_DATA_SEQ_OFFSET);
return SOFTBUS_OK;
}
static bool IsPathValid(char *filePath)
{
if ((filePath == NULL) || (strlen(filePath) == 0) ||
(strlen(filePath) > (MAX_REMOTE_PATH_LEN - 1)) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath size is wrong");
return false;
}
if (filePath[strlen(filePath) - 1] == PATH_SEPARATOR) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath is end with '/' ");
return false;
}
return true;
}
int32_t CreateDestDir(char *filePath)
{
uint32_t len = (uint32_t)strlen(filePath);
int32_t ret;
char *tempPath = (char *)SoftBusCalloc(len + 1);
if (tempPath == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc tempPath failed");
return SOFTBUS_ERR;
}
for (uint32_t i = 0; i < len; i++) {
tempPath[i] = filePath[i];
if (tempPath[i] != PATH_SEPARATOR) {
continue;
}
if (access(tempPath, 0) == -1) {
ret = mkdir(tempPath, DEFAULT_NEW_PATH_AUTHORITY);
if (ret == -1 && errno != EEXIST) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "mkdir failed(%d)", errno);
SoftBusFree(tempPath);
return SOFTBUS_ERR;
}
}
}
SoftBusFree(tempPath);
return SOFTBUS_OK;
}
static char *CreateFullRecvPath(const char *filePath, const char *recvRootDir)
{
if ((filePath == NULL) || (recvRootDir == NULL)) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath is null or rootDir is null");
return NULL;
}
int32_t rootDirLength = strlen(recvRootDir);
int32_t filePathLength = strlen(filePath);
bool isNeedAddSep = true;
if (((filePathLength > 0) && (filePath[0] == PATH_SEPARATOR)) ||
((rootDirLength > 0) && (recvRootDir[rootDirLength - 1] == PATH_SEPARATOR))) {
isNeedAddSep = false;
}
int32_t destFullPathLength = (isNeedAddSep) ? (rootDirLength + sizeof('/') + filePathLength) :
(rootDirLength + filePathLength);
char *recvFullPath = SoftBusCalloc(destFullPathLength + 1);
if (recvFullPath == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "recvFullPath is null");
return NULL;
}
int32_t ret;
if (isNeedAddSep) {
ret = sprintf_s(recvFullPath, destFullPathLength + 1, "%s%c%s", recvRootDir, PATH_SEPARATOR, filePath);
} else {
ret = sprintf_s(recvFullPath, destFullPathLength + 1, "%s%s", recvRootDir, filePath);
}
if (ret == -1) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "create fullPath fail");
SoftBusFree(recvFullPath);
return NULL;
}
return recvFullPath;
}
int32_t CreateFileFromFrame(int32_t sessionId, FileFrame fileFrame, FileListener fileListener)
{
if (SoftBusMutexLock(g_recvFileInfo.lock) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock fileFromFrame fail");
return SOFTBUS_ERR;
}
uint32_t seq = 0;
if (GetDestFileFrameSeq(fileFrame, &seq) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "open destFile fail");
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
char *destFilePath = GetDestFilePath(fileFrame);
if (destFilePath == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "GetDestFilePath failed");
SoftBusFree(destFilePath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
char *fullRecvPath = CreateFullRecvPath(destFilePath, fileListener.rootDir);
if (IsPathValid(fullRecvPath) == false) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "destFilePath is invalid");
SoftBusFree(destFilePath);
SoftBusFree(fullRecvPath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
if (CreateDestDir(fullRecvPath) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "CreateDestFile failed");
SoftBusFree(destFilePath);
SoftBusFree(fullRecvPath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
int32_t fd = open(fullRecvPath, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fd < 0) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "open destFile fail");
SoftBusFree(destFilePath);
SoftBusFree(fullRecvPath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
if (PutToRecvList(fd, seq, fullRecvPath, fileListener, sessionId) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "PutToRecvList failed");
SoftBusFree(destFilePath);
SoftBusFree(fullRecvPath);
close(fd);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
if (fileListener.recvListener.OnReceiveFileStarted != NULL) {
fileListener.recvListener.OnReceiveFileStarted(sessionId, fullRecvPath, 1);
}
SoftBusFree(destFilePath);
SoftBusFree(fullRecvPath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_OK;
}
int32_t WriteFrameToFile(FileFrame fileFrame)
{
if (SoftBusMutexLock(g_recvFileInfo.lock) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock write frame fail");
return SOFTBUS_ERR;
}
uint32_t seq = 0;
if (GetDestFileFrameSeq(fileFrame, &seq) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "open destFile fail");
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
SingleFileInfo fileInfo = {0};
if (GetRecvFileInfoBySeq(seq, &fileInfo) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "GetFileFdBySeq fail");
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
if (fileInfo.fileStatus == NODE_ERR) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fileStatus is error");
close(fileInfo.fileFd);
remove(fileInfo.filePath);
if (RemoveFromRecvListBySeq(seq) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "Clear RecvFileInfo fail");
}
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
int32_t frameLength = fileFrame.frameLength;
if (fileFrame.frameLength <= FRAME_DATA_SEQ_OFFSET) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "WriteFrameToFile framelength less then offset");
close(fileInfo.fileFd);
remove(fileInfo.filePath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
int32_t frameDataLength = frameLength - FRAME_DATA_SEQ_OFFSET;
int32_t wirteLength = pwrite(fileInfo.fileFd, fileFrame.data + FRAME_DATA_SEQ_OFFSET, frameDataLength,
(uint64_t)fileInfo.fileOffset);
if (wirteLength < 0) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "pwrite file failed");
close(fileInfo.fileFd);
remove(fileInfo.filePath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
fileInfo.fileOffset += wirteLength;
if (fileInfo.fileOffset > MAX_FILE_SIZE) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "file is too large");
close(fileInfo.fileFd);
remove(fileInfo.filePath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
if (UpdateRecvInfo(fileInfo) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "UpdateRecvInfo fail");
close(fileInfo.fileFd);
remove(fileInfo.filePath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
int32_t frameType = fileFrame.frameType;
// last frame
if ((frameType == FILE_LAST_FRAME) || (frameType == FILE_ONLYONE_FRAME)) {
close(fileInfo.fileFd);
if (RemoveFromRecvListBySeq(seq) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ClearRecvFileInfoBySeq fail");
remove(fileInfo.filePath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
}
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_OK;
}
int32_t ProcessFileFrameData(int32_t sessionId, FileListener fileListener, const char *data, int32_t len,
int32_t type)
{
int32_t ret;
FileFrame oneFrame;
oneFrame.frameType = type;
oneFrame.frameLength = len;
oneFrame.data = (uint8_t *)data;
switch (oneFrame.frameType) {
case FILE_FIRST_FRAME : {
ret = CreateFileFromFrame(sessionId, oneFrame, fileListener);
if (ret != SOFTBUS_OK) {
if (fileListener.recvListener.OnFileTransError != NULL) {
fileListener.recvListener.OnFileTransError(sessionId);
}
}
break;
}
case FILE_ONGOINE_FRAME :
case FILE_ONLYONE_FRAME :
case FILE_LAST_FRAME : {
ret = WriteFrameToFile(oneFrame);
if (ret != SOFTBUS_OK) {
if (fileListener.recvListener.OnFileTransError != NULL) {
fileListener.recvListener.OnFileTransError(sessionId);
}
}
break;
}
default : {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "frame type is invalid");
return SOFTBUS_ERR;
}
}
return ret;
}
static int32_t FileListToBuffer(const char **destFile, uint32_t fileCnt, FileListBuffer *outbufferInfo)
{
if (outbufferInfo == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "outbufferInfo is NULL");
return SOFTBUS_ERR;
}
outbufferInfo->buffer = NULL;
outbufferInfo->bufferSize = 0;
uint8_t *buffer = NULL;
int32_t totalLength = 0;
int32_t offset = 0;
uint32_t index;
for (index = 0; index < fileCnt; index++) {
totalLength += strlen(destFile[index]);
}
int32_t fileNameSize = 0;
int32_t indexSize = sizeof(index);
int32_t bufferSize = totalLength + (indexSize + sizeof(fileNameSize)) * fileCnt;
buffer = (uint8_t *)SoftBusCalloc(bufferSize);
if (buffer == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc filelist failed");
return SOFTBUS_ERR;
}
for (index = 0; index < fileCnt; index++) {
memcpy_s(buffer + offset, indexSize, &index, indexSize);
offset += indexSize;
fileNameSize = strlen(destFile[index]) + 1;
memcpy_s(buffer + offset, sizeof(fileNameSize), &fileNameSize, sizeof(fileNameSize));
offset += sizeof(fileNameSize);
memcpy_s(buffer + offset, fileNameSize, destFile[index], fileNameSize);
offset += fileNameSize;
}
outbufferInfo->buffer = buffer;
outbufferInfo->bufferSize = offset;
return SOFTBUS_OK;
}
int32_t BufferToFileList(FileListBuffer bufferInfo, char *firstFile, int32_t *fileCount)
{
if ((bufferInfo.buffer == NULL) || (firstFile == NULL) || (fileCount == NULL)) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "BufferToFileList input invalid");
return SOFTBUS_ERR;
}
*fileCount = 0;
uint8_t *buffer = bufferInfo.buffer;
uint32_t offset = 0;
int32_t count = 0;
int32_t fileNameLength = 0;
//uint32_t index = 0;
//uint32_t indexSize = sizeof(index);
while (offset < bufferInfo.bufferSize) {
//memcpy_s(&index, indexSize, buffer + offset, indexSize);
offset += sizeof(uint32_t);
memcpy_s(&fileNameLength, sizeof(fileNameLength), buffer + offset, sizeof(fileNameLength));
offset += sizeof(fileNameLength);
if ((fileNameLength < 0) || (fileNameLength > (int32_t)(bufferInfo.bufferSize - offset))) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "BufferToFileList invalid fileLength");
return SOFTBUS_ERR;
}
/* only output first file path */
if (count == 0) {
memcpy_s(firstFile, fileNameLength, buffer + offset, fileNameLength);
}
offset += fileNameLength;
count ++;
}
*fileCount = count;
return SOFTBUS_OK;
}
int32_t ProcessFileListData(int32_t sessionId, FileListener fileListener, const char *data, int32_t len)
{
if (SoftBusMutexLock(g_recvFileInfo.lock) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock filelist data fail");
return SOFTBUS_ERR;
}
FileListBuffer bufferInfo;
char firtFilePath[MAX_REMOTE_PATH_LEN];
int32_t fileCount = 0;
bufferInfo.buffer = (uint8_t *)data;
bufferInfo.bufferSize = (uint32_t)len;
int32_t ret = BufferToFileList(bufferInfo, firtFilePath, &fileCount);
if (ret != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "Buffer To File List failed");
SoftBusMutexUnlock(g_recvFileInfo.lock)
return SOFTBUS_ERR;
}
char *fullRecvPath = CreateFullRecvPath(firtFilePath, fileListener.rootDir);
if (IsPathValid(fullRecvPath) == false) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fullRecvPath is invalid");
SoftBusFree(fullRecvPath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_ERR;
}
if (fileListener.recvListener.OnReceiveFileFinished != NULL) {
fileListener.recvListener.OnReceiveFileFinished(sessionId, fullRecvPath, fileCount);
}
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "Process File List Data success!!!");
SoftBusFree(fullRecvPath);
SoftBusMutexUnlock(g_recvFileInfo.lock);
return SOFTBUS_OK;
}
int32_t SendFileList(int32_t channelId, const char **destFile, uint32_t fileCnt)
{
FileListBuffer bufferInfo;
int32_t ret = FileListToBuffer(destFile, fileCnt, &bufferInfo);
if (ret != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "FileListToBuffer failed");
SoftBusFree(bufferInfo.buffer);
return SOFTBUS_ERR;
}
// send file list
int32_t type = TRANS_SESSION_FILE_ALLFILE_SENT;
int32_t ret = ProxyChannelSendFileStream(channelId, (char *)bufferInfo.buffer, bufferInfo.bufferSize, type);
if (ret < 0) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "conn send buf fail %d", ret);
SoftBusFree(bufferInfo.buffer);
return ret;
}
// 执行回调函数
SoftBusFree(bufferInfo.buffer);
return SOFTBUS_OK;
}
int32_t SendSingleFile(int32_t channelId, const char *sourceFile,const char *destFile)
{
if ((sourceFile == NULL) || (destFile == NULL)) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sourfile or dstfile is null");
return SOFTBUS_ERR;
}
int32_t ret;
ret = FileToFrameAndSendFile(channelId, sourceFile, destFile);
if (ret != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "FileToFrameAndSendFile failed");
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
static int32_t ProxySendFile(int32_t channelId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt)
{
if (g_sendFileInfo.seqLockInitFlag == false) {
if (SoftBusMutexInit(&g_sendFileInfo.lock, NULL) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "mutex init fail!");
return SOFTBUS_ERR;
}
g_sendFileInfo.seqLockInitFlag = true;
}
if (SoftBusMutexLock(&g_sendFileInfo.lock) != 0) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock mutex failed");
return SOFTBUS_ERR;
}
int ret = SOFTBUS_ERR;
if ((fileCnt == 0 ) || (fileCnt > MAX_FILE_NUM)) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sendfile arg filecnt[%d] error", fileCnt);
SoftBusMutexUnlock(&g_sendFileInfo.lock);
return SOFTBUS_ERR;
}
if (!IsValidFileString(sFileList, fileCnt, MAX_FILE_PATH_NAME_LEN) ||
!IsValidFileString(dFileList, fileCnt, MAX_REMOTE_PATH_LEN)) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sendfile invalid arg input");
SoftBusMutexUnlock(&g_sendFileInfo.lock);
return SOFTBUS_ERR;
}
for (uint32_t index = 0; index < fileCnt; index++) {
ret = SendSingleFile(channelId, sFileList[index], dFileList[index]);
if (ret != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "SendSingleFile fileindex[%d], failed", index);
SoftBusMutexUnlock(&g_sendFileInfo.lock);
return SOFTBUS_ERR;
}
}
ret = SendFileList(channelId, dFileList, fileCnt);
//ret = SendFileListDemo(channelId, dFileList, fileCnt);
if (ret != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "SendFileList failed");
SoftBusMutexUnlock(&g_sendFileInfo.lock);
return SOFTBUS_ERR;
}
SoftBusMutexUnlock(&g_sendFileInfo.lock);
return SOFTBUS_OK;
}
int32_t TransProxyChannelSendFile(int32_t channelId, const char *sFileList[], const char *dFileList[],
uint32_t fileCnt)
{
return ProxySendFile(channelId, sFileList, dFileList, fileCnt);
}