• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "client_trans_proxy_manager.h"
17 
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <limits.h>
21 #include <securec.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 #include "client_trans_session_manager.h"
27 #include "client_trans_tcp_direct_message.h"
28 #include "softbus_adapter_mem.h"
29 #include "softbus_adapter_timer.h"
30 #include "softbus_conn_interface.h"
31 #include "softbus_errcode.h"
32 #include "softbus_feature_config.h"
33 #include "softbus_log.h"
34 #include "softbus_utils.h"
35 #include "trans_server_proxy.h"
36 
37 static IClientSessionCallBack g_sessionCb;
38 static uint32_t g_authMaxByteBufSize;
39 static uint32_t g_authMaxMessageBufSize;
40 static SendFileInfo g_sendFileInfo = {
41     .seqCount = 0,
42     .seqLockInitFlag = false,
43 };
44 
45 static RecvFileInfo g_recvFileInfo = {
46     .sessionId = 0,
47 };
48 
49 static void ProxyFileTransTimerProc(void);
50 
51 #define BYTE_INT_NUM 4
52 #define BIT_INT_NUM 32
53 #define BIT_BYTE_NUM 8
54 #define SEND_DELAY_TIME 20
55 
ClinetTransProxyInit(const IClientSessionCallBack * cb)56 int32_t ClinetTransProxyInit(const IClientSessionCallBack *cb)
57 {
58     if (cb == NULL) {
59         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ClinetTransProxyInit cb param is null!");
60         return SOFTBUS_INVALID_PARAM;
61     }
62 
63     g_sessionCb = *cb;
64     if (g_sendFileInfo.seqLockInitFlag == false) {
65         if (SoftBusMutexInit(&g_sendFileInfo.lock, NULL) != SOFTBUS_OK) {
66             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sendfile mutex init fail!");
67             return SOFTBUS_ERR;
68         }
69         g_sendFileInfo.seqLockInitFlag = true;
70     }
71 
72     if (SoftBusMutexInit(&g_recvFileInfo.lock, NULL) != SOFTBUS_OK) {
73         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "recvfile mutex init fail!");
74         return SOFTBUS_ERR;
75     }
76 
77     if (RegisterTimeoutCallback(SOFTBUS_PROXY_SENDFILE_TIMER_FUN, ProxyFileTransTimerProc) != SOFTBUS_OK) {
78         SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "register sendfile timer fail");
79     }
80 
81     if (SoftbusGetConfig(SOFTBUS_INT_AUTH_MAX_BYTES_LENGTH,
82         (unsigned char*)&g_authMaxByteBufSize, sizeof(g_authMaxByteBufSize)) != SOFTBUS_OK) {
83         SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "get auth proxy channel max bytes length fail");
84     }
85     if (SoftbusGetConfig(SOFTBUS_INT_AUTH_MAX_MESSAGE_LENGTH,
86         (unsigned char*)&g_authMaxMessageBufSize, sizeof(g_authMaxMessageBufSize)) != SOFTBUS_OK) {
87         SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "get auth proxy channel max message length fail");
88     }
89     SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "proxy auth byteSize[%u], messageSize[%u]",
90         g_authMaxByteBufSize, g_authMaxMessageBufSize);
91     return SOFTBUS_OK;
92 }
93 
ClientTransProxyDeinit(void)94 void ClientTransProxyDeinit(void)
95 {
96     if (SoftBusMutexDestroy(&g_sendFileInfo.lock) != SOFTBUS_OK) {
97         SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "destroy send file lock fail");
98         return;
99     }
100     if (SoftBusMutexDestroy(&g_recvFileInfo.lock) != SOFTBUS_OK) {
101         SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "destroy recv file lock fail");
102         return;
103     }
104 }
105 
ClientTransProxyOnChannelOpened(const char * sessionName,const ChannelInfo * channel)106 int32_t ClientTransProxyOnChannelOpened(const char *sessionName, const ChannelInfo *channel)
107 {
108     if (sessionName == NULL || channel == NULL) {
109         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ClientTransProxyOnChannelOpened invalid param.");
110         return SOFTBUS_INVALID_PARAM;
111     }
112 
113     int ret = g_sessionCb.OnSessionOpened(sessionName, channel, TYPE_MESSAGE);
114     if (ret != SOFTBUS_OK) {
115         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "notify session open fail, sessionName=[%s].", sessionName);
116         return ret;
117     }
118 
119     return SOFTBUS_OK;
120 }
121 
ClientTransProxyOnChannelClosed(int32_t channelId)122 int32_t ClientTransProxyOnChannelClosed(int32_t channelId)
123 {
124     int ret = g_sessionCb.OnSessionClosed(channelId, CHANNEL_TYPE_PROXY);
125     if (ret != SOFTBUS_OK) {
126         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "notify session closed err[%d], cId[%d].", ret, channelId);
127         return ret;
128     }
129     return SOFTBUS_OK;
130 }
131 
ClientTransProxyOnChannelOpenFailed(int32_t channelId)132 int32_t ClientTransProxyOnChannelOpenFailed(int32_t channelId)
133 {
134     int ret = g_sessionCb.OnSessionOpenFailed(channelId, CHANNEL_TYPE_PROXY);
135     if (ret != SOFTBUS_OK) {
136         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "notify session openfail cId[%d].", channelId);
137         return ret;
138     }
139 
140     return SOFTBUS_OK;
141 }
142 
ClientTransProxyOnDataReceived(int32_t channelId,const void * data,uint32_t len,SessionPktType type)143 int32_t ClientTransProxyOnDataReceived(int32_t channelId,
144     const void *data, uint32_t len, SessionPktType type)
145 {
146     if (data == NULL) {
147         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR,
148             "ClientTransProxyOnDataReceived cId[%d] data null.", channelId);
149         return SOFTBUS_INVALID_PARAM;
150     }
151     int ret = g_sessionCb.OnDataReceived(channelId, CHANNEL_TYPE_PROXY, data, len, type);
152     if (ret != SOFTBUS_OK) {
153         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "notify data recv err, cId[%d].", channelId);
154         return ret;
155     }
156     return SOFTBUS_OK;
157 }
158 
ClientTransProxyCloseChannel(int32_t channelId)159 void ClientTransProxyCloseChannel(int32_t channelId)
160 {
161     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "TransCloseProxyChannel, channelId [%d]", channelId);
162     if (ServerIpcCloseChannel(channelId, CHANNEL_TYPE_PROXY) != SOFTBUS_OK) {
163         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "server close channel[%d] err.", channelId);
164     }
165 }
166 
TransProxyChannelSendBytes(int32_t channelId,const void * data,uint32_t len)167 int32_t TransProxyChannelSendBytes(int32_t channelId, const void *data, uint32_t len)
168 {
169 #define PROXY_MAX_BYTES_LEN (4 * 1024)
170     int32_t encryp = 0;
171     int32_t ret = GetEncryptByChannelId(channelId, CHANNEL_TYPE_PROXY, &encryp);
172     if (ret != SOFTBUS_OK) {
173         return SOFTBUS_ERR;
174     }
175     if (encryp == 1) {
176         if (len > PROXY_MAX_BYTES_LEN) {
177             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
178         }
179     } else {
180         if (len > g_authMaxByteBufSize) {
181             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
182         }
183     }
184     ret = ServerIpcSendMessage(channelId, CHANNEL_TYPE_PROXY, data, len, TRANS_SESSION_BYTES);
185     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send bytes: channelId=%d, ret=%d", channelId, ret);
186     return ret;
187 }
188 
TransProxyChannelSendMessage(int32_t channelId,const void * data,uint32_t len)189 int32_t TransProxyChannelSendMessage(int32_t channelId, const void *data, uint32_t len)
190 {
191 #define PROXY_MAX_MESSAGE_LEN (1 * 1024)
192     int32_t encryp = 0;
193     int32_t ret = GetEncryptByChannelId(channelId, CHANNEL_TYPE_PROXY, &encryp);
194     if (ret != SOFTBUS_OK) {
195         return SOFTBUS_ERR;
196     }
197     if (encryp == 1) {
198         if (len > PROXY_MAX_MESSAGE_LEN) {
199             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
200         }
201     } else {
202         if (len > g_authMaxMessageBufSize) {
203             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
204         }
205     }
206     ret = ServerIpcSendMessage(channelId, CHANNEL_TYPE_PROXY, data, len, TRANS_SESSION_MESSAGE);
207     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send msg: channelId=%d, ret=%d", channelId, ret);
208     return ret;
209 }
210 
IntToByte(uint32_t value,char * buffer,uint32_t len)211 static bool IntToByte(uint32_t value, char *buffer, uint32_t len)
212 {
213     if ((buffer == NULL) || (len < sizeof(uint32_t))) {
214         return false;
215     }
216 
217     for (uint32_t i = 0; i < BYTE_INT_NUM; i++) {
218         uint32_t offset = BIT_INT_NUM - (i + 1) * BIT_BYTE_NUM;
219         buffer[i] = (char)((value >> offset) & 0xFF);
220     }
221     return true;
222 }
223 
ByteToInt(char * buffer,uint32_t len,uint32_t * outValue)224 static bool ByteToInt(char *buffer, uint32_t len, uint32_t *outValue)
225 {
226     if ((outValue == NULL) || (buffer == NULL) || (len < sizeof(uint32_t))) {
227         return false;
228     }
229     uint32_t value = 0;
230     for (int32_t i = 0; i < BYTE_INT_NUM; i++) {
231         value <<= BIT_BYTE_NUM;
232         value |= buffer[i] & 0xFF;
233     }
234 
235     *outValue = value;
236     return true;
237 }
238 
GetIdleIndexNode(int32_t * index)239 static int32_t GetIdleIndexNode(int32_t *index)
240 {
241     if (index == NULL) {
242         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "input index is null");
243         return SOFTBUS_ERR;
244     }
245     int32_t i;
246     for (i = 0; i < MAX_RECV_FILE_NUM; i++) {
247         if (g_recvFileInfo.recvFileInfo[i].fileStatus == NODE_IDLE) {
248             *index = i;
249             return SOFTBUS_OK;
250         }
251     }
252 
253     if (i == MAX_RECV_FILE_NUM) {
254         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "there is no idle node");
255         *index = INVALID_NODE_INDEX;
256         return SOFTBUS_ERR;
257     }
258 
259     return SOFTBUS_OK;
260 }
261 
GetRecvFileInfoBySeq(uint32_t seq,SingleFileInfo * fileInfo)262 static int32_t GetRecvFileInfoBySeq(uint32_t seq, SingleFileInfo *fileInfo)
263 {
264     if (fileInfo == NULL) {
265         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fd is null");
266         return SOFTBUS_ERR;
267     }
268 
269     int32_t i;
270     for (i = 0; i < MAX_RECV_FILE_NUM; i++) {
271         if (g_recvFileInfo.recvFileInfo[i].seq == seq) {
272             fileInfo->index = g_recvFileInfo.recvFileInfo[i].index;
273             fileInfo->seq = seq;
274             fileInfo->fileFd = g_recvFileInfo.recvFileInfo[i].fileFd;
275             fileInfo->fileStatus = g_recvFileInfo.recvFileInfo[i].fileStatus;
276             fileInfo->fileOffset = g_recvFileInfo.recvFileInfo[i].fileOffset;
277             if (memcpy_s(fileInfo->filePath, MAX_FILE_PATH_NAME_LEN, g_recvFileInfo.recvFileInfo[i].filePath,
278                 MAX_FILE_PATH_NAME_LEN) != EOK) {
279                 return SOFTBUS_ERR;
280             }
281             return SOFTBUS_OK;
282         }
283     }
284 
285     if (i == MAX_RECV_FILE_NUM) {
286         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "there is no match seq to get");
287         return SOFTBUS_ERR;
288     }
289 
290     return SOFTBUS_OK;
291 }
292 
RemoveFromRecvListBySeq(uint32_t seq)293 static int32_t RemoveFromRecvListBySeq(uint32_t seq)
294 {
295     int32_t i;
296     for (i = 0; i < MAX_RECV_FILE_NUM; i++) {
297         if (g_recvFileInfo.recvFileInfo[i].seq == seq) {
298             g_recvFileInfo.recvFileInfo[i].index = 0;
299             g_recvFileInfo.recvFileInfo[i].seq = 0;
300             g_recvFileInfo.recvFileInfo[i].fileFd = INVALID_FD;
301             g_recvFileInfo.recvFileInfo[i].fileStatus = NODE_IDLE;
302             g_recvFileInfo.recvFileInfo[i].fileOffset = 0;
303             g_recvFileInfo.recvFileInfo[i].timeOut = 0;
304             memset_s(g_recvFileInfo.recvFileInfo[i].filePath, MAX_FILE_PATH_NAME_LEN, 0, MAX_FILE_PATH_NAME_LEN);
305             memset_s(&g_recvFileInfo.fileListener, sizeof(FileListener), 0, sizeof(FileListener));
306             return SOFTBUS_OK;
307         }
308     }
309 
310     if (i == MAX_RECV_FILE_NUM) {
311         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "there is no match seq to clear");
312         return SOFTBUS_ERR;
313     }
314 
315     return SOFTBUS_OK;
316 }
317 
CheckRecvFileExist(const char * absFullPath)318 static bool CheckRecvFileExist(const char *absFullPath)
319 {
320     if (absFullPath == NULL) {
321         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "absFullPath is null");
322         return false;
323     }
324 
325     int32_t i;
326     for (i = 0; i < MAX_RECV_FILE_NUM; i++) {
327         if ((strcmp(g_recvFileInfo.recvFileInfo[i].filePath, absFullPath) == 0) &&
328             (g_recvFileInfo.recvFileInfo[i].fileStatus == NODE_BUSY)) {
329             return true;
330         }
331     }
332 
333     return false;
334 }
335 
PutToRecvList(int32_t fd,uint32_t seq,const char * destFilePath,FileListener fileListener,int32_t sessionId)336 static int32_t PutToRecvList(int32_t fd, uint32_t seq, const char *destFilePath, FileListener fileListener,
337     int32_t sessionId)
338 {
339     if (destFilePath == NULL) {
340         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "destFilePath is null");
341         return SOFTBUS_ERR;
342     }
343     int index = 0;
344     if (GetIdleIndexNode(&index) != SOFTBUS_OK) {
345         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "GetIdleIndexNode fail");
346         return SOFTBUS_ERR;
347     }
348     g_recvFileInfo.sessionId = sessionId;
349     g_recvFileInfo.recvFileInfo[index].index = index;
350     g_recvFileInfo.recvFileInfo[index].seq = seq;
351     g_recvFileInfo.recvFileInfo[index].fileFd = fd;
352     g_recvFileInfo.recvFileInfo[index].fileStatus = NODE_BUSY;
353     g_recvFileInfo.recvFileInfo[index].fileOffset = 0;
354     g_recvFileInfo.recvFileInfo[index].timeOut = 0;
355     if (memcpy_s(g_recvFileInfo.recvFileInfo[index].filePath, MAX_FILE_PATH_NAME_LEN,
356         destFilePath, MAX_FILE_PATH_NAME_LEN) != EOK) {
357         return SOFTBUS_ERR;
358     }
359     if (memcpy_s(&g_recvFileInfo.fileListener, sizeof(FileListener),
360         &fileListener, sizeof(FileListener)) != EOK) {
361         return SOFTBUS_ERR;
362     }
363     return SOFTBUS_OK;
364 }
365 
UpdateRecvInfo(SingleFileInfo fileInfo)366 static int32_t UpdateRecvInfo(SingleFileInfo fileInfo)
367 {
368     int index = fileInfo.index;
369     if (index >= MAX_RECV_FILE_NUM) {
370         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fileInfo.index is large than MAX_RECV_FILE_NUM");
371         return SOFTBUS_ERR;
372     }
373     g_recvFileInfo.sessionId = 0;
374     g_recvFileInfo.recvFileInfo[index].index = fileInfo.index;
375     g_recvFileInfo.recvFileInfo[index].seq = fileInfo.seq;
376     g_recvFileInfo.recvFileInfo[index].fileFd = fileInfo.fileFd;
377     g_recvFileInfo.recvFileInfo[index].fileStatus = fileInfo.fileStatus;
378     g_recvFileInfo.recvFileInfo[index].fileOffset = fileInfo.fileOffset;
379     g_recvFileInfo.recvFileInfo[index].timeOut = fileInfo.timeOut;
380     if (memcpy_s(g_recvFileInfo.recvFileInfo[index].filePath, MAX_FILE_PATH_NAME_LEN, fileInfo.filePath,
381         MAX_FILE_PATH_NAME_LEN) != EOK) {
382         return SOFTBUS_ERR;
383     }
384     return SOFTBUS_OK;
385 }
386 
IsValidFileString(const char * str[],uint32_t fileNum,size_t maxLen)387 static bool IsValidFileString(const char *str[], uint32_t fileNum, size_t maxLen)
388 {
389     if (str == NULL || fileNum == 0) {
390         return false;
391     }
392     for (uint32_t i = 0; i < fileNum; i++) {
393         if (str[i] == NULL) {
394             return false;
395         }
396         size_t len = strlen(str[i]);
397         if (len == 0 || len > (maxLen - 1)) {
398             return false;
399         }
400     }
401     return true;
402 }
403 
FrameIndexToType(uint64_t index,uint64_t frameNumber)404 static int32_t FrameIndexToType(uint64_t index, uint64_t frameNumber)
405 {
406 #define FRAME_NUM_0 0
407 #define FRAME_NUM_1 1
408 #define FRAME_NUM_2 2
409     if (index == FRAME_NUM_0) {
410         return FILE_FIRST_FRAME;
411     }
412 
413     if ((index == FRAME_NUM_1) && (frameNumber == FRAME_NUM_2)) {
414         return FILE_ONLYONE_FRAME;
415     }
416 
417     if (index == (frameNumber - 1)) {
418         return FILE_LAST_FRAME;
419     }
420 
421     return FILE_ONGOINE_FRAME;
422 }
423 
ProxyChannelSendFileStream(int32_t channelId,const char * data,uint32_t len,int32_t type)424 static int32_t ProxyChannelSendFileStream(int32_t channelId, const char *data, uint32_t len, int32_t type)
425 {
426 #define FILE_RETRY_DELAY_TIME 100
427 #define FILE_RETRY_COUNT 3
428     int32_t retry = FILE_RETRY_COUNT;
429     int32_t ret;
430     while (retry) {
431         ret = ServerIpcSendMessage(channelId, CHANNEL_TYPE_PROXY, data, len, type);
432         if (ret == SOFTBUS_CONNECTION_ERR_SENDQUEUE_FULL) {
433             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "send queue full %d", ret);
434             SoftBusSleepMs(FILE_RETRY_DELAY_TIME);
435             retry--;
436             continue;
437         }
438         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send msg(%d): type=%d, ret=%d", channelId, type, ret);
439         return ret;
440     }
441     return ret;
442 }
443 
FrameTypeToSessionType(int32_t type)444 static int32_t FrameTypeToSessionType(int32_t type)
445 {
446     switch (type) {
447         case FILE_FIRST_FRAME:
448             return TRANS_SESSION_FILE_FIRST_FRAME;
449         case FILE_ONGOINE_FRAME:
450             return TRANS_SESSION_FILE_ONGOINE_FRAME;
451         case FILE_LAST_FRAME:
452             return TRANS_SESSION_FILE_LAST_FRAME;
453         case FILE_ONLYONE_FRAME:
454             return TRANS_SESSION_FILE_ONLYONE_FRAME;
455         case FILE_ALLFILE_SENT:
456             return TRANS_SESSION_FILE_ALLFILE_SENT;
457         default:
458             return SOFTBUS_ERR;
459     }
460 }
461 
DoTransErrorCallBack(void)462 static void DoTransErrorCallBack(void)
463 {
464     if (g_recvFileInfo.fileListener.recvListener.OnFileTransError != NULL) {
465         g_recvFileInfo.fileListener.recvListener.OnFileTransError(g_recvFileInfo.sessionId);
466     }
467 }
468 
ProxyFileTransTimerProc(void)469 static void ProxyFileTransTimerProc(void)
470 {
471 #define FILE_TRANS_TIMEOUT 10
472     if (SoftBusMutexLock(&g_recvFileInfo.lock) != SOFTBUS_OK) {
473         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock file timer failed");
474         return;
475     }
476 
477     for (int32_t index = 0; index < MAX_RECV_FILE_NUM; index++) {
478         int32_t status = g_recvFileInfo.recvFileInfo[index].fileStatus;
479         int32_t timeOut = g_recvFileInfo.recvFileInfo[index].timeOut;
480         if (status == NODE_BUSY) {
481             if (timeOut >= FILE_TRANS_TIMEOUT) {
482                 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "file %s recv timeout",
483                     g_recvFileInfo.recvFileInfo[index].filePath);
484                 g_recvFileInfo.recvFileInfo[index].fileStatus = NODE_ERR;
485                 g_recvFileInfo.recvFileInfo[index].timeOut = 0;
486                 close(g_recvFileInfo.recvFileInfo[index].fileFd);
487                 remove(g_recvFileInfo.recvFileInfo[index].filePath);
488                 DoTransErrorCallBack();
489             } else {
490                 g_recvFileInfo.recvFileInfo[index].timeOut++;
491             }
492         }
493     }
494 
495     SoftBusMutexUnlock(&g_recvFileInfo.lock);
496     return;
497 }
498 
GetAndCheckRealPath(const char * filePath,char * absPath)499 static char *GetAndCheckRealPath(const char *filePath, char *absPath)
500 {
501     if ((filePath == NULL) || (absPath == NULL)) {
502         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "input invalid");
503         return NULL;
504     }
505 
506     char *realPath = NULL;
507     if (realpath(filePath, absPath) == NULL) {
508         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "realpath failed, err[%s]", strerror(errno));
509         return NULL;
510     } else {
511         realPath = absPath;
512     }
513 
514     if (strstr(realPath, "..") != NULL) {
515         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "real path is not canonical form");
516         return NULL;
517     }
518 
519     int32_t pathLength = strlen(realPath);
520     if ((pathLength > (MAX_FILE_PATH_NAME_LEN - 1)) || (pathLength > PATH_MAX)) {
521         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "pathLength[%d] is too large", pathLength);
522         return NULL;
523     }
524 
525     return realPath;
526 }
527 
GetAndCheckFileSize(const char * sourceFile,uint64_t * fileSize)528 static int32_t GetAndCheckFileSize(const char *sourceFile, uint64_t *fileSize)
529 {
530     if ((sourceFile == NULL) || (fileSize == NULL)) {
531         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sourceFile or fileSize is null");
532         return SOFTBUS_FILE_ERR;
533     }
534     struct stat statbuff;
535     if (stat(sourceFile, &statbuff) < 0) {
536         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "stat file fail");
537         return SOFTBUS_FILE_ERR;
538     } else {
539         *fileSize = statbuff.st_size;
540     }
541 
542     if (*fileSize > MAX_FILE_SIZE) {
543         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "file is too large, filesize : %llu", *fileSize);
544         return SOFTBUS_FILE_ERR;
545     }
546 
547     return SOFTBUS_OK;
548 }
549 
SendOneFrame(int32_t channelId,FileFrame fileFrame)550 static int32_t SendOneFrame(int32_t channelId, FileFrame fileFrame)
551 {
552     if (fileFrame.data == NULL) {
553         return SOFTBUS_ERR;
554     }
555     int32_t type = FrameTypeToSessionType(fileFrame.frameType);
556     if (type == SOFTBUS_ERR) {
557         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "Frame Type To Session Type fail %d", fileFrame.frameType);
558         return SOFTBUS_ERR;
559     }
560     int32_t ret = ProxyChannelSendFileStream(channelId, (char *)fileFrame.data, fileFrame.frameLength, type);
561     if (ret != SOFTBUS_OK) {
562         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "conn send buf fail %d", ret);
563         return ret;
564     }
565     return SOFTBUS_OK;
566 }
567 
FileToFrame(SendListenerInfo sendInfo,uint64_t frameNum,int32_t fd,const char * destFile,uint64_t fileSize)568 static int32_t FileToFrame(SendListenerInfo sendInfo, uint64_t frameNum, int32_t fd,
569     const char *destFile, uint64_t fileSize)
570 {
571     FileFrame fileFrame;
572     uint8_t *buffer = (uint8_t *)SoftBusCalloc(PROXY_MAX_PACKET_SIZE);
573     if (buffer == NULL) {
574         return SOFTBUS_ERR;
575     }
576     uint64_t fileOffset = 0;
577     uint64_t remainedSendSize = fileSize;
578     uint64_t frameDataSize = PROXY_MAX_PACKET_SIZE - FRAME_DATA_SEQ_OFFSET;
579     for (uint64_t index = 0; index < frameNum; index++) {
580         fileFrame.frameType = FrameIndexToType(index, frameNum);
581         fileFrame.data = buffer;
582         if (memcpy_s(fileFrame.data, FRAME_DATA_SEQ_OFFSET, (char *)&sendInfo.channelId,
583             FRAME_DATA_SEQ_OFFSET) != EOK) {
584             goto EXIT_ERR;
585         }
586         if (index == 0) {
587             uint32_t dNameSize = strlen(destFile);
588             if (memcpy_s(fileFrame.data + FRAME_DATA_SEQ_OFFSET, dNameSize, destFile, dNameSize) != SOFTBUS_OK) {
589                 goto EXIT_ERR;
590             }
591             fileFrame.frameLength = FRAME_DATA_SEQ_OFFSET + dNameSize;
592         } else {
593             uint64_t readLength = (remainedSendSize < frameDataSize) ? remainedSendSize : frameDataSize;
594             int32_t len = pread(fd, fileFrame.data + FRAME_DATA_SEQ_OFFSET, readLength, fileOffset);
595             if (len >= 0) {
596                 fileOffset += readLength;
597                 fileFrame.frameLength = readLength + FRAME_DATA_SEQ_OFFSET;
598                 remainedSendSize -= readLength;
599             } else {
600                 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "pread src file failed");
601                 goto EXIT_ERR;
602             }
603         }
604 
605         if (sendInfo.fileListener.sendListener.OnSendFileProcess != NULL) {
606             sendInfo.fileListener.sendListener.OnSendFileProcess(sendInfo.channelId, fileOffset, fileSize);
607         }
608         if (SendOneFrame(sendInfo.channelId, fileFrame) != SOFTBUS_OK) {
609             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "send one frame failed");
610             goto EXIT_ERR;
611         }
612         memset_s(fileFrame.data, PROXY_MAX_PACKET_SIZE, 0, PROXY_MAX_PACKET_SIZE);
613         SoftBusSleepMs(SEND_DELAY_TIME);
614     }
615     SoftBusFree(fileFrame.data);
616     return SOFTBUS_OK;
617 EXIT_ERR:
618     SoftBusFree(fileFrame.data);
619     return SOFTBUS_ERR;
620 }
621 
622 
CheckDestFilePathValid(const char * destFile)623 static bool CheckDestFilePathValid(const char *destFile)
624 {
625     if (destFile == NULL) {
626         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "destFile is null");
627         return false;
628     }
629     int32_t len = strlen(destFile);
630     if ((len == 0) || (destFile[0] == PATH_SEPARATOR)) {
631         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "destFile first char is '/'");
632         return false;
633     }
634 
635     if (strstr(destFile, "..") != NULL) {
636         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "dest path is not canonical form");
637         return false;
638     }
639     return true;
640 }
641 
FileToFrameAndSendFile(SendListenerInfo sendInfo,const char * sourceFile,const char * destFile)642 static int32_t FileToFrameAndSendFile(SendListenerInfo sendInfo, const char *sourceFile, const char *destFile)
643 {
644     uint64_t fileSize = 0;
645     char *absSrcPath = (char *)SoftBusCalloc(PATH_MAX + 1);
646     if (absSrcPath == NULL) {
647         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc absFullDir failed");
648         return SOFTBUS_ERR;
649     }
650     const char *realSrcPath = GetAndCheckRealPath(sourceFile, absSrcPath);
651     if (realSrcPath == NULL) {
652         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get src abs file failed");
653         goto EXIT_ERR;
654     }
655 
656     if (CheckDestFilePathValid(destFile) == false) {
657         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "dest path's form is wrong");
658         goto EXIT_ERR;
659     }
660 
661     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "srcPath:%s, srcAbsPath:%s, destPath:%s",
662         sourceFile, realSrcPath, destFile);
663 
664     if (GetAndCheckFileSize(realSrcPath, &fileSize) != SOFTBUS_OK) {
665         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sourcefile size err");
666         goto EXIT_ERR;
667     }
668     int32_t fd = open(realSrcPath, O_RDONLY);
669     if (fd < 0) {
670         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "open file fail");
671         goto EXIT_ERR;
672     }
673     if (PROXY_MAX_PACKET_SIZE <= FRAME_DATA_SEQ_OFFSET) {
674         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "stat file fail");
675         goto EXIT_ERR;
676     }
677     uint64_t frameDataSize = PROXY_MAX_PACKET_SIZE - FRAME_DATA_SEQ_OFFSET;
678     uint64_t frameNum = fileSize / frameDataSize;
679     if ((fileSize % frameDataSize) != 0) {
680         frameNum++;
681     }
682 
683     /* add 1 means reserve frame to send destFile string */
684     frameNum++;
685     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO,
686         "channelId:%d, fileName:%s, fileSize:%llu, frameNum:%llu, destPath:%s",
687         sendInfo.channelId, realSrcPath, fileSize, frameNum, destFile);
688     if (FileToFrame(sendInfo, frameNum, fd, destFile, fileSize) != SOFTBUS_OK) {
689         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "File To Frame fail");
690         goto EXIT_ERR;
691     }
692     SoftBusFree(absSrcPath);
693     return SOFTBUS_OK;
694 EXIT_ERR:
695     SoftBusFree(absSrcPath);
696     return SOFTBUS_ERR;
697 }
698 
GetDestFilePath(FileFrame fileFrame)699 static char *GetDestFilePath(FileFrame fileFrame)
700 {
701     if (fileFrame.frameLength <= FRAME_DATA_SEQ_OFFSET) {
702         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "CreateFileFromFrame framelength less then offset");
703         return NULL;
704     }
705 
706     uint32_t filePathSize = fileFrame.frameLength - FRAME_DATA_SEQ_OFFSET + 1;
707     if (filePathSize > MAX_FILE_PATH_NAME_LEN) {
708         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath is too long");
709         return NULL;
710     }
711     char *filePath = (char *)SoftBusCalloc(filePathSize);
712     if (filePath == NULL) {
713         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc filePath failed");
714         return NULL;
715     }
716     if (memcpy_s(filePath, filePathSize, fileFrame.data + FRAME_DATA_SEQ_OFFSET,
717         fileFrame.frameLength - FRAME_DATA_SEQ_OFFSET) != SOFTBUS_OK) {
718         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "memcpy_s failed");
719         SoftBusFree(filePath);
720         return NULL;
721     }
722 
723     if (CheckDestFilePathValid(filePath) == false) {
724         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "recv file path[%s] form is wrong", filePath);
725         SoftBusFree(filePath);
726         return NULL;
727     }
728     return filePath;
729 }
730 
GetDestFileFrameSeq(FileFrame fileFrame,uint32_t * seq)731 static int32_t GetDestFileFrameSeq(FileFrame fileFrame, uint32_t *seq)
732 {
733     if (seq == NULL) {
734         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "seq is null");
735         return SOFTBUS_ERR;
736     }
737     if (fileFrame.frameLength <= FRAME_DATA_SEQ_OFFSET) {
738         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "CreateFileFromFrame framelength less then offset");
739         return SOFTBUS_ERR;
740     }
741 
742     if (memcpy_s(seq, FRAME_DATA_SEQ_OFFSET, fileFrame.data, FRAME_DATA_SEQ_OFFSET) != EOK) {
743         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "memcpy_s failed");
744         return SOFTBUS_ERR;
745     }
746 
747     return SOFTBUS_OK;
748 }
749 
IsPathValid(char * filePath)750 static bool IsPathValid(char *filePath)
751 {
752     if (filePath == NULL) {
753         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath is null");
754         return false;
755     }
756     if ((strlen(filePath) == 0) || (strlen(filePath) > (MAX_FILE_PATH_NAME_LEN - 1))) {
757         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath size[%d] is wrong", (int32_t)strlen(filePath));
758         return false;
759     }
760 
761     if (filePath[strlen(filePath) - 1] == PATH_SEPARATOR) {
762         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath is end with '/' ");
763         return false;
764     }
765 
766     return true;
767 }
768 
GetDirPath(const char * fullPath,char * dirPath,int32_t dirPathLen)769 static int32_t GetDirPath(const char *fullPath, char *dirPath, int32_t dirPathLen)
770 {
771     if ((fullPath == NULL) || (strlen(fullPath) < 1) || (fullPath[strlen(fullPath) - 1] == PATH_SEPARATOR)) {
772         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "invalid input param");
773         return SOFTBUS_ERR;
774     }
775     int32_t i = 0;
776     int32_t dirFullLen = (int32_t)strlen(fullPath);
777     for (i = dirFullLen - 1; i >= 0; i--) {
778         if (fullPath[i] == PATH_SEPARATOR) {
779             i++;
780             break;
781         }
782         if (i == 0) {
783             break;
784         }
785     }
786     int32_t dirLen = i;
787     if (dirLen >= dirPathLen) {
788         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "dirLen[%d] >= dirPathLen[%d]", dirLen, dirPathLen);
789         return SOFTBUS_ERR;
790     }
791 
792     if (strncpy_s(dirPath, dirPathLen, fullPath, dirLen) != EOK) {
793         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "strcpy_s dir path error, dirLen[%d]", dirLen);
794         return SOFTBUS_ERR;
795     }
796 
797     return SOFTBUS_OK;
798 }
799 
GetFileName(const char * fullPath,char * fileName,int32_t fileNameLen)800 static int32_t GetFileName(const char *fullPath, char *fileName, int32_t fileNameLen)
801 {
802     if ((fullPath == NULL) || (strlen(fullPath) < 1) || (fullPath[strlen(fullPath) - 1] == PATH_SEPARATOR)) {
803         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "invalid input param");
804         return SOFTBUS_ERR;
805     }
806     int32_t i;
807     int32_t dirFullLen = (int32_t)strlen(fullPath);
808     for (i = dirFullLen - 1; i >= 0; i--) {
809         if (fullPath[i] == PATH_SEPARATOR) {
810             i++;
811             break;
812         }
813         if (i == 0) {
814             break;
815         }
816     }
817 
818     if (strcpy_s(fileName, fileNameLen, fullPath + i) != EOK) {
819         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "strcpy_s filename error, fileNameLen[%d]", fileNameLen);
820         return SOFTBUS_ERR;
821     }
822 
823     return SOFTBUS_OK;
824 }
825 
GetAbsFullPath(const char * fullPath,char * recvAbsPath,int32_t pathSize)826 static int32_t GetAbsFullPath(const char *fullPath, char *recvAbsPath, int32_t pathSize)
827 {
828     char dirPath[MAX_FILE_PATH_NAME_LEN] = { 0 };
829     char fileName[MAX_FILE_PATH_NAME_LEN] = { 0 };
830     if (GetDirPath(fullPath, dirPath, sizeof(dirPath)) != SOFTBUS_OK) {
831         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get dir path failed");
832         return SOFTBUS_ERR;
833     }
834     if (GetFileName(fullPath, fileName, sizeof(fileName)) != SOFTBUS_OK) {
835         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get file name failed");
836         return SOFTBUS_ERR;
837     }
838 
839     char *absFullDir = (char *)SoftBusCalloc(PATH_MAX + 1);
840     if (absFullDir == NULL) {
841         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc absFullDir failed");
842         return SOFTBUS_ERR;
843     }
844     const char *realFullDir = GetAndCheckRealPath(dirPath, absFullDir);
845     if (realFullDir == NULL) {
846         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get full abs file failed");
847         SoftBusFree(absFullDir);
848         return SOFTBUS_ERR;
849     }
850 
851     int32_t fileNameLength = strlen(fileName);
852     int32_t dirPathLength = strlen(realFullDir);
853     if (pathSize < (fileNameLength + dirPathLength + 1)) {
854         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "copy name is too large, dirLen:%d, fileNameLen:%d",
855             dirPathLength, fileNameLength);
856         SoftBusFree(absFullDir);
857         return SOFTBUS_ERR;
858     }
859     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "dirPath[%s]len[%d], fileName[%s][%d], realFullDir[%s]",
860         dirPath, dirPathLength, fileName, fileNameLength, realFullDir);
861 
862     if (sprintf_s(recvAbsPath, pathSize, "%s/%s", realFullDir, fileName) == -1) {
863         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "memcpy filename error");
864         SoftBusFree(absFullDir);
865         return SOFTBUS_ERR;
866     }
867 
868     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "recvAbsPath[%s]", recvAbsPath);
869     SoftBusFree(absFullDir);
870     return SOFTBUS_OK;
871 }
872 
CreateDirAndGetAbsPath(const char * filePath,char * recvAbsPath,int32_t pathSize)873 static int32_t CreateDirAndGetAbsPath(const char *filePath, char *recvAbsPath, int32_t pathSize)
874 {
875     if ((filePath == NULL) || (recvAbsPath == NULL)) {
876         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "invalid input");
877         return SOFTBUS_ERR;
878     }
879     uint32_t len = (uint32_t)strlen(filePath);
880     int32_t ret;
881     char *tempPath = (char *)SoftBusCalloc(len + 1);
882     if (tempPath == NULL) {
883         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc tempPath failed");
884         return SOFTBUS_ERR;
885     }
886     for (uint32_t i = 0; i < len; i++) {
887         tempPath[i] = filePath[i];
888         if (tempPath[i] != PATH_SEPARATOR) {
889             continue;
890         }
891         if (access(tempPath, 0) == -1) {
892             ret = mkdir(tempPath, DEFAULT_NEW_PATH_AUTHORITY);
893             if (ret == -1 && errno != EEXIST) {
894                 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "mkdir failed(%d)", errno);
895                 SoftBusFree(tempPath);
896                 return SOFTBUS_ERR;
897             }
898         }
899     }
900 
901     SoftBusFree(tempPath);
902     if (GetAbsFullPath(filePath, recvAbsPath, pathSize) != SOFTBUS_OK) {
903         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "dest dir is invalid");
904         return SOFTBUS_ERR;
905     }
906     return SOFTBUS_OK;
907 }
908 
GetFullRecvPath(const char * filePath,const char * recvRootDir)909 static char *GetFullRecvPath(const char *filePath, const char *recvRootDir)
910 {
911     if ((filePath == NULL) || (recvRootDir == NULL)) {
912         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath is null or rootDir is null");
913         return NULL;
914     }
915 
916     int32_t rootDirLength = strlen(recvRootDir);
917     int32_t filePathLength = strlen(filePath);
918     bool isNeedAddSep = true;
919     if (((filePathLength > 0) && (filePath[0] == PATH_SEPARATOR)) ||
920         ((rootDirLength > 0) && (recvRootDir[rootDirLength - 1] == PATH_SEPARATOR))) {
921         isNeedAddSep = false;
922     }
923 
924     int32_t destFullPathLength = (isNeedAddSep) ? (rootDirLength + sizeof('/') + filePathLength) :
925         (rootDirLength + filePathLength);
926     char *recvFullPath = (char *)SoftBusCalloc(destFullPathLength + 1);
927     if (recvFullPath == NULL) {
928         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "recvFullPath is null");
929         return NULL;
930     }
931 
932     int32_t ret;
933     if (isNeedAddSep) {
934         ret = sprintf_s(recvFullPath, destFullPathLength + 1, "%s%c%s", recvRootDir, PATH_SEPARATOR, filePath);
935     } else {
936         ret = sprintf_s(recvFullPath, destFullPathLength + 1, "%s%s", recvRootDir, filePath);
937     }
938     if (ret == -1) {
939         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "create fullPath fail");
940         SoftBusFree(recvFullPath);
941         return NULL;
942     }
943     return recvFullPath;
944 }
945 
GetFileAbsPathAndSeq(FileFrame fileFrame,const char * rootDir,uint32_t * seq)946 static char *GetFileAbsPathAndSeq(FileFrame fileFrame, const char *rootDir, uint32_t *seq)
947 {
948     if (seq == NULL) {
949         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "seq is null");
950         return NULL;
951     }
952 
953     if (GetDestFileFrameSeq(fileFrame, seq) != SOFTBUS_OK) {
954         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "open destFile fail");
955         return NULL;
956     }
957 
958     char *destFilePath = GetDestFilePath(fileFrame);
959     if (destFilePath == NULL) {
960         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "GetDestFilePath failed");
961         return NULL;
962     }
963 
964     if (strstr(rootDir, "..") != NULL) {
965         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "rootDir[%s] is not cannoical form", rootDir);
966         SoftBusFree(destFilePath);
967         return NULL;
968     }
969 
970     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "destFilePath[%s], rootDir[%s]", destFilePath, rootDir);
971 
972     char *fullRecvPath = GetFullRecvPath(destFilePath, rootDir);
973     if (IsPathValid(fullRecvPath) == false) {
974         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "destFilePath is invalid");
975         SoftBusFree(destFilePath);
976         SoftBusFree(fullRecvPath);
977         return NULL;
978     }
979 
980     SoftBusFree(destFilePath);
981     int32_t pathSize = strlen(fullRecvPath) + 1;
982     char *absFullPath = (char *)SoftBusCalloc(pathSize);
983     if (absFullPath == NULL) {
984         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "absFullPath is null");
985         SoftBusFree(fullRecvPath);
986         return NULL;
987     }
988     if (CreateDirAndGetAbsPath(fullRecvPath, absFullPath, pathSize) != SOFTBUS_OK) {
989         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "create dest dir failed");
990         SoftBusFree(fullRecvPath);
991         SoftBusFree(absFullPath);
992         return NULL;
993     }
994     SoftBusFree(fullRecvPath);
995     return absFullPath;
996 }
997 
CreateFileFromFrame(int32_t sessionId,FileFrame fileFrame,FileListener fileListener)998 static int32_t CreateFileFromFrame(int32_t sessionId, FileFrame fileFrame, FileListener fileListener)
999 {
1000     if (SoftBusMutexLock(&g_recvFileInfo.lock) != SOFTBUS_OK) {
1001         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock fileFromFrame fail");
1002         return SOFTBUS_ERR;
1003     }
1004     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "create file from frame start");
1005     uint32_t seq = 0;
1006 
1007     char *fullRecvPath = GetFileAbsPathAndSeq(fileFrame, fileListener.rootDir, &seq);
1008     if (fullRecvPath == NULL) {
1009         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fullRecvPath is null");
1010         SoftBusMutexUnlock(&g_recvFileInfo.lock);
1011         return SOFTBUS_ERR;
1012     }
1013 
1014     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "fullRecvPath %s, seq:%u", fullRecvPath, seq);
1015     if (CheckRecvFileExist(fullRecvPath) == true) {
1016         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "file is already exist and busy");
1017         goto EXIT_ERR;
1018     }
1019 
1020     int32_t fd = open(fullRecvPath, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
1021     if (fd < 0) {
1022         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "open destFile fail");
1023         goto EXIT_ERR;
1024     }
1025 
1026     if (PutToRecvList(fd, seq, fullRecvPath, fileListener, sessionId) != SOFTBUS_OK) {
1027         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "put seq[%u] failed", seq);
1028         close(fd);
1029         remove(fullRecvPath);
1030         if (RemoveFromRecvListBySeq(seq) != SOFTBUS_OK) {
1031             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "remove from list failed");
1032         }
1033         goto EXIT_ERR;
1034     }
1035 
1036     if (fileListener.recvListener.OnReceiveFileStarted != NULL) {
1037         fileListener.recvListener.OnReceiveFileStarted(sessionId, fullRecvPath, 1);
1038     }
1039     SoftBusFree(fullRecvPath);
1040     SoftBusMutexUnlock(&g_recvFileInfo.lock);
1041     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "create file from frame success");
1042     return SOFTBUS_OK;
1043 EXIT_ERR:
1044     SoftBusFree(fullRecvPath);
1045     SoftBusMutexUnlock(&g_recvFileInfo.lock);
1046     return SOFTBUS_ERR;
1047 }
1048 
ProcessOneFrame(FileFrame fileFrame,SingleFileInfo fileInfo,int32_t seq)1049 static int32_t ProcessOneFrame(FileFrame fileFrame, SingleFileInfo fileInfo, int32_t seq)
1050 {
1051     uint32_t frameLength = fileFrame.frameLength;
1052     if (fileFrame.frameLength <= FRAME_DATA_SEQ_OFFSET) {
1053         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "WriteFrameToFile framelength less then offset");
1054         return SOFTBUS_ERR;
1055     }
1056 
1057     uint32_t frameDataLength = frameLength - FRAME_DATA_SEQ_OFFSET;
1058     int32_t writeLength = pwrite(fileInfo.fileFd, fileFrame.data + FRAME_DATA_SEQ_OFFSET, frameDataLength,
1059         (uint64_t)fileInfo.fileOffset);
1060     if (writeLength < 0) {
1061         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "pwrite file failed");
1062         return SOFTBUS_ERR;
1063     }
1064     fileInfo.fileOffset += (uint64_t)writeLength;
1065 
1066     if (fileInfo.fileOffset > MAX_FILE_SIZE) {
1067         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "file is too large, offset:%llu", fileInfo.fileOffset);
1068         return SOFTBUS_ERR;
1069     }
1070     if (UpdateRecvInfo(fileInfo) != SOFTBUS_OK) {
1071         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "UpdateRecvInfo fail");
1072         return SOFTBUS_ERR;
1073     }
1074     int32_t frameType = fileFrame.frameType;
1075 
1076     /* last frame */
1077     if ((frameType == FILE_LAST_FRAME) || (frameType == FILE_ONLYONE_FRAME)) {
1078         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "process last frame, seq:%d", seq);
1079         close(fileInfo.fileFd);
1080         if (RemoveFromRecvListBySeq(seq) != SOFTBUS_OK) {
1081             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ClearRecvFileInfoBySeq fail");
1082             remove(fileInfo.filePath);
1083             return SOFTBUS_ERR;
1084         }
1085     }
1086     return SOFTBUS_OK;
1087 }
1088 
WriteFrameToFile(FileFrame fileFrame)1089 static int32_t WriteFrameToFile(FileFrame fileFrame)
1090 {
1091     if (SoftBusMutexLock(&g_recvFileInfo.lock) != SOFTBUS_OK) {
1092         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock write frame fail");
1093         return SOFTBUS_ERR;
1094     }
1095     uint32_t seq = 0;
1096     SingleFileInfo fileInfo = {0};
1097     if (GetDestFileFrameSeq(fileFrame, &seq) != SOFTBUS_OK) {
1098         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get dest file frame failed");
1099         SoftBusMutexUnlock(&g_recvFileInfo.lock);
1100         return SOFTBUS_ERR;
1101     }
1102 
1103     if (GetRecvFileInfoBySeq(seq, &fileInfo) != SOFTBUS_OK) {
1104         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "GetFileFdBySeq fail");
1105         SoftBusMutexUnlock(&g_recvFileInfo.lock);
1106         return SOFTBUS_ERR;
1107     }
1108 
1109     if (fileInfo.fileStatus == NODE_ERR) {
1110         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fileStatus is error");
1111         goto EXIT_ERR;
1112     }
1113     if (ProcessOneFrame(fileFrame, fileInfo, seq) != SOFTBUS_OK) {
1114         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "write one frame error");
1115         goto EXIT_ERR;
1116     }
1117     SoftBusMutexUnlock(&g_recvFileInfo.lock);
1118     return SOFTBUS_OK;
1119 EXIT_ERR:
1120     close(fileInfo.fileFd);
1121     remove(fileInfo.filePath);
1122     if (RemoveFromRecvListBySeq(seq) != SOFTBUS_OK) {
1123         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "WriteFrameToFile remove fail");
1124     }
1125     SoftBusMutexUnlock(&g_recvFileInfo.lock);
1126     return SOFTBUS_ERR;
1127 }
1128 
ProcessFileFrameData(int32_t sessionId,FileListener fileListener,const char * data,uint32_t len,int32_t type)1129 int32_t ProcessFileFrameData(int32_t sessionId, FileListener fileListener, const char *data, uint32_t len,
1130     int32_t type)
1131 {
1132     int32_t ret;
1133     FileFrame oneFrame;
1134     oneFrame.frameType = type;
1135     oneFrame.frameLength = len;
1136     oneFrame.data = (uint8_t *)data;
1137     switch (oneFrame.frameType) {
1138         case FILE_FIRST_FRAME:
1139             ret = CreateFileFromFrame(sessionId, oneFrame, fileListener);
1140             if (ret != SOFTBUS_OK) {
1141                 if (fileListener.recvListener.OnFileTransError != NULL) {
1142                     fileListener.recvListener.OnFileTransError(sessionId);
1143                 }
1144             }
1145             break;
1146         case FILE_ONGOINE_FRAME:
1147         case FILE_ONLYONE_FRAME:
1148         case FILE_LAST_FRAME:
1149             ret = WriteFrameToFile(oneFrame);
1150             if (ret != SOFTBUS_OK) {
1151                 if (fileListener.recvListener.OnFileTransError != NULL) {
1152                     fileListener.recvListener.OnFileTransError(sessionId);
1153                 }
1154             }
1155             break;
1156         default:
1157             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "frame type is invalid");
1158             return SOFTBUS_ERR;
1159     }
1160     return ret;
1161 }
1162 
FileListToBuffer(const char ** destFile,uint32_t fileCnt,FileListBuffer * outbufferInfo)1163 static int32_t FileListToBuffer(const char **destFile, uint32_t fileCnt, FileListBuffer *outbufferInfo)
1164 {
1165     if (outbufferInfo == NULL) {
1166         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "outbufferInfo is NULL");
1167         return SOFTBUS_ERR;
1168     }
1169     outbufferInfo->buffer = NULL;
1170     outbufferInfo->bufferSize = 0;
1171     uint32_t totalLength = 0;
1172     uint32_t offset = 0;
1173     uint32_t index;
1174     for (index = 0; index < fileCnt; index++) {
1175         totalLength += strlen(destFile[index]);
1176     }
1177 
1178     uint32_t fileNameSize = 0;
1179     uint32_t indexSize  = sizeof(index);
1180     uint32_t bufferSize = totalLength + (indexSize + sizeof(fileNameSize)) * fileCnt;
1181     uint8_t *buffer = (uint8_t *)SoftBusCalloc(bufferSize);
1182     if (buffer == NULL) {
1183         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc filelist failed");
1184         return SOFTBUS_ERR;
1185     }
1186 
1187     char byteBuff[sizeof(int32_t)] = {0};
1188     for (index = 0; index < fileCnt; index++) {
1189         if (IntToByte(index, byteBuff, indexSize) == false) {
1190             goto EXIT;
1191         }
1192         if (memcpy_s(buffer + offset, indexSize, byteBuff, indexSize) != EOK) {
1193             goto EXIT;
1194         }
1195         offset += indexSize;
1196         fileNameSize = strlen(destFile[index]);
1197         if (IntToByte(fileNameSize, byteBuff, indexSize) == false) {
1198             goto EXIT;
1199         }
1200         if (memcpy_s(buffer + offset, sizeof(fileNameSize), byteBuff, sizeof(fileNameSize)) != EOK) {
1201             goto EXIT;
1202         }
1203         offset += sizeof(fileNameSize);
1204         if (memcpy_s(buffer + offset, fileNameSize, destFile[index], fileNameSize) != EOK) {
1205             goto EXIT;
1206         }
1207         offset += fileNameSize;
1208     }
1209 
1210     outbufferInfo->buffer = buffer;
1211     outbufferInfo->bufferSize = offset;
1212     return SOFTBUS_OK;
1213 EXIT:
1214     SoftBusFree(buffer);
1215     return SOFTBUS_ERR;
1216 }
1217 
BufferToFileList(FileListBuffer bufferInfo,char * firstFile,int32_t * fileCount)1218 static int32_t BufferToFileList(FileListBuffer bufferInfo, char *firstFile, int32_t *fileCount)
1219 {
1220     if ((bufferInfo.buffer == NULL) || (firstFile == NULL) || (fileCount == NULL)) {
1221         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "BufferToFileList input invalid");
1222         return SOFTBUS_ERR;
1223     }
1224     *fileCount = 0;
1225     uint8_t *buffer = bufferInfo.buffer;
1226     uint32_t offset = 0;
1227     int32_t count = 0;
1228     uint32_t fileNameLength = 0;
1229     uint32_t byteLen = sizeof(uint32_t);
1230     char byteBuff[sizeof(int32_t)] = {0};
1231     while (offset < bufferInfo.bufferSize) {
1232         offset += sizeof(uint32_t);
1233 
1234         if (memcpy_s(byteBuff, sizeof(byteBuff), buffer + offset, byteLen) != EOK) {
1235             return SOFTBUS_ERR;
1236         }
1237         if (ByteToInt(byteBuff, byteLen, &fileNameLength) == false) {
1238             return SOFTBUS_ERR;
1239         }
1240         offset += byteLen;
1241         if (fileNameLength > bufferInfo.bufferSize - offset) {
1242             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "BufferToFileList invalid fileLength");
1243             return SOFTBUS_ERR;
1244         }
1245         /* only output first file path */
1246         if (count == 0) {
1247             if (memcpy_s(firstFile, fileNameLength, buffer + offset, fileNameLength) != EOK) {
1248                 return SOFTBUS_ERR;
1249             }
1250         }
1251         offset += fileNameLength;
1252         count++;
1253     }
1254 
1255     *fileCount = count;
1256     return SOFTBUS_OK;
1257 }
1258 
ProcessFileListData(int32_t sessionId,FileListener fileListener,const char * data,uint32_t len)1259 int32_t ProcessFileListData(int32_t sessionId, FileListener fileListener, const char *data, uint32_t len)
1260 {
1261     if (SoftBusMutexLock(&g_recvFileInfo.lock) != SOFTBUS_OK) {
1262         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock filelist data fail");
1263         return SOFTBUS_ERR;
1264     }
1265 
1266     FileListBuffer bufferInfo;
1267     char firstFilePath[MAX_FILE_PATH_NAME_LEN] = {0};
1268     int32_t fileCount = 0;
1269     bufferInfo.buffer = (uint8_t *)data;
1270     bufferInfo.bufferSize = len;
1271     int32_t ret = BufferToFileList(bufferInfo, firstFilePath, &fileCount);
1272     if (ret != SOFTBUS_OK) {
1273         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "Buffer To File List failed");
1274         SoftBusMutexUnlock(&g_recvFileInfo.lock);
1275         return SOFTBUS_ERR;
1276     }
1277     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "rootDir:%s, firstFilePath:%s", fileListener.rootDir, firstFilePath);
1278     char *fullRecvPath = GetFullRecvPath(firstFilePath, fileListener.rootDir);
1279     if (IsPathValid(fullRecvPath) == false) {
1280         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fullRecvPath is invalid");
1281         SoftBusFree(fullRecvPath);
1282         SoftBusMutexUnlock(&g_recvFileInfo.lock);
1283         return SOFTBUS_ERR;
1284     }
1285 
1286     char *absRecvPath = (char *)SoftBusCalloc(PATH_MAX + 1);
1287     if (absRecvPath == NULL) {
1288         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc absFullDir failed");
1289         SoftBusFree(fullRecvPath);
1290         SoftBusMutexUnlock(&g_recvFileInfo.lock);
1291         return SOFTBUS_ERR;
1292     }
1293     const char *realRecvPath = GetAndCheckRealPath(fullRecvPath, absRecvPath);
1294     if (realRecvPath == NULL) {
1295         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get recv abs file path failed");
1296         SoftBusFree(fullRecvPath);
1297         SoftBusFree(absRecvPath);
1298         SoftBusMutexUnlock(&g_recvFileInfo.lock);
1299         return SOFTBUS_ERR;
1300     }
1301     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "fullRecvPath:%s", realRecvPath);
1302 
1303     if (fileListener.recvListener.OnReceiveFileFinished != NULL) {
1304         fileListener.recvListener.OnReceiveFileFinished(sessionId, realRecvPath, fileCount);
1305     }
1306 
1307     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "Process File List Data success!!!");
1308     SoftBusFree(fullRecvPath);
1309     SoftBusFree(absRecvPath);
1310     SoftBusMutexUnlock(&g_recvFileInfo.lock);
1311     return SOFTBUS_OK;
1312 }
1313 
SendFileList(int32_t channelId,const char ** destFile,uint32_t fileCnt)1314 static int32_t SendFileList(int32_t channelId, const char **destFile, uint32_t fileCnt)
1315 {
1316     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "SendFileList begin");
1317     FileListBuffer bufferInfo;
1318     int32_t ret = FileListToBuffer(destFile, fileCnt, &bufferInfo);
1319     if (ret != SOFTBUS_OK) {
1320         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "FileListToBuffer failed");
1321         SoftBusFree(bufferInfo.buffer);
1322         return SOFTBUS_ERR;
1323     }
1324 
1325     /* send file list */
1326     int32_t type = TRANS_SESSION_FILE_ALLFILE_SENT;
1327     ret = ProxyChannelSendFileStream(channelId, (char *)bufferInfo.buffer, bufferInfo.bufferSize, type);
1328     if (ret < 0) {
1329         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "conn send buf fail %d", ret);
1330         SoftBusFree(bufferInfo.buffer);
1331         return ret;
1332     }
1333 
1334     SoftBusFree(bufferInfo.buffer);
1335     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "SendFileList success");
1336 
1337     return SOFTBUS_OK;
1338 }
1339 
SendSingleFile(SendListenerInfo sendInfo,const char * sourceFile,const char * destFile)1340 static int32_t SendSingleFile(SendListenerInfo sendInfo, const char *sourceFile, const char *destFile)
1341 {
1342     if ((sourceFile == NULL) || (destFile == NULL)) {
1343         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sourfile or dstfile is null");
1344         return SOFTBUS_ERR;
1345     }
1346     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send file[%s] begin, dest is :%s", sourceFile, destFile);
1347 
1348     int32_t ret;
1349     ret = FileToFrameAndSendFile(sendInfo, sourceFile, destFile);
1350     if (ret != SOFTBUS_OK) {
1351         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "FileToFrameAndSendFile failed");
1352         return SOFTBUS_ERR;
1353     }
1354 
1355     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send file[%s] success", sourceFile);
1356 
1357     return SOFTBUS_OK;
1358 }
1359 
ProxySendFile(SendListenerInfo sendInfo,const char * sFileList[],const char * dFileList[],uint32_t fileCnt)1360 static int32_t ProxySendFile(SendListenerInfo sendInfo, const char *sFileList[], const char *dFileList[],
1361     uint32_t fileCnt)
1362 {
1363     int32_t ret;
1364     if ((fileCnt == 0) || (fileCnt > MAX_FILE_NUM)) {
1365         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sendfile arg filecnt[%d] error", fileCnt);
1366         return SOFTBUS_ERR;
1367     }
1368 
1369     if (!IsValidFileString(sFileList, fileCnt, MAX_FILE_PATH_NAME_LEN) ||
1370         !IsValidFileString(dFileList, fileCnt, MAX_FILE_PATH_NAME_LEN)) {
1371         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sendfile invalid arg input");
1372         return SOFTBUS_ERR;
1373     }
1374 
1375     for (uint32_t index = 0; index < fileCnt; index++) {
1376         ret = SendSingleFile(sendInfo, sFileList[index], dFileList[index]);
1377         if (ret != SOFTBUS_OK) {
1378             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "send file %s, failed", sFileList[index]);
1379             return SOFTBUS_ERR;
1380         }
1381     }
1382 
1383     ret = SendFileList(sendInfo.channelId, dFileList, fileCnt);
1384     if (ret != SOFTBUS_OK) {
1385         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "SendFileList failed");
1386         return SOFTBUS_ERR;
1387     }
1388 
1389     if (sendInfo.fileListener.sendListener.OnSendFileFinished != NULL) {
1390         sendInfo.fileListener.sendListener.OnSendFileFinished(sendInfo.sessionId, dFileList[0]);
1391     }
1392     return SOFTBUS_OK;
1393 }
1394 
TransProxyChannelSendFile(int32_t channelId,const char * sFileList[],const char * dFileList[],uint32_t fileCnt)1395 int32_t TransProxyChannelSendFile(int32_t channelId, const char *sFileList[], const char *dFileList[],
1396     uint32_t fileCnt)
1397 {
1398     if (SoftBusMutexLock(&g_sendFileInfo.lock) != 0) {
1399         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock mutex failed");
1400         return SOFTBUS_ERR;
1401     }
1402     SendListenerInfo sendInfo;
1403     memset_s(&sendInfo, sizeof(sendInfo), 0, sizeof(sendInfo));
1404     int32_t sessionId;
1405     int32_t ret = ClientGetSessionIdByChannelId(channelId, CHANNEL_TYPE_PROXY, &sessionId);
1406     if (ret != SOFTBUS_OK) {
1407         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get sessionId failed, channelId [%d]", channelId);
1408         goto EXIT_ERR;
1409     }
1410 
1411     char sessionName[SESSION_NAME_SIZE_MAX] = { 0 };
1412     if (ClientGetSessionDataById(sessionId, sessionName, SESSION_NAME_SIZE_MAX, KEY_SESSION_NAME)
1413         != SOFTBUS_OK) {
1414         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get sessionId name failed");
1415         goto EXIT_ERR;
1416     }
1417 
1418     sendInfo.channelId = channelId;
1419     sendInfo.sessionId = sessionId;
1420     if (TransGetFileListener(sessionName, &sendInfo.fileListener) != SOFTBUS_OK) {
1421         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get file listener failed");
1422         goto EXIT_ERR;
1423     }
1424     if (ProxySendFile(sendInfo, sFileList, dFileList, fileCnt) != SOFTBUS_OK) {
1425         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "proxy send file failed");
1426         goto EXIT_ERR;
1427     }
1428     SoftBusMutexUnlock(&g_sendFileInfo.lock);
1429     return SOFTBUS_OK;
1430 EXIT_ERR:
1431     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "send file trans error failed");
1432     if (sendInfo.fileListener.sendListener.OnFileTransError != NULL) {
1433         sendInfo.fileListener.sendListener.OnFileTransError(sendInfo.sessionId);
1434     }
1435     SoftBusMutexUnlock(&g_sendFileInfo.lock);
1436     return SOFTBUS_ERR;
1437 }
1438