• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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_file_manager.h"
17 
18 #include <inttypes.h>
19 #include <limits.h>
20 #include <securec.h>
21 #include <stdbool.h>
22 #include <string.h>
23 #include <unistd.h>
24 
25 #include "client_trans_pending.h"
26 #include "client_trans_proxy_manager.h"
27 #include "client_trans_session_manager.h"
28 #include "softbus_adapter_errcode.h"
29 #include "softbus_adapter_file.h"
30 #include "softbus_adapter_mem.h"
31 #include "softbus_app_info.h"
32 #include "softbus_def.h"
33 #include "softbus_errcode.h"
34 #include "softbus_utils.h"
35 #include "trans_log.h"
36 
37 static TransFileInfoLock g_sendFileInfoLock = {
38     .lock = 0,
39     .lockInitFlag = false,
40 };
41 static TransFileInfoLock g_recvFileInfoLock = {
42     .lock = 0,
43     .lockInitFlag = false,
44 };
45 static LIST_HEAD(g_sessionFileLockList);
46 static LIST_HEAD(g_sendListenerInfoList);
47 static LIST_HEAD(g_recvRecipientInfoList);
48 
ProxyChannelSendFileStream(int32_t channelId,const char * data,uint32_t len,int32_t type)49 static int32_t ProxyChannelSendFileStream(int32_t channelId, const char *data, uint32_t len, int32_t type)
50 {
51     ProxyChannelInfoDetail info;
52     if (ClientTransProxyGetInfoByChannelId(channelId, &info) != SOFTBUS_OK) {
53         TRANS_LOGE(TRANS_FILE, "client trans proxy get info by ChannelId fail");
54         return SOFTBUS_ERR;
55     }
56     return TransProxyPackAndSendData(channelId, data, len, &info, (SessionPktType)type);
57 }
58 
SendFileTransResult(int32_t channelId,uint32_t seq,int32_t result,uint32_t side)59 static int32_t SendFileTransResult(int32_t channelId, uint32_t seq, int32_t result, uint32_t side)
60 {
61     TRANS_LOGI(TRANS_FILE, "send file result seq=%{public}u, side=%{public}u, result=%{public}d", seq, side, result);
62     uint32_t len = FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + sizeof(uint32_t) + sizeof(int32_t);
63     char *data = (char *)SoftBusCalloc(len);
64     if (data == NULL) {
65         TRANS_LOGE(TRANS_FILE, "malloc failedLen=%{public}d.", len);
66         return SOFTBUS_MALLOC_ERR;
67     }
68     *(uint32_t *)data = FILE_MAGIC_NUMBER;
69     *(uint64_t *)(data + FRAME_MAGIC_OFFSET) = (FRAME_DATA_SEQ_OFFSET + sizeof(uint32_t) + sizeof(int32_t));
70     *(uint32_t *)(data + FRAME_HEAD_LEN) = seq;
71     *(uint32_t *)(data + FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET) = side;
72     *(int32_t *)(data + FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + sizeof(uint32_t)) = result;
73 
74     int32_t ret = ProxyChannelSendFileStream(channelId, data, len, TRANS_SESSION_FILE_RESULT_FRAME);
75     if (ret != SOFTBUS_OK) {
76         TRANS_LOGE(TRANS_FILE, "conn send file fail ret=%{public}d", ret);
77     }
78     SoftBusFree(data);
79     return ret;
80 }
81 
UnpackFileTransResultFrame(const uint8_t * data,uint32_t len,uint32_t * seq,int32_t * result,uint32_t * side)82 static int32_t UnpackFileTransResultFrame(const uint8_t *data, uint32_t len, uint32_t *seq,
83     int32_t *result, uint32_t *side)
84 {
85     if (seq == NULL || result == NULL || side == NULL) {
86         TRANS_LOGE(TRANS_FILE, "param invalid");
87         return SOFTBUS_ERR;
88     }
89     if (data == NULL || len < FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + FRAME_DATA_SEQ_OFFSET) {
90         TRANS_LOGE(TRANS_FILE, "recv ack fail. responseLen=%{public}u", len);
91         return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
92     }
93     uint32_t magic = *(uint32_t *)data;
94     uint64_t dataLen = *(uint64_t *)(data + FRAME_MAGIC_OFFSET);
95     if (magic != FILE_MAGIC_NUMBER || dataLen != (FRAME_DATA_SEQ_OFFSET + sizeof(uint32_t) + sizeof(int32_t))) {
96         TRANS_LOGE(TRANS_FILE,
97             "recv ack response head fail. magic=%{public}u, dataLen=%{public}" PRIu64, magic, dataLen);
98         return SOFTBUS_INVALID_DATA_HEAD;
99     }
100     (*seq) = (*(uint32_t *)(data + FRAME_HEAD_LEN));
101     (*side) = (*(uint32_t *)(data + FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET));
102     (*result) = (*(int32_t *)(data + FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + sizeof(uint32_t)));
103     TRANS_LOGI(TRANS_FILE, "seq=%{public}u, side=%{public}u, result=%{public}d", *seq, *side, *result);
104     return SOFTBUS_OK;
105 }
106 
ClearRecipientResources(FileRecipientInfo * info)107 static void ClearRecipientResources(FileRecipientInfo *info)
108 {
109     if (info->recvFileInfo.fileFd != INVALID_FD) {
110         (void)FileUnLock(info->recvFileInfo.fileFd);
111         SoftBusCloseFile(info->recvFileInfo.fileFd);
112         info->recvFileInfo.fileFd = INVALID_FD;
113     }
114     if (info->recvState == TRANS_FILE_RECV_ERR_STATE) {
115         SoftBusRemoveFile(info->recvFileInfo.filePath);
116         if (info->crc == APP_INFO_FILE_FEATURES_SUPPORT) {
117             (void)SendFileTransResult(info->channelId, info->recvFileInfo.seq, SOFTBUS_ERR, IS_RECV_RESULT);
118         }
119 
120         if (info->fileListener.socketRecvCallback != NULL) {
121             FileEvent event = {.type = FILE_EVENT_RECV_ERROR};
122             info->fileListener.socketRecvCallback(info->sessionId, &event);
123         } else if (info->fileListener.recvListener.OnFileTransError != NULL) {
124             info->fileListener.recvListener.OnFileTransError(info->sessionId);
125         }
126     }
127 }
SetRecipientRecvState(FileRecipientInfo * recipient,int32_t state)128 static void SetRecipientRecvState(FileRecipientInfo *recipient, int32_t state)
129 {
130     if (SoftBusMutexLock(&g_recvFileInfoLock.lock) != SOFTBUS_OK) {
131         return;
132     }
133     if (recipient->recvState != TRANS_FILE_RECV_ERR_STATE) {
134         recipient->recvState = state;
135         if (state == TRANS_FILE_RECV_IDLE_STATE) {
136             recipient->recvFileInfo.fileStatus = NODE_IDLE;
137         }
138     }
139     (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
140 }
141 
ProxyFileTransTimerProc(void)142 static void ProxyFileTransTimerProc(void)
143 {
144 #define FILE_TRANS_TIMEOUT 10
145     if (SoftBusMutexLock(&g_recvFileInfoLock.lock) != SOFTBUS_OK) {
146         TRANS_LOGE(TRANS_FILE, "lock file timer failed");
147         return;
148     }
149     FileRecipientInfo *info = NULL;
150     FileRecipientInfo *next = NULL;
151     LIST_FOR_EACH_ENTRY_SAFE(info, next, &g_recvRecipientInfoList, FileRecipientInfo, node) {
152         if (info->recvState == TRANS_FILE_RECV_IDLE_STATE) {
153             continue;
154         }
155         if (info->recvFileInfo.timeOut >= FILE_TRANS_TIMEOUT) {
156             TRANS_LOGE(TRANS_FILE, "recv timeout, filePath=%{public}s, recvState=%{public}d",
157                 info->recvFileInfo.filePath, info->recvState);
158             info->recvFileInfo.fileStatus = NODE_ERR;
159             info->recvState = TRANS_FILE_RECV_ERR_STATE;
160             info->recvFileInfo.timeOut = 0;
161             info->objRefCount--;
162             ListDelete(&info->node);
163             if (info->objRefCount == 0) {
164                 ClearRecipientResources(info);
165                 SoftBusFree(info);
166             }
167         } else {
168             info->recvFileInfo.timeOut++;
169         }
170     }
171     (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
172 }
173 
ClinetTransProxyFileManagerInit(void)174 int32_t ClinetTransProxyFileManagerInit(void)
175 {
176     if (g_sendFileInfoLock.lockInitFlag == false) {
177         if (SoftBusMutexInit(&g_sendFileInfoLock.lock, NULL) != SOFTBUS_OK) {
178             TRANS_LOGE(TRANS_FILE, "sendfile mutex init fail!");
179             return SOFTBUS_ERR;
180         }
181         g_sendFileInfoLock.lockInitFlag = true;
182     }
183     if (g_recvFileInfoLock.lockInitFlag == false) {
184         if (SoftBusMutexInit(&g_recvFileInfoLock.lock, NULL) != SOFTBUS_OK) {
185             TRANS_LOGE(TRANS_FILE, "recvfile mutex init fail!");
186             return SOFTBUS_ERR;
187         }
188         g_recvFileInfoLock.lockInitFlag = true;
189     }
190     if (InitPendingPacket() != SOFTBUS_OK) {
191         TRANS_LOGE(TRANS_FILE, "InitPendingPacket fail!");
192         return SOFTBUS_ERR;
193     }
194     if (RegisterTimeoutCallback(SOFTBUS_PROXY_SENDFILE_TIMER_FUN, ProxyFileTransTimerProc) != SOFTBUS_OK) {
195         TRANS_LOGE(TRANS_FILE, "register sendfile timer fail");
196     }
197     return SOFTBUS_OK;
198 }
199 
ClinetTransProxyFileManagerDeinit(void)200 void ClinetTransProxyFileManagerDeinit(void)
201 {
202     (void)RegisterTimeoutCallback(SOFTBUS_PROXY_SENDFILE_TIMER_FUN, NULL);
203     if (SoftBusMutexDestroy(&g_sendFileInfoLock.lock) != SOFTBUS_OK) {
204         TRANS_LOGE(TRANS_FILE, "destroy send file lock fail");
205     }
206     g_sendFileInfoLock.lockInitFlag = false;
207     if (SoftBusMutexDestroy(&g_recvFileInfoLock.lock) != SOFTBUS_OK) {
208         TRANS_LOGE(TRANS_FILE, "destroy recv file lock fail");
209     }
210     g_recvFileInfoLock.lockInitFlag = false;
211 }
212 
SendFileAckReqAndResData(int32_t channelId,uint32_t startSeq,uint32_t value,int32_t type)213 static int32_t SendFileAckReqAndResData(int32_t channelId, uint32_t startSeq, uint32_t value, int32_t type)
214 {
215     uint32_t len = FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + FRAME_DATA_SEQ_OFFSET;
216     char *data = (char *)SoftBusCalloc(len);
217     if (data == NULL) {
218         TRANS_LOGE(TRANS_FILE, "calloc fail! len=%{public}d.", len);
219         return SOFTBUS_MALLOC_ERR;
220     }
221     *(uint32_t *)data = FILE_MAGIC_NUMBER;
222     *(int64_t *)(data + FRAME_MAGIC_OFFSET) = (FRAME_DATA_SEQ_OFFSET + FRAME_DATA_SEQ_OFFSET);
223     *(uint32_t *)(data + FRAME_HEAD_LEN) = startSeq;
224     *(uint32_t *)(data + FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET) = value;
225     int32_t ret = ProxyChannelSendFileStream(channelId, data, len, type);
226     if (ret != SOFTBUS_OK) {
227         TRANS_LOGE(TRANS_FILE, "conn send ack buf fail ret=%{public}d.", ret);
228     }
229     SoftBusFree(data);
230     return ret;
231 }
232 
UnpackAckReqAndResData(FileFrame * frame,uint32_t * startSeq,uint32_t * value)233 static int32_t UnpackAckReqAndResData(FileFrame *frame, uint32_t *startSeq, uint32_t *value)
234 {
235     if (frame == NULL || startSeq == NULL || value == NULL || frame->data == NULL) {
236         return SOFTBUS_INVALID_PARAM;
237     }
238     if (frame->frameLength < FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + FRAME_DATA_SEQ_OFFSET) {
239         TRANS_LOGE(TRANS_FILE, "unpack ack data fail. frameLen=%{public}d", frame->frameLength);
240         return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
241     }
242     frame->magic = (*(uint32_t *)(frame->data));
243     uint64_t dataLen = (*(uint64_t *)(frame->data + FRAME_MAGIC_OFFSET));
244     if (frame->magic != FILE_MAGIC_NUMBER || dataLen < FRAME_DATA_SEQ_OFFSET + FRAME_DATA_SEQ_OFFSET) {
245         TRANS_LOGE(TRANS_FILE, "unpack ack head fail. magic=%{public}u, dataLen=%{public}" PRIu64,
246             frame->magic, dataLen);
247         return SOFTBUS_INVALID_DATA_HEAD;
248     }
249     frame->fileData = frame->data + FRAME_HEAD_LEN;
250     (*startSeq) = (*(uint32_t *)(frame->fileData));
251     (*value) = (*(uint32_t *)(frame->fileData + FRAME_DATA_SEQ_OFFSET));
252     return SOFTBUS_OK;
253 }
254 
PackReadFileData(FileFrame * fileFrame,uint64_t readLength,uint64_t fileOffset,SendListenerInfo * info)255 static int64_t PackReadFileData(FileFrame *fileFrame, uint64_t readLength, uint64_t fileOffset,
256     SendListenerInfo *info)
257 {
258     int64_t len = SoftBusPreadFile(info->fd, fileFrame->fileData + FRAME_DATA_SEQ_OFFSET, readLength, fileOffset);
259     if (len <= 0) {
260         TRANS_LOGE(TRANS_FILE, "pread src file failed. ret=%{public}" PRId64, len);
261         return len;
262     }
263     if (info->crc == APP_INFO_FILE_FEATURES_SUPPORT) {
264         uint64_t dataLen = len + FRAME_DATA_SEQ_OFFSET;
265         fileFrame->frameLength = FRAME_HEAD_LEN + dataLen + FRAME_CRC_LEN;
266         if (fileFrame->frameLength > PROXY_MAX_PACKET_SIZE) {
267             TRANS_LOGE(TRANS_FILE, "frameLength invalid. frameLength=%{public}u", fileFrame->frameLength);
268             return SOFTBUS_ERR;
269         }
270         uint16_t crc = RTU_CRC(fileFrame->fileData + FRAME_DATA_SEQ_OFFSET, len);
271         (*(uint32_t *)(fileFrame->data)) = fileFrame->magic;
272         (*(uint64_t *)(fileFrame->data + FRAME_MAGIC_OFFSET)) = dataLen;
273         info->seq++;
274         (*(uint32_t *)(fileFrame->fileData)) = info->seq;
275         (*(uint16_t *)(fileFrame->fileData + dataLen)) = crc;
276         info->checkSumCRC += crc;
277     } else {
278         fileFrame->frameLength = FRAME_DATA_SEQ_OFFSET + len;
279         if (fileFrame->frameLength > PROXY_MAX_PACKET_SIZE) {
280             TRANS_LOGE(TRANS_FILE, "frameLength invalid. frameLength=%{public}u", fileFrame->frameLength);
281             return SOFTBUS_ERR;
282         }
283         (*(int32_t *)(fileFrame->fileData)) = info->channelId;
284     }
285     return len;
286 }
287 
PackReadFileRetransData(FileFrame * fileFrame,uint32_t seq,uint64_t readLength,uint64_t fileOffset,const SendListenerInfo * info)288 static int64_t PackReadFileRetransData(FileFrame *fileFrame, uint32_t seq, uint64_t readLength, uint64_t fileOffset,
289     const SendListenerInfo *info)
290 {
291     int64_t len = SoftBusPreadFile(info->fd, fileFrame->fileData + FRAME_DATA_SEQ_OFFSET, readLength, fileOffset);
292     if (len <= 0) {
293         TRANS_LOGE(TRANS_FILE, "pread src file failed. ret=%{public}" PRId64, len);
294         return len;
295     }
296     uint64_t dataLen = len + FRAME_DATA_SEQ_OFFSET;
297     fileFrame->frameLength = FRAME_HEAD_LEN + dataLen + FRAME_CRC_LEN;
298     if (fileFrame->frameLength > PROXY_MAX_PACKET_SIZE) {
299         TRANS_LOGE(TRANS_FILE, "frameLength invalid. frameLength=%{public}u", fileFrame->frameLength);
300         return SOFTBUS_ERR;
301     }
302     uint16_t crc = RTU_CRC(fileFrame->fileData + FRAME_DATA_SEQ_OFFSET, len);
303     (*(uint32_t *)(fileFrame->data)) = fileFrame->magic;
304     (*(uint64_t *)(fileFrame->data + FRAME_MAGIC_OFFSET)) = dataLen;
305     (*(uint32_t *)(fileFrame->fileData)) = seq;
306     (*(uint16_t *)(fileFrame->fileData + dataLen)) = crc;
307 
308     int32_t ret = ProxyChannelSendFileStream(info->channelId, (char *)fileFrame->data,
309         fileFrame->frameLength, FrameIndexToType((uint64_t)seq, info->frameNum));
310     if (ret != SOFTBUS_OK) {
311         TRANS_LOGE(TRANS_FILE, "conn send buf fail ret=%{public}d", ret);
312         return ret;
313     }
314     return len;
315 }
316 
UnpackFileDataFrame(FileRecipientInfo * info,FileFrame * fileFrame,uint32_t * fileDataLen)317 static int32_t UnpackFileDataFrame(FileRecipientInfo *info, FileFrame *fileFrame, uint32_t *fileDataLen)
318 {
319     if (info->crc == APP_INFO_FILE_FEATURES_SUPPORT) {
320         if (fileFrame->frameLength <= FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + FRAME_CRC_LEN) {
321             TRANS_LOGE(TRANS_FILE, "frameLength invalid. frameLength=%{public}u", fileFrame->frameLength);
322             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
323         }
324         fileFrame->magic = (*(uint32_t *)(fileFrame->data));
325         uint64_t dataLen = (*(uint64_t *)(fileFrame->data + FRAME_MAGIC_OFFSET));
326         if (fileFrame->magic != FILE_MAGIC_NUMBER ||
327             (dataLen + FRAME_HEAD_LEN + FRAME_CRC_LEN) != fileFrame->frameLength) {
328             TRANS_LOGE(TRANS_FILE, "unpack data frame failed. magic=%{public}u, dataLen=%{public}" PRIu64,
329                 fileFrame->magic, dataLen);
330             return SOFTBUS_INVALID_DATA_HEAD;
331         }
332         fileFrame->fileData = fileFrame->data + FRAME_HEAD_LEN;
333         fileFrame->seq = (*(uint32_t *)(fileFrame->fileData));
334         uint16_t recvCRC = (*(uint16_t *)(fileFrame->fileData + dataLen));
335         uint16_t crc = RTU_CRC(fileFrame->fileData + FRAME_DATA_SEQ_OFFSET, dataLen - FRAME_DATA_SEQ_OFFSET);
336         if (crc != recvCRC) {
337             TRANS_LOGE(TRANS_FILE, "crc check fail recvCrc=%{public}u, crc=%{public}u",
338                 (uint32_t)recvCRC, (uint32_t)crc);
339             return SOFTBUS_ERR;
340         }
341         *fileDataLen = dataLen;
342         fileFrame->crc = crc;
343     } else {
344         fileFrame->fileData = fileFrame->data;
345         if (fileFrame->frameLength <= FRAME_DATA_SEQ_OFFSET) {
346             TRANS_LOGE(TRANS_FILE, "frameLength invalid. frameLength=%{public}u", fileFrame->frameLength);
347             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
348         }
349         fileFrame->seq = (*(uint32_t *)(fileFrame->fileData));
350         *fileDataLen = fileFrame->frameLength;
351     }
352     return SOFTBUS_OK;
353 }
354 
RetransFileFrameBySeq(const SendListenerInfo * info,int32_t seq)355 static int32_t RetransFileFrameBySeq(const SendListenerInfo *info, int32_t seq)
356 {
357     if ((info != NULL) && (info->crc != APP_INFO_FILE_FEATURES_SUPPORT)) {
358         return SOFTBUS_OK;
359     }
360     if ((info == NULL) || (seq <= 0)) {
361         TRANS_LOGE(TRANS_FILE, "param invalid");
362         return SOFTBUS_INVALID_PARAM;
363     }
364     FileFrame fileFrame = {0};
365     fileFrame.data = (uint8_t *)SoftBusCalloc(PROXY_MAX_PACKET_SIZE);
366     if (fileFrame.data == NULL) {
367         TRANS_LOGE(TRANS_FILE, "data calloc fail");
368         return SOFTBUS_MALLOC_ERR;
369     }
370     fileFrame.magic = FILE_MAGIC_NUMBER;
371     fileFrame.fileData = fileFrame.data + FRAME_HEAD_LEN;
372     uint64_t frameDataSize = PROXY_MAX_PACKET_SIZE - FRAME_HEAD_LEN - FRAME_DATA_SEQ_OFFSET - FRAME_CRC_LEN;
373     uint64_t fileOffset = frameDataSize * ((uint32_t)seq - 1);
374     if (fileOffset >= info->fileSize) {
375         TRANS_LOGE(TRANS_FILE, "retrans file frame failed, seq=%{public}d", seq);
376         SoftBusFree(fileFrame.data);
377         return SOFTBUS_INVALID_PARAM;
378     }
379     uint64_t remainedSize = info->fileSize - fileOffset;
380     uint64_t readLength = (remainedSize < frameDataSize) ? remainedSize : frameDataSize;
381     int64_t len = PackReadFileRetransData(&fileFrame, seq, readLength, fileOffset, info);
382     if (len <= 0) {
383         TRANS_LOGE(TRANS_FILE, "retrans file frame failed");
384         SoftBusFree(fileFrame.data);
385         return SOFTBUS_ERR;
386     }
387     SoftBusFree(fileFrame.data);
388     return SOFTBUS_OK;
389 }
390 
AckResponseDataHandle(const SendListenerInfo * info,const char * data,uint32_t len)391 static int32_t AckResponseDataHandle(const SendListenerInfo *info, const char *data, uint32_t len)
392 {
393     if (data == NULL || len != sizeof(AckResponseData)) {
394         TRANS_LOGE(TRANS_FILE, "data or len invalid");
395         return SOFTBUS_OK;
396     }
397     AckResponseData *resData = (AckResponseData *)data;
398     uint32_t startSeq = resData->startSeq;
399     uint32_t seqResult = resData->seqResult;
400     if (seqResult != FILE_SEND_ACK_RESULT_SUCCESS) {
401         uint32_t failSeq;
402         for (int32_t i = 0; i < FILE_SEND_ACK_INTERVAL; i++) {
403             if (((seqResult >> i) & 0x01) == 0x01) {
404                 continue;
405             }
406             failSeq = startSeq + i;
407             if (RetransFileFrameBySeq(info, (int32_t)failSeq) != SOFTBUS_OK) {
408                 return SOFTBUS_ERR;
409             }
410         }
411     }
412     return SOFTBUS_OK;
413 }
414 
GetFullRecvPath(const char * filePath,const char * recvRootDir)415 static char *GetFullRecvPath(const char *filePath, const char *recvRootDir)
416 {
417     if ((filePath == NULL) || (recvRootDir == NULL)) {
418         TRANS_LOGE(TRANS_FILE, "filePath or rootDir is null");
419         return NULL;
420     }
421     int32_t rootDirLength = (int32_t)strlen(recvRootDir);
422     int32_t filePathLength = (int32_t)strlen(filePath);
423     bool isNeedAddSep = true;
424     if (((filePathLength > 0) && (filePath[0] == PATH_SEPARATOR)) ||
425         ((rootDirLength > 0) && (recvRootDir[rootDirLength - 1] == PATH_SEPARATOR))) {
426         isNeedAddSep = false;
427     }
428     int32_t destFullPathLength = (int32_t)((isNeedAddSep) ? (rootDirLength + sizeof('/') + filePathLength) :
429         (rootDirLength + filePathLength));
430     char *recvFullPath = (char *)SoftBusCalloc(destFullPathLength + 1);
431     if (recvFullPath == NULL) {
432         TRANS_LOGE(TRANS_FILE, "recvFullPath is null");
433         return NULL;
434     }
435     int32_t ret;
436     if (isNeedAddSep) {
437         ret = sprintf_s(recvFullPath, destFullPathLength + 1, "%s%c%s", recvRootDir, PATH_SEPARATOR, filePath);
438     } else {
439         ret = sprintf_s(recvFullPath, destFullPathLength + 1, "%s%s", recvRootDir, filePath);
440     }
441     if (ret < 0) {
442         TRANS_LOGE(TRANS_FILE, "create fullPath fail");
443         SoftBusFree(recvFullPath);
444         return NULL;
445     }
446     return recvFullPath;
447 }
448 
GetDirPath(const char * fullPath,char * dirPath,int32_t dirPathLen)449 static int32_t GetDirPath(const char *fullPath, char *dirPath, int32_t dirPathLen)
450 {
451     if ((fullPath == NULL) || (strlen(fullPath) < 1) || (fullPath[strlen(fullPath) - 1] == PATH_SEPARATOR)) {
452         TRANS_LOGE(TRANS_FILE, "invalid input param");
453         return SOFTBUS_INVALID_PARAM;
454     }
455     int32_t i = 0;
456     int32_t dirFullLen = (int32_t)strlen(fullPath);
457     for (i = dirFullLen - 1; i >= 0; i--) {
458         if (fullPath[i] == PATH_SEPARATOR) {
459             i++;
460             break;
461         }
462         if (i == 0) {
463             break;
464         }
465     }
466     int32_t dirLen = i;
467     if (dirLen >= dirPathLen) {
468         TRANS_LOGE(TRANS_FILE, "dirLen >= dirPathLen. dirLen=%{public}d, dirPathLen=%{public}d", dirLen, dirPathLen);
469         return SOFTBUS_INVALID_PARAM;
470     }
471     if (strncpy_s(dirPath, dirPathLen, fullPath, dirLen) != EOK) {
472         TRANS_LOGE(TRANS_FILE, "strcpy_s dir path error, dirLen=%{public}d", dirLen);
473         return SOFTBUS_MEM_ERR;
474     }
475     return SOFTBUS_OK;
476 }
477 
GetAbsFullPath(const char * fullPath,char * recvAbsPath,int32_t pathSize)478 static int32_t GetAbsFullPath(const char *fullPath, char *recvAbsPath, int32_t pathSize)
479 {
480     char *dirPath = (char *)SoftBusCalloc(MAX_FILE_PATH_NAME_LEN);
481     if (dirPath == NULL) {
482         return SOFTBUS_MALLOC_ERR;
483     }
484     if (GetDirPath(fullPath, dirPath, MAX_FILE_PATH_NAME_LEN) != SOFTBUS_OK) {
485         TRANS_LOGE(TRANS_FILE, "get dir path failed");
486         SoftBusFree(dirPath);
487         return SOFTBUS_INVALID_PARAM;
488     }
489     char *absFullDir = (char *)SoftBusCalloc(PATH_MAX + 1);
490     if (absFullDir == NULL) {
491         TRANS_LOGE(TRANS_FILE, "calloc absFullDir failed");
492         SoftBusFree(dirPath);
493         return SOFTBUS_MALLOC_ERR;
494     }
495     int32_t fileNameLength = -1;
496     int32_t dirPathLength = -1;
497     const char *fileName = TransGetFileName(fullPath);
498     if (fileName == NULL) {
499         TRANS_LOGE(TRANS_FILE, "get file name failed");
500         goto EXIT_ERR;
501     }
502     if (GetAndCheckRealPath(dirPath, absFullDir) != SOFTBUS_OK) {
503         TRANS_LOGE(TRANS_FILE, "get full abs file failed");
504         goto EXIT_ERR;
505     }
506     TRANS_LOGI(TRANS_FILE, "dirPath=%{public}s, absFullDir=%{public}s", dirPath, absFullDir);
507     fileNameLength = (int32_t)strlen(fileName);
508     dirPathLength = (int32_t)strlen(absFullDir);
509     if (pathSize < (fileNameLength + dirPathLength + 1)) {
510         TRANS_LOGE(TRANS_FILE, "copy name is too large, dirLen=%{public}d, fileNameLen=%{public}d",
511             dirPathLength, fileNameLength);
512         goto EXIT_ERR;
513     }
514     TRANS_LOGI(TRANS_FILE, "fileName=%{public}s, fileNameLen=%{public}d", fileName, fileNameLength);
515     if (sprintf_s(recvAbsPath, pathSize, "%s/%s", absFullDir, fileName) < 0) {
516         TRANS_LOGE(TRANS_FILE, "sprintf_s filename error");
517         goto EXIT_ERR;
518     }
519     TRANS_LOGI(TRANS_FILE, "recvAbsPath=%{public}s", recvAbsPath);
520     SoftBusFree(absFullDir);
521     SoftBusFree(dirPath);
522     return SOFTBUS_OK;
523 EXIT_ERR:
524     SoftBusFree(dirPath);
525     SoftBusFree(absFullDir);
526     return SOFTBUS_ERR;
527 }
528 
CreateDirAndGetAbsPath(const char * filePath,char * recvAbsPath,int32_t pathSize)529 static int32_t CreateDirAndGetAbsPath(const char *filePath, char *recvAbsPath, int32_t pathSize)
530 {
531     if ((filePath == NULL) || (recvAbsPath == NULL)) {
532         TRANS_LOGE(TRANS_FILE, "invalid input");
533         return SOFTBUS_INVALID_PARAM;
534     }
535     uint32_t len = (uint32_t)strlen(filePath);
536     int32_t ret;
537     char *tempPath = (char *)SoftBusCalloc(len + 1);
538     if (tempPath == NULL) {
539         TRANS_LOGE(TRANS_FILE, "calloc tempPath failed");
540         return SOFTBUS_MALLOC_ERR;
541     }
542     for (uint32_t i = 0; i < len; i++) {
543         tempPath[i] = filePath[i];
544         if (tempPath[i] != PATH_SEPARATOR) {
545             continue;
546         }
547         if (SoftBusAccessFile(tempPath, SOFTBUS_F_OK) != SOFTBUS_OK) {
548             ret = SoftBusMakeDir(tempPath, DEFAULT_NEW_PATH_AUTHORITY);
549             if (ret == SOFTBUS_ADAPTER_ERR) {
550                 TRANS_LOGE(TRANS_FILE, "mkdir failed errno=%{public}d", errno);
551                 SoftBusFree(tempPath);
552                 return SOFTBUS_ERR;
553             }
554         }
555     }
556 
557     SoftBusFree(tempPath);
558     ret = GetAbsFullPath(filePath, recvAbsPath, pathSize);
559     if (ret != SOFTBUS_OK) {
560         TRANS_LOGI(TRANS_FILE, "dest dir is invalid");
561         return ret;
562     }
563     return SOFTBUS_OK;
564 }
565 
GetSessionFileLock(int32_t channelId)566 static ProxyFileMutexLock *GetSessionFileLock(int32_t channelId)
567 {
568     if (SoftBusMutexLock(&g_sendFileInfoLock.lock) != 0) {
569         TRANS_LOGE(TRANS_FILE, "lock mutex failed");
570         return NULL;
571     }
572     ProxyFileMutexLock *item = NULL;
573     ProxyFileMutexLock *sessionLock = NULL;
574     LIST_FOR_EACH_ENTRY(item, &g_sessionFileLockList, ProxyFileMutexLock, node) {
575         if (item->channelId == channelId) {
576             sessionLock = item;
577             break;
578         }
579     }
580     if (sessionLock != NULL) {
581         sessionLock->count++;
582         (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
583         return sessionLock;
584     }
585     sessionLock = (ProxyFileMutexLock *)SoftBusCalloc(sizeof(ProxyFileMutexLock));
586     if (sessionLock == NULL) {
587         (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
588         return NULL;
589     }
590     if (SoftBusMutexInit(&sessionLock->sendLock, NULL) != SOFTBUS_OK) {
591         (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
592         SoftBusFree(sessionLock);
593         return NULL;
594     }
595     ListInit(&sessionLock->node);
596     sessionLock->count = 1;
597     sessionLock->channelId = channelId;
598     ListAdd(&g_sessionFileLockList, &sessionLock->node);
599     TRANS_LOGI(TRANS_FILE, "add channelId=%{public}d", channelId);
600     (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
601     return sessionLock;
602 }
603 
DelSessionFileLock(ProxyFileMutexLock * sessionLock)604 static void DelSessionFileLock(ProxyFileMutexLock *sessionLock)
605 {
606     if (sessionLock == NULL) {
607         return;
608     }
609 
610     if (SoftBusMutexLock(&g_sendFileInfoLock.lock) != SOFTBUS_OK) {
611         TRANS_LOGE(TRANS_FILE, "lock mutex failed");
612         return;
613     }
614     sessionLock->count--;
615     if (sessionLock->count == 0) {
616         ListDelete(&sessionLock->node);
617         (void)SoftBusMutexDestroy(&sessionLock->sendLock);
618         SoftBusFree(sessionLock);
619     }
620     (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
621 }
622 
AddSendListenerInfo(SendListenerInfo * info)623 static int32_t AddSendListenerInfo(SendListenerInfo *info)
624 {
625     if (info == NULL) {
626         TRANS_LOGW(TRANS_FILE, "add send listener info invalid param.");
627         return SOFTBUS_INVALID_PARAM;
628     }
629     if (SoftBusMutexLock(&g_sendFileInfoLock.lock) != SOFTBUS_OK) {
630         TRANS_LOGE(TRANS_FILE, "proxy add send info lock fail");
631         return SOFTBUS_LOCK_ERR;
632     }
633     SendListenerInfo *item = NULL;
634     LIST_FOR_EACH_ENTRY(item, &g_sendListenerInfoList, SendListenerInfo, node) {
635         if (item->sessionId == info->sessionId) {
636             (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
637             return SOFTBUS_ALREADY_EXISTED;
638         }
639     }
640     ListTailInsert(&g_sendListenerInfoList, &info->node);
641     (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
642     return SOFTBUS_OK;
643 }
644 
DelSendListenerInfo(SendListenerInfo * info)645 static void DelSendListenerInfo(SendListenerInfo *info)
646 {
647     if (info == NULL) {
648         TRANS_LOGW(TRANS_FILE, "invalid param.");
649         return;
650     }
651     if (SoftBusMutexLock(&g_sendFileInfoLock.lock) != SOFTBUS_OK) {
652         TRANS_LOGE(TRANS_FILE, "mutex lock error.");
653         return;
654     }
655     ListDelete(&info->node);
656     TRANS_LOGI(TRANS_FILE, "delete sessionId = %{public}d", info->sessionId);
657     (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
658 }
659 
PackFileTransStartInfo(FileFrame * fileFrame,const char * destFile,uint64_t fileSize,const SendListenerInfo * info)660 static int32_t PackFileTransStartInfo(FileFrame *fileFrame, const char *destFile, uint64_t fileSize,
661     const SendListenerInfo *info)
662 {
663     if ((info == NULL) || (fileFrame == NULL) || (destFile == NULL)) {
664         TRANS_LOGW(TRANS_FILE, "invalid param.");
665         return SOFTBUS_INVALID_PARAM;
666     }
667     int32_t len = (int32_t)strlen(destFile);
668     if (info->crc == APP_INFO_FILE_FEATURES_SUPPORT) {
669         uint64_t dataLen = len + FRAME_DATA_SEQ_OFFSET + sizeof(uint64_t);
670         fileFrame->frameLength = FRAME_HEAD_LEN + dataLen;
671         if (fileFrame->frameLength > PROXY_MAX_PACKET_SIZE) {
672             TRANS_LOGE(TRANS_FILE, "frameLength overSize");
673             return SOFTBUS_ERR;
674         }
675         // magic(4 byte) + dataLen(8 byte) + oneFrameLen(4 byte) + fileSize + fileName
676         (*(uint32_t *)(fileFrame->data)) = fileFrame->magic;
677         (*(uint64_t *)(fileFrame->data + FRAME_MAGIC_OFFSET)) = dataLen;
678         (*(uint32_t *)(fileFrame->fileData)) =
679             PROXY_MAX_PACKET_SIZE - FRAME_HEAD_LEN - FRAME_DATA_SEQ_OFFSET - FRAME_CRC_LEN;
680         (*(uint64_t *)(fileFrame->fileData + FRAME_DATA_SEQ_OFFSET)) = fileSize;
681         if (memcpy_s(fileFrame->fileData + FRAME_DATA_SEQ_OFFSET + sizeof(uint64_t), len, destFile, len) != EOK) {
682             return SOFTBUS_MEM_ERR;
683         }
684     } else {
685         // seq(4byte) + fileName
686         fileFrame->frameLength = FRAME_DATA_SEQ_OFFSET + len;
687         if (fileFrame->frameLength > PROXY_MAX_PACKET_SIZE) {
688             return SOFTBUS_ERR;
689         }
690         (*(int32_t *)(fileFrame->fileData)) = info->channelId;
691         if (memcpy_s(fileFrame->fileData + FRAME_DATA_SEQ_OFFSET, len, destFile, len) != EOK) {
692             return SOFTBUS_MEM_ERR;
693         }
694     }
695     return SOFTBUS_OK;
696 }
697 
UnpackFileTransStartInfo(FileFrame * fileFrame,const FileRecipientInfo * info,SingleFileInfo * file)698 static int32_t UnpackFileTransStartInfo(FileFrame *fileFrame, const FileRecipientInfo *info, SingleFileInfo *file)
699 {
700     if ((info == NULL) || (fileFrame == NULL) || (file == NULL)) {
701         TRANS_LOGW(TRANS_FILE, "invalid param.");
702         return SOFTBUS_INVALID_PARAM;
703     }
704     uint8_t *fileNameData = NULL;
705     uint64_t fileNameLen = 0;
706     if (info->crc == APP_INFO_FILE_FEATURES_SUPPORT) {
707         if (fileFrame->frameLength < FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET) {
708             TRANS_LOGE(TRANS_FILE, "frameLength invalid");
709             return SOFTBUS_INVALID_PARAM;
710         }
711         // magic(4 byte) + dataLen(8 byte) + oneFrameLen(4 byte) + fileSize(8 byte) + fileName
712         fileFrame->magic = (*(uint32_t *)(fileFrame->data));
713         uint64_t dataLen = (*(uint64_t *)(fileFrame->data + FRAME_MAGIC_OFFSET));
714         if (FRAME_HEAD_LEN + dataLen > fileFrame->frameLength) {
715             return SOFTBUS_ERR;
716         }
717         if (fileFrame->magic != FILE_MAGIC_NUMBER || dataLen < (FRAME_DATA_SEQ_OFFSET + sizeof(uint64_t))) {
718             TRANS_LOGE(TRANS_FILE, "start info fail magic=%{public}X dataLen=%{public}" PRIu64,
719                 fileFrame->magic, dataLen);
720             return SOFTBUS_ERR;
721         }
722         fileFrame->fileData = fileFrame->data + FRAME_HEAD_LEN;
723         file->oneFrameLen = (*(uint32_t *)(fileFrame->fileData));
724         file->fileSize = (*(uint64_t *)(fileFrame->fileData + FRAME_DATA_SEQ_OFFSET));
725         fileNameLen = dataLen - FRAME_DATA_SEQ_OFFSET - sizeof(uint64_t);
726         if (fileNameLen > 0) {
727             fileNameData = fileFrame->fileData + FRAME_DATA_SEQ_OFFSET + sizeof(uint64_t);
728         }
729         file->startSeq = file->preStartSeq = 1;
730         file->seqResult = file->preSeqResult = 0;
731     } else {
732         // seq(4byte) + fileName
733         if (fileFrame->frameLength < FRAME_DATA_SEQ_OFFSET) {
734             return SOFTBUS_ERR;
735         }
736         fileFrame->fileData = fileFrame->data;
737         fileNameLen = fileFrame->frameLength - FRAME_DATA_SEQ_OFFSET;
738         file->seq = (*(uint32_t *)(fileFrame->fileData));
739         if (fileNameLen > 0) {
740             fileNameData = fileFrame->fileData + FRAME_DATA_SEQ_OFFSET;
741         }
742     }
743     if (fileNameLen > MAX_FILE_PATH_NAME_LEN) {
744         TRANS_LOGE(TRANS_FILE, "start info fail fileNameLen=%{public}" PRIu64, fileNameLen);
745         return SOFTBUS_INVALID_PARAM;
746     }
747     if (fileNameData != NULL && memcpy_s(file->filePath, MAX_FILE_PATH_NAME_LEN, fileNameData, fileNameLen) != EOK)  {
748         return SOFTBUS_MEM_ERR;
749     }
750     return SOFTBUS_OK;
751 }
752 
GetAndCheckFileSize(const char * sourceFile,uint64_t * fileSize,uint64_t * frameNum,int32_t crc)753 static int32_t GetAndCheckFileSize(const char *sourceFile, uint64_t *fileSize, uint64_t *frameNum, int32_t crc)
754 {
755     if ((sourceFile == NULL) || (fileSize == NULL) || (frameNum == NULL)) {
756         TRANS_LOGE(TRANS_FILE, "get file size num params invalid");
757         return SOFTBUS_INVALID_PARAM;
758     }
759 
760     if (SoftBusGetFileSize(sourceFile, fileSize) != SOFTBUS_OK) {
761         TRANS_LOGE(TRANS_FILE, "get file size fail");
762         return SOFTBUS_FILE_ERR;
763     }
764 
765     if (*fileSize > MAX_FILE_SIZE) {
766         TRANS_LOGE(TRANS_FILE, "file is too large, fileSize=%{public}" PRIu64, *fileSize);
767         return SOFTBUS_FILE_ERR;
768     }
769 
770     uint64_t oneFrameSize = PROXY_MAX_PACKET_SIZE - FRAME_DATA_SEQ_OFFSET;
771     if (crc == APP_INFO_FILE_FEATURES_SUPPORT) {
772         oneFrameSize -= (FRAME_HEAD_LEN + FRAME_CRC_LEN);
773     }
774     uint64_t frameNumTemp = (*fileSize) / oneFrameSize;
775     if (((*fileSize) % oneFrameSize) != 0) {
776         frameNumTemp++;
777     }
778 
779     /* add 1 means reserve frame to send destFile string */
780     frameNumTemp++;
781     *frameNum = frameNumTemp;
782     return SOFTBUS_OK;
783 }
784 
SendOneFrameFront(SendListenerInfo * info,int32_t frameType)785 static int32_t SendOneFrameFront(SendListenerInfo *info, int32_t frameType)
786 {
787     if (info == NULL) {
788         TRANS_LOGW(TRANS_FILE, "invalid param.");
789         return SOFTBUS_INVALID_PARAM;
790     }
791     if (info->crc != APP_INFO_FILE_FEATURES_SUPPORT) {
792         return SOFTBUS_OK;
793     }
794     if (frameType == TRANS_SESSION_FILE_FIRST_FRAME) {
795         if (CreatePendingPacket(info->sessionId, 0) != SOFTBUS_OK) {
796             return SOFTBUS_ERR;
797         }
798         info->waitSeq = 0;
799         info->waitTimeoutCount = 0;
800     }
801     return SOFTBUS_OK;
802 }
803 
SendOneFrameMiddle(SendListenerInfo * info,int32_t frameType)804 static int32_t SendOneFrameMiddle(SendListenerInfo *info, int32_t frameType)
805 {
806     if (info == NULL) {
807         TRANS_LOGW(TRANS_FILE, "invalid param.");
808         return SOFTBUS_INVALID_PARAM;
809     }
810     if (info->crc != APP_INFO_FILE_FEATURES_SUPPORT) {
811         return SOFTBUS_OK;
812     }
813     if (frameType == TRANS_SESSION_FILE_ONGOINE_FRAME) {
814         if ((uint32_t)info->seq % FILE_SEND_ACK_INTERVAL != 0) {
815             return SOFTBUS_OK;
816         }
817         if (CreatePendingPacket((uint32_t)info->sessionId, (uint64_t)info->seq) != SOFTBUS_OK) {
818             return SOFTBUS_ERR;
819         }
820         info->waitSeq = (int32_t)(info->seq);
821         info->waitTimeoutCount = 0;
822         if (SendFileAckReqAndResData(info->channelId, info->seq - FILE_SEND_ACK_INTERVAL + 1, info->seq,
823             TRANS_SESSION_FILE_ACK_REQUEST_SENT) != SOFTBUS_OK) {
824             DeletePendingPacket((uint32_t)info->sessionId, (uint64_t)info->seq);
825             info->waitSeq = 0;
826             return SOFTBUS_ERR;
827         }
828         TRANS_LOGI(TRANS_FILE, "send ack request. channelId=%{public}d, waitSeq=%{public}d",
829             info->channelId, info->waitSeq);
830     }
831     return SOFTBUS_OK;
832 }
833 
SendOneFrameRear(SendListenerInfo * info,int32_t frameType)834 static int32_t SendOneFrameRear(SendListenerInfo *info, int32_t frameType)
835 {
836     if (info == NULL) {
837         return SOFTBUS_INVALID_PARAM;
838     }
839     if (info->crc != APP_INFO_FILE_FEATURES_SUPPORT || frameType == TRANS_SESSION_FILE_ONLYONE_FRAME) {
840         return SOFTBUS_OK;
841     }
842     int32_t ret;
843     TransPendData pendData = {0};
844     if (frameType == TRANS_SESSION_FILE_FIRST_FRAME) {
845         ret = GetPendingPacketData(info->sessionId, 0, WAIT_START_ACK_TIME, true, &pendData);
846         if (ret == SOFTBUS_ALREADY_TRIGGERED || ret == SOFTBUS_OK) {
847             SoftBusFree(pendData.data);
848             return SOFTBUS_OK;
849         }
850         TRANS_LOGE(TRANS_FILE, "recv start frame respone timeout. channelId=%{public}d, ret=%{public}d",
851             info->channelId, ret);
852     } else {
853         if ((uint32_t)info->waitSeq == 0) {
854             return SOFTBUS_OK;
855         }
856         uint32_t time = WAIT_ACK_TIME;
857         if (frameType == TRANS_SESSION_FILE_LAST_FRAME || info->waitTimeoutCount >= WAIT_FRAME_ACK_TIMEOUT_COUNT) {
858             time = WAIT_ACK_LAST_TIME;
859         }
860         ret = GetPendingPacketData(info->sessionId, (uint64_t)info->waitSeq, time, false, &pendData);
861         if (ret == SOFTBUS_ALREADY_TRIGGERED || ret == SOFTBUS_OK) {
862             ret = AckResponseDataHandle(info, pendData.data, pendData.len);
863             info->waitSeq = 0;
864             info->waitTimeoutCount = 0;
865             SoftBusFree(pendData.data);
866             return ret;
867         } else if (ret == SOFTBUS_TIMOUT) {
868             info->waitTimeoutCount++;
869             if (frameType != TRANS_SESSION_FILE_LAST_FRAME &&
870                 info->waitTimeoutCount <= WAIT_FRAME_ACK_TIMEOUT_COUNT) {
871                 return SOFTBUS_OK;
872             }
873             DeletePendingPacket(info->sessionId, (uint64_t)info->waitSeq);
874         }
875         TRANS_LOGE(TRANS_FILE, "recv ack respone timeout. channelId=%{public}d, waitSeq=%{public}d, ret=%{public}d",
876             info->channelId, info->waitSeq, ret);
877         info->waitSeq = 0;
878         info->waitTimeoutCount = 0;
879     }
880     return SOFTBUS_ERR;
881 }
882 
SendOneFrame(const SendListenerInfo * sendInfo,const FileFrame * fileFrame)883 static int32_t SendOneFrame(const SendListenerInfo *sendInfo, const FileFrame *fileFrame)
884 {
885     if ((sendInfo == NULL) || (fileFrame == NULL)) {
886         TRANS_LOGW(TRANS_FILE, "invalid param.");
887         return SOFTBUS_INVALID_PARAM;
888     }
889     if (SendOneFrameFront((SendListenerInfo *)sendInfo, fileFrame->frameType) != SOFTBUS_OK) {
890         return SOFTBUS_ERR;
891     }
892     int32_t ret = ProxyChannelSendFileStream(sendInfo->channelId, (char *)fileFrame->data,
893         fileFrame->frameLength, fileFrame->frameType);
894     if (ret != SOFTBUS_OK) {
895         TRANS_LOGE(TRANS_FILE, "conn send buf fail ret=%{public}d", ret);
896         return ret;
897     }
898     if (SendOneFrameMiddle((SendListenerInfo *)sendInfo, fileFrame->frameType) != SOFTBUS_OK) {
899         return SOFTBUS_ERR;
900     }
901     if (SendOneFrameRear((SendListenerInfo *)sendInfo, fileFrame->frameType) != SOFTBUS_OK) {
902         return SOFTBUS_ERR;
903     }
904     if (sendInfo->result != SOFTBUS_OK) {
905         TRANS_LOGE(TRANS_FILE, "peer receiving data error. channalId=%{public}d, errcode=%{public}d",
906             sendInfo->channelId, sendInfo->result);
907         return SOFTBUS_ERR;
908     }
909     return SOFTBUS_OK;
910 }
911 
SendFileCrcCheckSum(const SendListenerInfo * info)912 static int32_t SendFileCrcCheckSum(const SendListenerInfo *info)
913 {
914     if (info == NULL) {
915         TRANS_LOGW(TRANS_FILE, "invalid param.");
916         return SOFTBUS_INVALID_PARAM;
917     }
918     if (info->crc != APP_INFO_FILE_FEATURES_SUPPORT) {
919         return SOFTBUS_OK;
920     }
921     uint32_t len = FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + sizeof(info->checkSumCRC);
922     char *data = (char *)SoftBusCalloc(len);
923     if (data == NULL) {
924         return SOFTBUS_MALLOC_ERR;
925     }
926     uint32_t seq = info->seq + 1; //magic(4 byte) + dataLen(8 byte) + seq(4 byte) + crc(8 byte)
927     (*(uint32_t *)data) = FILE_MAGIC_NUMBER;
928     (*(uint64_t *)(data + FRAME_MAGIC_OFFSET)) = (FRAME_DATA_SEQ_OFFSET + sizeof(info->checkSumCRC));
929     (*(uint32_t *)(data + FRAME_HEAD_LEN)) = seq;
930     (*(uint64_t *)(data + FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET)) = info->checkSumCRC;
931     if (CreatePendingPacket((uint32_t)info->sessionId, seq) != SOFTBUS_OK) {
932         TRANS_LOGE(TRANS_FILE, "Create Pend fail. channelId=%{public}d, seq=%{public}d", info->channelId, seq);
933         SoftBusFree(data);
934         return SOFTBUS_ERR;
935     }
936     TRANS_LOGI(TRANS_FILE, "send check sum. channelId=%{public}d, seq=%{public}d", info->channelId, seq);
937     int32_t ret = ProxyChannelSendFileStream(info->channelId, data, len, TRANS_SESSION_FILE_CRC_CHECK_FRAME);
938     if (ret != SOFTBUS_OK) {
939         TRANS_LOGE(TRANS_FILE, "conn send crc buf fail ret=%{public}d", ret);
940         DeletePendingPacket((uint32_t)info->sessionId, seq);
941         SoftBusFree(data);
942         return ret;
943     }
944     SoftBusFree(data);
945     TransPendData pendData = {0};
946     ret = GetPendingPacketData(info->sessionId, seq, WAIT_START_ACK_TIME, true, &pendData);
947     if (ret == SOFTBUS_ALREADY_TRIGGERED || ret == SOFTBUS_OK) {
948         SoftBusFree(pendData.data);
949         return SOFTBUS_OK;
950     }
951     TRANS_LOGE(TRANS_FILE, "recv check sum result timeout. channelId=%{public}d, seq=%{public}d, ret=%{public}d",
952         info->channelId, seq, ret);
953     return ret;
954 }
955 
UnpackFileCrcCheckSum(const FileRecipientInfo * info,FileFrame * fileFrame)956 static int32_t UnpackFileCrcCheckSum(const FileRecipientInfo *info, FileFrame *fileFrame)
957 {
958     if ((info == NULL) || (fileFrame == NULL)) {
959         TRANS_LOGW(TRANS_FILE, "invalid param.");
960         return SOFTBUS_INVALID_PARAM;
961     }
962     if (info->crc == APP_INFO_FILE_FEATURES_SUPPORT) {
963         SingleFileInfo *file = (SingleFileInfo *)(&info->recvFileInfo);
964         if (fileFrame->frameLength != FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + sizeof(file->checkSumCRC)) {
965             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
966         }
967         fileFrame->magic = (*(uint32_t *)(fileFrame->data));
968         uint64_t dataLen = (*(uint64_t *)(fileFrame->data + FRAME_MAGIC_OFFSET));
969         if ((fileFrame->magic != FILE_MAGIC_NUMBER) ||
970             (dataLen != FRAME_DATA_SEQ_OFFSET + sizeof(file->checkSumCRC))) {
971             TRANS_LOGE(TRANS_FILE,
972                 "unpack crc check frame failed. magic=%{public}u, dataLen=%{public}" PRIu64, fileFrame->magic, dataLen);
973             return SOFTBUS_INVALID_DATA_HEAD;
974         }
975         fileFrame->fileData = fileFrame->data + FRAME_HEAD_LEN;
976         fileFrame->seq = (*(uint32_t *)(fileFrame->fileData));
977         uint64_t recvCheckSumCRC = (*(uint64_t *)(fileFrame->fileData + FRAME_DATA_SEQ_OFFSET));
978         if (recvCheckSumCRC != file->checkSumCRC) {
979             TRANS_LOGE(TRANS_FILE,
980                 "crc check sum fail recvCrc=%{public}" PRIu64 ", crc=%{public}" PRIu64, recvCheckSumCRC,
981                 file->checkSumCRC);
982             return SOFTBUS_ERR;
983         }
984     }
985     return SOFTBUS_OK;
986 }
987 
FileToFrame(SendListenerInfo * sendInfo,uint64_t frameNum,const char * destFile,uint64_t fileSize)988 static int32_t FileToFrame(SendListenerInfo *sendInfo, uint64_t frameNum,
989     const char *destFile, uint64_t fileSize)
990 {
991     FileFrame fileFrame = {0};
992     fileFrame.data = (uint8_t *)SoftBusCalloc(PROXY_MAX_PACKET_SIZE);
993     if (fileFrame.data == NULL) {
994         return SOFTBUS_ERR;
995     }
996     fileFrame.magic = FILE_MAGIC_NUMBER;
997     fileFrame.fileData = fileFrame.data;
998     uint64_t fileOffset = 0;
999     uint64_t remainedSendSize = fileSize;
1000     uint64_t frameDataSize = PROXY_MAX_PACKET_SIZE - FRAME_DATA_SEQ_OFFSET;
1001     if (sendInfo->crc == APP_INFO_FILE_FEATURES_SUPPORT) {
1002         fileFrame.fileData = fileFrame.data + FRAME_HEAD_LEN;
1003         frameDataSize -= (FRAME_HEAD_LEN + FRAME_CRC_LEN);
1004     }
1005     for (uint64_t index = 0; index < frameNum; index++) {
1006         fileFrame.frameType = FrameIndexToType(index, frameNum);
1007         if (index == 0) {
1008             if (PackFileTransStartInfo(&fileFrame, destFile, fileSize, sendInfo) != SOFTBUS_OK) {
1009                 goto EXIT_ERR;
1010             }
1011         } else {
1012             uint64_t readLength = (remainedSendSize < frameDataSize) ? remainedSendSize : frameDataSize;
1013             int64_t len = PackReadFileData(&fileFrame, readLength, fileOffset, sendInfo);
1014             if (len <= 0) {
1015                 TRANS_LOGE(TRANS_FILE, "read file src file failed");
1016                 goto EXIT_ERR;
1017             }
1018             fileOffset += len;
1019             remainedSendSize -= len;
1020             sendInfo->totalInfo.bytesProcessed += len;
1021         }
1022         if (SendOneFrame(sendInfo, &fileFrame) != SOFTBUS_OK) {
1023             TRANS_LOGE(TRANS_FILE, "send one frame failed");
1024             goto EXIT_ERR;
1025         }
1026         if (sendInfo->fileListener.socketSendCallback != NULL) {
1027             FileEvent event = {
1028                 .type = FILE_EVENT_SEND_PROCESS,
1029                 .files = sendInfo->totalInfo.files,
1030                 .fileCnt = sendInfo->totalInfo.fileCnt,
1031                 .bytesProcessed = sendInfo->totalInfo.bytesProcessed,
1032                 .bytesTotal = sendInfo->totalInfo.bytesTotal,
1033                 .UpdateRecvPath = NULL,
1034             };
1035             sendInfo->fileListener.socketSendCallback(sendInfo->sessionId, &event);
1036         } else if (sendInfo->fileListener.sendListener.OnSendFileProcess != NULL) {
1037             sendInfo->fileListener.sendListener.OnSendFileProcess(sendInfo->channelId, fileOffset, fileSize);
1038         }
1039         (void)memset_s(fileFrame.data, PROXY_MAX_PACKET_SIZE, 0, PROXY_MAX_PACKET_SIZE);
1040     }
1041     TRANS_LOGI(TRANS_FILE, "send crc check sum");
1042     if (SendFileCrcCheckSum(sendInfo) != SOFTBUS_OK) {
1043         goto EXIT_ERR;
1044     }
1045     SoftBusFree(fileFrame.data);
1046     return SOFTBUS_OK;
1047 EXIT_ERR:
1048     SoftBusFree(fileFrame.data);
1049     return SOFTBUS_ERR;
1050 }
1051 
FileToFrameAndSendFile(SendListenerInfo * sendInfo,const char * sourceFile,const char * destFile)1052 static int32_t FileToFrameAndSendFile(SendListenerInfo *sendInfo, const char *sourceFile, const char *destFile)
1053 {
1054 #define RETRY_READ_LOCK_TIMES 2
1055     if (sendInfo == NULL) {
1056         TRANS_LOGW(TRANS_FILE, "invalid param.");
1057         return SOFTBUS_INVALID_PARAM;
1058     }
1059     if (CheckDestFilePathValid(destFile) == false) {
1060         TRANS_LOGE(TRANS_FILE, "dest path is wrong. channelId=%{public}d", sendInfo->channelId);
1061         return SOFTBUS_ERR;
1062     }
1063     char *absSrcPath = (char *)SoftBusCalloc(PATH_MAX + 1);
1064     if (absSrcPath == NULL) {
1065         TRANS_LOGE(TRANS_FILE, "calloc absFullDir fail");
1066         return SOFTBUS_ERR;
1067     }
1068     if (GetAndCheckRealPath(sourceFile, absSrcPath) != SOFTBUS_OK) {
1069         TRANS_LOGE(TRANS_FILE, "get src abs file fail. channelId=%{public}d", sendInfo->channelId);
1070         SoftBusFree(absSrcPath);
1071         return SOFTBUS_ERR;
1072     }
1073     uint64_t fileSize = 0;
1074     uint64_t frameNum = 0;
1075     if (GetAndCheckFileSize(absSrcPath, &fileSize, &frameNum, sendInfo->crc) != SOFTBUS_OK) {
1076         TRANS_LOGE(TRANS_FILE,
1077             "absSrcPath size err. channelId=%{public}d, absSrcPath=%{public}s", sendInfo->channelId, absSrcPath);
1078         SoftBusFree(absSrcPath);
1079         return SOFTBUS_ERR;
1080     }
1081     TRANS_LOGI(TRANS_FILE,
1082         "channelId=%{public}d, srcPath=%{public}s, srcAbsPath=%{public}s, destPath=%{public}s, "
1083         "fileSize=%{public}" PRIu64 ", frameNum=%{public}" PRIu64,
1084         sendInfo->channelId, sourceFile, absSrcPath, destFile, fileSize, frameNum);
1085     int32_t fd = SoftBusOpenFile(absSrcPath, SOFTBUS_O_RDONLY);
1086     if (fd < 0) {
1087         TRANS_LOGE(TRANS_FILE, "open file fail. channelId=%{public}d", sendInfo->channelId);
1088         SoftBusFree(absSrcPath);
1089         return SOFTBUS_ERR;
1090     }
1091     if (TryFileLock(fd, SOFTBUS_F_RDLCK, RETRY_READ_LOCK_TIMES) != SOFTBUS_OK) {
1092         TRANS_LOGE(TRANS_FILE, "file is writing");
1093         SoftBusCloseFile(fd);
1094         SoftBusFree(absSrcPath);
1095         return SOFTBUS_FILE_ERR;
1096     }
1097     sendInfo->fd = fd;
1098     sendInfo->fileSize = fileSize;
1099     sendInfo->frameNum = frameNum;
1100     int32_t ret = FileToFrame(sendInfo, frameNum, destFile, fileSize);
1101     SoftBusFree(absSrcPath);
1102     TRANS_LOGI(TRANS_FILE, "send file end. channelId=%{public}d, ret=%{public}d", sendInfo->channelId, ret);
1103     return ret;
1104 }
1105 
ClearSendInfo(SendListenerInfo * info)1106 static void ClearSendInfo(SendListenerInfo *info)
1107 {
1108     if (info->fd != INVALID_FD) {
1109         (void)FileUnLock(info->fd);
1110         SoftBusCloseFile(info->fd);
1111         info->fd = INVALID_FD;
1112     }
1113     info->fileSize = 0;
1114     info->frameNum = 0;
1115     info->seq = 0;
1116     info->waitSeq = 0;
1117     info->waitTimeoutCount = 0;
1118     info->result = SOFTBUS_OK;
1119     info->checkSumCRC = 0;
1120 }
1121 
SendSingleFile(const SendListenerInfo * sendInfo,const char * sourceFile,const char * destFile)1122 static int32_t SendSingleFile(const SendListenerInfo *sendInfo, const char *sourceFile, const char *destFile)
1123 {
1124     if ((sourceFile == NULL) || (destFile == NULL)) {
1125         TRANS_LOGE(TRANS_FILE, "sourfile or dstfile is null");
1126         return SOFTBUS_ERR;
1127     }
1128     TRANS_LOGE(TRANS_FILE, "channelId=%{public}d, srcFile=%{public}s, dstFile=%{public}s",
1129         sendInfo->channelId, sourceFile, destFile);
1130 
1131     int32_t ret = FileToFrameAndSendFile((SendListenerInfo *)sendInfo, sourceFile, destFile);
1132     ClearSendInfo((SendListenerInfo *)sendInfo);
1133     TRANS_LOGI(TRANS_FILE, "channelId=%{public}d, srcFile=%{public}s, ret=%{public}d",
1134         sendInfo->channelId, sourceFile, ret);
1135     return ret;
1136 }
1137 
SendFileList(int32_t channelId,const char ** destFile,uint32_t fileCnt)1138 static int32_t SendFileList(int32_t channelId, const char **destFile, uint32_t fileCnt)
1139 {
1140     TRANS_LOGI(TRANS_FILE, "send file list begin");
1141     FileListBuffer bufferInfo = {0};
1142     int32_t ret = FileListToBuffer(destFile, fileCnt, &bufferInfo);
1143     if (ret != SOFTBUS_OK) {
1144         TRANS_LOGE(TRANS_FILE, "file list to buffer fail");
1145         return SOFTBUS_ERR;
1146     }
1147 
1148     ret = ProxyChannelSendFileStream(channelId, (char *)bufferInfo.buffer, bufferInfo.bufferSize,
1149         TRANS_SESSION_FILE_ALLFILE_SENT);
1150     SoftBusFree(bufferInfo.buffer);
1151     TRANS_LOGI(TRANS_FILE, "send file list ret=%{public}d", ret);
1152     return ret;
1153 }
1154 
IsValidFileString(const char * str[],uint32_t fileNum,uint32_t maxLen)1155 static bool IsValidFileString(const char *str[], uint32_t fileNum, uint32_t maxLen)
1156 {
1157     if (str == NULL || fileNum == 0) {
1158         TRANS_LOGE(TRANS_FILE, "param invalid");
1159         return false;
1160     }
1161     for (uint32_t i = 0; i < fileNum; i++) {
1162         if (str[i] == NULL) {
1163             TRANS_LOGE(TRANS_FILE, "file string invalid");
1164             return false;
1165         }
1166         uint32_t len = strlen(str[i]);
1167         if (len == 0 || len >= maxLen) {
1168             TRANS_LOGE(TRANS_FILE, "len invalid");
1169             return false;
1170         }
1171     }
1172     return true;
1173 }
1174 
GetFileSize(const char * filePath,uint64_t * fileSize)1175 static int32_t GetFileSize(const char *filePath, uint64_t *fileSize)
1176 {
1177     char *absPath = (char *)SoftBusCalloc(PATH_MAX + 1);
1178     if (absPath == NULL) {
1179         TRANS_LOGE(TRANS_SDK, "calloc absFullDir fail");
1180         return SOFTBUS_ERR;
1181     }
1182 
1183     if (GetAndCheckRealPath(filePath, absPath) != SOFTBUS_OK) {
1184         TRANS_LOGE(TRANS_SDK, "get src abs file fail");
1185         SoftBusFree(absPath);
1186         return SOFTBUS_ERR;
1187     }
1188 
1189     if (SoftBusGetFileSize(absPath, fileSize) != SOFTBUS_OK) {
1190         TRANS_LOGE(TRANS_SDK, "get file size fail");
1191         SoftBusFree(absPath);
1192         return SOFTBUS_FILE_ERR;
1193     }
1194 
1195     SoftBusFree(absPath);
1196     return SOFTBUS_OK;
1197 }
1198 
CalcAllFilesInfo(FilesInfo * totalInfo,const char * fileList[],uint32_t fileCnt)1199 static int32_t CalcAllFilesInfo(FilesInfo *totalInfo, const char *fileList[], uint32_t fileCnt)
1200 {
1201     totalInfo->files = fileList;
1202     totalInfo->fileCnt = fileCnt;
1203     totalInfo->bytesProcessed = 0;
1204 
1205     uint64_t curFileSize = 0;
1206     for (uint32_t i = 0; i < fileCnt; i++) {
1207         if (GetFileSize(fileList[i], &curFileSize) != SOFTBUS_OK) {
1208             TRANS_LOGE(TRANS_SDK, "get file size failed, path=%{public}s", fileList[i]);
1209             return SOFTBUS_ERR;
1210         }
1211         totalInfo->bytesTotal += curFileSize;
1212     }
1213     return SOFTBUS_OK;
1214 }
1215 
ProxyStartSendFile(const SendListenerInfo * sendInfo,const char * sFileList[],const char * dFileList[],uint32_t fileCnt)1216 static int32_t ProxyStartSendFile(const SendListenerInfo *sendInfo, const char *sFileList[],
1217     const char *dFileList[], uint32_t fileCnt)
1218 {
1219     int32_t ret;
1220     if (CalcAllFilesInfo((FilesInfo *)&sendInfo->totalInfo, sFileList, fileCnt)) {
1221         TRANS_LOGE(TRANS_SDK, "calculate all files information failed");
1222         return SOFTBUS_ERR;
1223     }
1224 
1225     for (uint32_t index = 0; index < fileCnt; index++) {
1226         ret = SendSingleFile(sendInfo, sFileList[index], dFileList[index]);
1227         if (ret != SOFTBUS_OK) {
1228             TRANS_LOGE(TRANS_FILE,
1229                 "send file failed. sendFile=%{public}s, ret=%{public}" PRId32, sFileList[index], ret);
1230             return SOFTBUS_ERR;
1231         }
1232     }
1233     ret = SendFileList(sendInfo->channelId, dFileList, fileCnt);
1234     if (ret != SOFTBUS_OK) {
1235         TRANS_LOGE(TRANS_FILE, "SendFileList failed");
1236         return SOFTBUS_ERR;
1237     }
1238     if (sendInfo->result != SOFTBUS_OK) {
1239         TRANS_LOGE(TRANS_FILE, "send file recv side fail channelId=%{public}d, errCode=%{public}d",
1240             sendInfo->channelId, sendInfo->result);
1241         return SOFTBUS_ERR;
1242     }
1243     if (sendInfo->fileListener.socketSendCallback != NULL) {
1244         FileEvent event = {
1245             .type = FILE_EVENT_SEND_FINISH,
1246             .files =  sendInfo->totalInfo.files,
1247             .fileCnt = sendInfo->totalInfo.fileCnt,
1248             .bytesProcessed = sendInfo->totalInfo.bytesProcessed,
1249             .bytesTotal = sendInfo->totalInfo.bytesTotal,
1250             .UpdateRecvPath = NULL,
1251         };
1252         sendInfo->fileListener.socketSendCallback(sendInfo->sessionId, &event);
1253     } else if (sendInfo->fileListener.sendListener.OnSendFileFinished != NULL) {
1254         sendInfo->fileListener.sendListener.OnSendFileFinished(sendInfo->sessionId, dFileList[0]);
1255     }
1256     return SOFTBUS_OK;
1257 }
1258 
GetSendListenerInfoByChannelId(int32_t channelId,SendListenerInfo * info)1259 static int32_t GetSendListenerInfoByChannelId(int32_t channelId, SendListenerInfo *info)
1260 {
1261     int32_t sessionId;
1262     if (info == NULL) {
1263         TRANS_LOGW(TRANS_FILE, "invalid param.");
1264         return SOFTBUS_INVALID_PARAM;
1265     }
1266     int32_t ret = ClientGetSessionIdByChannelId(channelId, CHANNEL_TYPE_PROXY, &sessionId);
1267     if (ret != SOFTBUS_OK) {
1268         TRANS_LOGE(TRANS_FILE, "get sessionId failed, channelId=%{public}d", channelId);
1269         return SOFTBUS_ERR;
1270     }
1271     char sessionName[SESSION_NAME_SIZE_MAX] = {0};
1272     if (ClientGetSessionDataById(sessionId, sessionName, SESSION_NAME_SIZE_MAX, KEY_SESSION_NAME) != SOFTBUS_OK) {
1273         TRANS_LOGE(TRANS_FILE, "get sessionId name failed");
1274         return SOFTBUS_ERR;
1275     }
1276     if (ClientGetFileConfigInfoById(sessionId, &info->fileEncrypt, &info->algorithm, &info->crc) != SOFTBUS_OK) {
1277         TRANS_LOGE(TRANS_FILE, "get file config failed");
1278         return SOFTBUS_ERR;
1279     }
1280     if (TransGetFileListener(sessionName, &(info->fileListener)) != SOFTBUS_OK) {
1281         TRANS_LOGE(TRANS_FILE, "get file listener failed");
1282         return SOFTBUS_ERR;
1283     }
1284     info->channelId = channelId;
1285     info->sessionId = sessionId;
1286     ListInit(&info->node);
1287     return SOFTBUS_OK;
1288 }
1289 
CreateSendListenerInfo(SendListenerInfo ** sendListenerInfo,int32_t channelId)1290 static int32_t CreateSendListenerInfo(SendListenerInfo **sendListenerInfo, int32_t channelId)
1291 {
1292     SendListenerInfo *sendInfo = (SendListenerInfo *)SoftBusCalloc(sizeof(SendListenerInfo));
1293     if (sendInfo == NULL) {
1294         return SOFTBUS_MALLOC_ERR;
1295     }
1296     int32_t ret = SOFTBUS_ERR;
1297     do {
1298         ret = GetSendListenerInfoByChannelId(channelId, sendInfo);
1299         if (ret != SOFTBUS_OK) {
1300             break;
1301         }
1302 
1303         ret = AddSendListenerInfo(sendInfo);
1304         if (ret != SOFTBUS_OK) {
1305             break;
1306         }
1307     } while (false);
1308 
1309     if (ret != SOFTBUS_OK) {
1310         SoftBusFree(sendInfo);
1311         sendInfo = NULL;
1312     }
1313 
1314     *sendListenerInfo = sendInfo;
1315     return ret;
1316 }
1317 
ReleaseSendListenerInfo(SendListenerInfo * sendInfo)1318 static void ReleaseSendListenerInfo(SendListenerInfo *sendInfo)
1319 {
1320     if (sendInfo == NULL) {
1321         return;
1322     }
1323     DelSendListenerInfo(sendInfo);
1324     SoftBusFree(sendInfo);
1325 }
1326 
ProxyChannelSendFile(int32_t channelId,const char * sFileList[],const char * dFileList[],uint32_t fileCnt)1327 int32_t ProxyChannelSendFile(int32_t channelId, const char *sFileList[],
1328     const char *dFileList[], uint32_t fileCnt)
1329 {
1330     TRANS_LOGI(TRANS_FILE, "proxy send file trans start");
1331     if ((fileCnt == 0) || (fileCnt > MAX_SEND_FILE_NUM)) {
1332         TRANS_LOGE(TRANS_FILE, "sendfile arg filecnt=%{public}d error", fileCnt);
1333         return SOFTBUS_ERR;
1334     }
1335     if (sFileList == NULL || !IsValidFileString(sFileList, fileCnt, MAX_FILE_PATH_NAME_LEN)) {
1336         TRANS_LOGE(TRANS_FILE, "sendfile invalid arg sFileList");
1337         return SOFTBUS_ERR;
1338     }
1339     if (dFileList == NULL || !IsValidFileString(dFileList, fileCnt, MAX_FILE_PATH_NAME_LEN)) {
1340         TRANS_LOGE(TRANS_FILE, "sendfile invalid arg dFileList");
1341         return SOFTBUS_ERR;
1342     }
1343 
1344     ProxyFileMutexLock *sessionLock = GetSessionFileLock(channelId);
1345     if (sessionLock == NULL) {
1346         TRANS_LOGE(TRANS_FILE, "proxy send file get file lock failed");
1347         return SOFTBUS_LOCK_ERR;
1348     }
1349     if (SoftBusMutexLock(&sessionLock->sendLock) != SOFTBUS_OK) {
1350         TRANS_LOGE(TRANS_FILE, "proxy send file lock file mutex failed");
1351         DelSessionFileLock(sessionLock);
1352         return SOFTBUS_LOCK_ERR;
1353     }
1354 
1355     SendListenerInfo *sendInfo = NULL;
1356     int32_t ret = SOFTBUS_ERR;
1357     do {
1358         ret = CreateSendListenerInfo(&sendInfo, channelId);
1359         if (ret != SOFTBUS_OK || sendInfo == NULL) {
1360             TRANS_LOGE(TRANS_FILE, "create send listener info failed! ret=%{public}" PRId32, ret);
1361             break;
1362         }
1363         ret = ProxyStartSendFile(sendInfo, sFileList, dFileList, fileCnt);
1364         if (ret != SOFTBUS_OK) {
1365             TRANS_LOGE(TRANS_FILE, "proxy send file failed ret=%{public}" PRId32, ret);
1366             DeletePendingPacket(sendInfo->sessionId, sendInfo->waitSeq);
1367             ret = SOFTBUS_TRANS_PROXY_SENDMSG_ERR;
1368             break;
1369         }
1370         TRANS_LOGI(TRANS_FILE, "proxy send file trans ok");
1371     } while (false);
1372 
1373     if (ret != SOFTBUS_OK) {
1374         TRANS_LOGE(TRANS_FILE, "proxy send file trans error");
1375         if (sendInfo != NULL && sendInfo->fileListener.socketSendCallback != NULL) {
1376             FileEvent event = {
1377                 .type = FILE_EVENT_SEND_ERROR,
1378                 .files = sendInfo->totalInfo.files,
1379                 .fileCnt = sendInfo->totalInfo.fileCnt,
1380                 .bytesProcessed = 0,
1381                 .bytesTotal = 0,
1382             };
1383             sendInfo->fileListener.socketSendCallback(sendInfo->sessionId, &event);
1384         } else if (sendInfo != NULL && sendInfo->fileListener.sendListener.OnFileTransError != NULL) {
1385             sendInfo->fileListener.sendListener.OnFileTransError(sendInfo->sessionId);
1386         }
1387     }
1388 
1389     if (sendInfo != NULL) {
1390         ReleaseSendListenerInfo(sendInfo);
1391         sendInfo = NULL;
1392     }
1393 
1394     (void)SoftBusMutexUnlock(&sessionLock->sendLock);
1395     DelSessionFileLock(sessionLock);
1396     return ret;
1397 }
1398 
CheckRecvFileExist(const char * absFullPath)1399 static bool CheckRecvFileExist(const char *absFullPath)
1400 {
1401     if (absFullPath == NULL) {
1402         TRANS_LOGE(TRANS_FILE, "absFullPath is null");
1403         return false;
1404     }
1405     if (SoftBusMutexLock(&g_recvFileInfoLock.lock) != SOFTBUS_OK) {
1406         TRANS_LOGE(TRANS_FILE, "lock file timer failed");
1407         return false;
1408     }
1409     FileRecipientInfo *info = NULL;
1410     LIST_FOR_EACH_ENTRY(info, &g_recvRecipientInfoList, FileRecipientInfo, node) {
1411         if (info->recvState == TRANS_FILE_RECV_IDLE_STATE || info->recvFileInfo.fileStatus != NODE_BUSY) {
1412             continue;
1413         }
1414         if (strcmp(info->recvFileInfo.filePath, absFullPath) == 0) {
1415             (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1416             return true;
1417         }
1418     }
1419     (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1420     return false;
1421 }
PutToRecvFileList(FileRecipientInfo * recipient,const SingleFileInfo * file)1422 static int32_t PutToRecvFileList(FileRecipientInfo *recipient, const SingleFileInfo *file)
1423 {
1424 #define RETRY_WRITE_LOCK_TIMES 2
1425     if (recipient == NULL || file == NULL) {
1426         TRANS_LOGE(TRANS_FILE, "file is null");
1427         return SOFTBUS_ERR;
1428     }
1429     if (recipient->recvFileInfo.fileStatus != NODE_IDLE) {
1430         TRANS_LOGE(TRANS_FILE, "session receiving file");
1431         return SOFTBUS_ERR;
1432     }
1433     if (CheckRecvFileExist(file->filePath)) {
1434         TRANS_LOGE(TRANS_FILE, "file is already exist and busy");
1435         return SOFTBUS_FILE_ERR;
1436     }
1437     if (memcpy_s(&recipient->recvFileInfo, sizeof(SingleFileInfo), file, sizeof(SingleFileInfo)) != EOK) {
1438         TRANS_LOGE(TRANS_FILE, "memcpy file info fail");
1439         return SOFTBUS_MEM_ERR;
1440     }
1441     int32_t fd = SoftBusOpenFileWithPerms(file->filePath,
1442         SOFTBUS_O_WRONLY | SOFTBUS_O_CREATE, SOFTBUS_S_IRUSR | SOFTBUS_S_IWUSR);
1443     if (fd < 0) {
1444         TRANS_LOGE(TRANS_FILE, "open destFile fail");
1445         return SOFTBUS_FILE_ERR;
1446     }
1447     if (TryFileLock(fd, SOFTBUS_F_WRLCK, RETRY_WRITE_LOCK_TIMES) != SOFTBUS_OK) {
1448         TRANS_LOGE(TRANS_FILE, "file busy");
1449         SoftBusCloseFile(fd);
1450         return SOFTBUS_FILE_ERR;
1451     }
1452     (void)ftruncate(fd, 0);
1453     recipient->recvFileInfo.fileStatus = NODE_BUSY;
1454     recipient->recvFileInfo.fileOffset = 0;
1455     recipient->recvFileInfo.timeOut = 0;
1456     recipient->recvFileInfo.fileFd = fd;
1457     return SOFTBUS_OK;
1458 }
1459 
GetRecipientNoLock(int32_t sessionId)1460 static FileRecipientInfo *GetRecipientNoLock(int32_t sessionId)
1461 {
1462     FileRecipientInfo *info = NULL;
1463     LIST_FOR_EACH_ENTRY(info, &g_recvRecipientInfoList, FileRecipientInfo, node) {
1464         if (info->sessionId == sessionId) {
1465             return info;
1466         }
1467     }
1468     return NULL;
1469 }
1470 
ReleaseRecipientRef(FileRecipientInfo * info)1471 static void ReleaseRecipientRef(FileRecipientInfo *info)
1472 {
1473     if (info == NULL || SoftBusMutexLock(&g_recvFileInfoLock.lock) != SOFTBUS_OK) {
1474         return;
1475     }
1476     info->objRefCount--;
1477     if (info->objRefCount == 0) {
1478         ListDelete(&info->node);
1479         ClearRecipientResources(info);
1480         SoftBusFree(info);
1481     }
1482     (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1483 }
1484 
DelRecipient(int32_t sessionId)1485 static void DelRecipient(int32_t sessionId)
1486 {
1487     if (SoftBusMutexLock(&g_recvFileInfoLock.lock) != SOFTBUS_OK) {
1488         return;
1489     }
1490     FileRecipientInfo *info = NULL;
1491     LIST_FOR_EACH_ENTRY(info, &g_recvRecipientInfoList, FileRecipientInfo, node) {
1492         if (info->sessionId == sessionId) {
1493             info->objRefCount--;
1494             if (info->objRefCount == 0) {
1495                 ListDelete(&info->node);
1496                 TRANS_LOGI(TRANS_FILE, "delete sessionId = %{public}d", sessionId);
1497                 ClearRecipientResources(info);
1498                 SoftBusFree(info);
1499             }
1500             break;
1501         }
1502     }
1503     (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1504 }
1505 
ClientDeleteRecvFileList(int32_t sessionId)1506 void ClientDeleteRecvFileList(int32_t sessionId)
1507 {
1508     if (sessionId <= 0) {
1509         TRANS_LOGE(TRANS_FILE, "session id is invalid");
1510         return;
1511     }
1512     (void)DelRecipient(sessionId);
1513 }
1514 
UpdateFileReceivePath(int32_t sessionId,FileListener * fileListener)1515 static int32_t UpdateFileReceivePath(int32_t sessionId, FileListener *fileListener)
1516 {
1517     if (fileListener->socketRecvCallback == NULL) {
1518         return SOFTBUS_OK;
1519     }
1520     FileEvent event = {
1521         .type = FILE_EVENT_RECV_UPDATE_PATH,
1522         .files = NULL,
1523         .fileCnt = 0,
1524         .bytesProcessed = 0,
1525         .bytesTotal = 0,
1526         .UpdateRecvPath = NULL,
1527     };
1528     fileListener->socketRecvCallback(sessionId, &event);
1529     if (event.UpdateRecvPath == NULL) {
1530         TRANS_LOGE(TRANS_FILE, "failed to obtain the file receive path");
1531         return SOFTBUS_ERR;
1532     }
1533 
1534     const char *rootDir = event.UpdateRecvPath();
1535     char *absPath = realpath(rootDir, NULL);
1536     if (absPath == NULL) {
1537         TRANS_LOGE(TRANS_SDK,
1538             "rootDir not exist, rootDir=%{public}s, errno=%{public}d.", (rootDir == NULL ? "null" : rootDir), errno);
1539         return SOFTBUS_ERR;
1540     }
1541 
1542     if (strcpy_s(fileListener->rootDir, FILE_RECV_ROOT_DIR_SIZE_MAX, absPath) != EOK) {
1543         TRANS_LOGE(TRANS_FILE, "failed to strcpy the file receive path");
1544         SoftBusFree(absPath);
1545         return SOFTBUS_ERR;
1546     }
1547     SoftBusFree(absPath);
1548     return SOFTBUS_OK;
1549 }
1550 
CreateNewRecipient(int32_t sessionId,int32_t channelId)1551 static FileRecipientInfo *CreateNewRecipient(int32_t sessionId, int32_t channelId)
1552 {
1553     FileRecipientInfo *info = NULL;
1554     LIST_FOR_EACH_ENTRY(info, &g_recvRecipientInfoList, FileRecipientInfo, node) {
1555         if (info->sessionId == sessionId) {
1556             TRANS_LOGE(TRANS_FILE, "session id exists");
1557             return NULL;
1558         }
1559     }
1560     info = (FileRecipientInfo *)SoftBusCalloc(sizeof(FileRecipientInfo));
1561     if (info == NULL) {
1562         TRANS_LOGE(TRANS_FILE, "info calloc failed");
1563         return NULL;
1564     }
1565     char sessionName[SESSION_NAME_SIZE_MAX] = {0};
1566     if (ClientGetSessionDataById(sessionId, sessionName, SESSION_NAME_SIZE_MAX, KEY_SESSION_NAME) != SOFTBUS_OK) {
1567         TRANS_LOGE(TRANS_FILE, "get sessionId name failed");
1568         SoftBusFree(info);
1569         return NULL;
1570     }
1571     if (ClientGetFileConfigInfoById(sessionId, &info->fileEncrypt, &info->algorithm, &info->crc) != SOFTBUS_OK) {
1572         TRANS_LOGE(TRANS_FILE, "get file config failed");
1573         SoftBusFree(info);
1574         return NULL;
1575     }
1576     info->channelId = channelId;
1577     info->sessionId = sessionId;
1578     if (TransGetFileListener(sessionName, &(info->fileListener)) != SOFTBUS_OK) {
1579         TRANS_LOGE(TRANS_FILE, "get file listener failed");
1580         SoftBusFree(info);
1581         return NULL;
1582     }
1583 
1584     if (UpdateFileReceivePath(sessionId, &info->fileListener) != SOFTBUS_OK) {
1585         TRANS_LOGE(TRANS_FILE, "failed to get rootDir");
1586         SoftBusFree(info);
1587         return NULL;
1588     }
1589 
1590     ListInit(&info->node);
1591     info->objRefCount = 1;
1592     info->recvFileInfo.fileFd = INVALID_FD;
1593     ListTailInsert(&g_recvRecipientInfoList, &info->node);
1594     return info;
1595 }
1596 
GetFileInfoByStartFrame(const FileFrame * fileFrame,const FileRecipientInfo * info,SingleFileInfo * file)1597 static int32_t GetFileInfoByStartFrame(const FileFrame *fileFrame, const FileRecipientInfo *info, SingleFileInfo *file)
1598 {
1599     if (file == NULL || info == NULL || fileFrame == NULL) {
1600         return SOFTBUS_INVALID_PARAM;
1601     }
1602     const char *rootDir = info->fileListener.rootDir;
1603     if (strstr(rootDir, "..") != NULL) {
1604         TRANS_LOGE(TRANS_FILE, "rootDir is not canonical form. rootDir=%{public}s", rootDir);
1605         return SOFTBUS_ERR;
1606     }
1607     if (UnpackFileTransStartInfo((FileFrame *)fileFrame, info, file) != SOFTBUS_OK) {
1608         TRANS_LOGE(TRANS_FILE, "unpack start info fail. sessionId=%{public}d", info->sessionId);
1609         return SOFTBUS_ERR;
1610     }
1611     char *filePath = file->filePath;
1612     if (!CheckDestFilePathValid(filePath)) {
1613         TRANS_LOGE(TRANS_FILE, "recv filePath form is wrong. filePath=%{public}s", filePath);
1614         return SOFTBUS_ERR;
1615     }
1616     TRANS_LOGI(TRANS_FILE, "dst filePath=%{public}s, rootDir=%{public}s", filePath, rootDir);
1617     char *fullRecvPath = GetFullRecvPath(filePath, rootDir);
1618     if (!IsPathValid(fullRecvPath)) {
1619         TRANS_LOGE(TRANS_FILE, "destFilePath is invalid");
1620         SoftBusFree(fullRecvPath);
1621         return SOFTBUS_ERR;
1622     }
1623     (void)memset_s(filePath, MAX_FILE_PATH_NAME_LEN, 0, MAX_FILE_PATH_NAME_LEN);
1624     if (CreateDirAndGetAbsPath(fullRecvPath, filePath, MAX_FILE_PATH_NAME_LEN) != SOFTBUS_OK) {
1625         TRANS_LOGE(TRANS_FILE, "create dest dir failed");
1626         SoftBusFree(fullRecvPath);
1627         return SOFTBUS_ERR;
1628     }
1629     SoftBusFree(fullRecvPath);
1630     return SOFTBUS_OK;
1631 }
1632 
GetRecipientInCreateFileRef(int32_t sessionId,int32_t channelId)1633 static FileRecipientInfo *GetRecipientInCreateFileRef(int32_t sessionId, int32_t channelId)
1634 {
1635     if (SoftBusMutexLock(&g_recvFileInfoLock.lock) != SOFTBUS_OK) {
1636         TRANS_LOGE(TRANS_FILE, "mutex lock fail");
1637         return NULL;
1638     }
1639     FileRecipientInfo *recipient = GetRecipientNoLock(sessionId);
1640     if (recipient == NULL) {
1641         recipient = CreateNewRecipient(sessionId, channelId);
1642         if (recipient == NULL) {
1643             TRANS_LOGE(TRANS_FILE, "create file recipient fail. sessionId=%{public}d", sessionId);
1644             (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1645             return NULL;
1646         }
1647     }
1648     if (recipient->recvState != TRANS_FILE_RECV_IDLE_STATE) {
1649         TRANS_LOGE(TRANS_FILE, "create file fail. recvState=%{public}d, sessionId=%{public}d",
1650             sessionId, recipient->recvState);
1651         (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1652         return NULL;
1653     }
1654     recipient->recvState = TRANS_FILE_RECV_START_STATE;
1655     recipient->objRefCount++;
1656     (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1657     return recipient;
1658 }
1659 
GetRecipientInProcessRef(int32_t sessionId)1660 static FileRecipientInfo *GetRecipientInProcessRef(int32_t sessionId)
1661 {
1662     if (SoftBusMutexLock(&g_recvFileInfoLock.lock) != SOFTBUS_OK) {
1663         TRANS_LOGE(TRANS_FILE, "mutex lock fail");
1664         return NULL;
1665     }
1666     FileRecipientInfo *recipient = GetRecipientNoLock(sessionId);
1667     if (recipient == NULL || recipient->recvState == TRANS_FILE_RECV_IDLE_STATE) {
1668         TRANS_LOGE(TRANS_FILE, "get recipient no lock fail");
1669         (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1670         return NULL;
1671     }
1672     if (recipient->recvState == TRANS_FILE_RECV_START_STATE) {
1673         recipient->recvState = TRANS_FILE_RECV_PROCESS_STATE;
1674     }
1675     recipient->objRefCount++;
1676     (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1677     return recipient;
1678 }
1679 
GetRecipientInfo(int32_t sessionId)1680 static FileRecipientInfo *GetRecipientInfo(int32_t sessionId)
1681 {
1682     if (SoftBusMutexLock(&g_recvFileInfoLock.lock) != SOFTBUS_OK) {
1683         TRANS_LOGE(TRANS_FILE, "mutex lock fail");
1684         return NULL;
1685     }
1686     FileRecipientInfo *recipient = GetRecipientNoLock(sessionId);
1687     if (recipient == NULL) {
1688         TRANS_LOGE(TRANS_FILE, "get recipient no lock fail");
1689         (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1690         return NULL;
1691     }
1692     if (recipient->recvState == TRANS_FILE_RECV_START_STATE) {
1693         recipient->recvState = TRANS_FILE_RECV_PROCESS_STATE;
1694     }
1695     recipient->objRefCount++;
1696     (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1697     return recipient;
1698 }
1699 
CreateFileFromFrame(int32_t sessionId,int32_t channelId,const FileFrame * fileFrame)1700 static int32_t CreateFileFromFrame(int32_t sessionId, int32_t channelId, const FileFrame *fileFrame)
1701 {
1702     FileRecipientInfo *recipient = GetRecipientInCreateFileRef(sessionId, channelId);
1703     if (recipient == NULL) {
1704         TRANS_LOGE(TRANS_FILE, "GetRecipientInCreateFileRef fail. sessionId=%{public}d", sessionId);
1705         return SOFTBUS_ERR;
1706     }
1707     int32_t result = SOFTBUS_ERR;
1708     SingleFileInfo *file = (SingleFileInfo *)SoftBusCalloc(sizeof(SingleFileInfo));
1709     if (file == NULL) {
1710         TRANS_LOGE(TRANS_FILE, "file calloc fail");
1711         goto EXIT_ERR;
1712     }
1713     if (GetFileInfoByStartFrame(fileFrame, recipient, file) != SOFTBUS_OK) {
1714         TRANS_LOGE(TRANS_FILE, "get file info by start frame fail");
1715         goto EXIT_ERR;
1716     }
1717     TRANS_LOGI(TRANS_FILE, "null filePath. filePath=%{public}s, seq=%{public}u", file->filePath, file->seq);
1718     if (PutToRecvFileList(recipient, file) != SOFTBUS_OK) {
1719         TRANS_LOGE(TRANS_FILE, "put to recv files failed. sessionId=%{public}u", recipient->sessionId);
1720         goto EXIT_ERR;
1721     }
1722     if (recipient->fileListener.socketRecvCallback != NULL) {
1723         const char *fileList[] = { file->filePath };
1724         FileEvent event = {
1725             .type = FILE_EVENT_RECV_START,
1726             .files = fileList,
1727             .fileCnt = 1,
1728             .bytesProcessed = file->fileSize,
1729             .bytesTotal = file->fileSize,
1730             .UpdateRecvPath = NULL,
1731         };
1732         recipient->fileListener.socketRecvCallback(sessionId, &event);
1733     } else if (recipient->fileListener.recvListener.OnReceiveFileStarted != NULL) {
1734         recipient->fileListener.recvListener.OnReceiveFileStarted(sessionId, file->filePath, 1);
1735     }
1736     ReleaseRecipientRef(recipient);
1737     SoftBusFree(file);
1738     if (recipient->crc == APP_INFO_FILE_FEATURES_SUPPORT) {
1739         (void)SendFileTransResult(channelId, 0, SOFTBUS_OK, IS_RECV_RESULT);
1740     }
1741     return SOFTBUS_OK;
1742 EXIT_ERR:
1743     SoftBusFree(file);
1744     if (recipient->crc == APP_INFO_FILE_FEATURES_SUPPORT) {
1745         (void)SendFileTransResult(channelId, 0, result, IS_RECV_RESULT);
1746     }
1747     if (recipient->fileListener.socketRecvCallback != NULL) {
1748         FileEvent event = {.type = FILE_EVENT_RECV_ERROR};
1749         recipient->fileListener.socketRecvCallback(sessionId, &event);
1750     } else if (recipient->fileListener.recvListener.OnFileTransError != NULL) {
1751         recipient->fileListener.recvListener.OnFileTransError(sessionId);
1752     }
1753     ReleaseRecipientRef(recipient);
1754     DelRecipient(sessionId);
1755     return SOFTBUS_ERR;
1756 }
1757 
WriteEmptyFrame(SingleFileInfo * fileInfo,int32_t count)1758 static int32_t WriteEmptyFrame(SingleFileInfo *fileInfo, int32_t count)
1759 {
1760     if (fileInfo == NULL) {
1761         TRANS_LOGW(TRANS_FILE, "invalid param.");
1762         return SOFTBUS_INVALID_PARAM;
1763     }
1764 
1765     if (count > 0) {
1766         TRANS_LOGI(TRANS_FILE, "write empty frame. count=%{public}d", count);
1767         char *emptyBuff = (char *)SoftBusCalloc(fileInfo->oneFrameLen);
1768         if (emptyBuff == NULL) {
1769             return SOFTBUS_MALLOC_ERR;
1770         }
1771         for (int32_t i = 0; i < count; ++i) {
1772             int64_t emptyLen = SoftBusPwriteFile(fileInfo->fileFd, emptyBuff,
1773                 fileInfo->oneFrameLen, fileInfo->fileOffset);
1774             if (emptyLen < 0 || (uint64_t)emptyLen != fileInfo->oneFrameLen) {
1775                 TRANS_LOGE(TRANS_FILE, "pwrite empty frame fail");
1776                 SoftBusFree(emptyBuff);
1777                 return SOFTBUS_ERR;
1778             }
1779             fileInfo->fileOffset += (uint64_t)emptyLen;
1780         }
1781         SoftBusFree(emptyBuff);
1782     }
1783     return SOFTBUS_OK;
1784 }
1785 
ProcessOneFrameCRC(const FileFrame * frame,uint32_t dataLen,SingleFileInfo * fileInfo)1786 static int32_t ProcessOneFrameCRC(const FileFrame *frame, uint32_t dataLen, SingleFileInfo *fileInfo)
1787 {
1788     if ((frame == NULL) || (fileInfo == NULL)) {
1789         TRANS_LOGW(TRANS_FILE, "invalid param.");
1790         return SOFTBUS_INVALID_PARAM;
1791     }
1792     uint32_t seq = frame->seq;
1793     if (seq < 1 || seq >= fileInfo->startSeq + FILE_SEND_ACK_INTERVAL) {
1794         return SOFTBUS_ERR;
1795     }
1796     uint64_t fileOffset = 0;
1797     uint32_t bit = seq % FILE_SEND_ACK_INTERVAL;
1798     bit = ((bit == 0) ? (FILE_SEND_ACK_INTERVAL - 1) : (bit - 1));
1799     if (seq >= fileInfo->startSeq) {
1800         int32_t seqDiff = (int32_t)(seq - fileInfo->seq - 1);
1801 
1802         int64_t bytesToWrite =  (int64_t)(seqDiff * fileInfo->oneFrameLen);
1803         if (MAX_FILE_SIZE < bytesToWrite) {
1804             TRANS_LOGE(TRANS_FILE,
1805                 "WriteEmptyFrame bytesToWrite is too large, bytesToWrite=%{public}" PRIu64, bytesToWrite);
1806             return SOFTBUS_ERR;
1807         }
1808         if (fileInfo->fileOffset > (uint64_t)MAX_FILE_SIZE - bytesToWrite) {
1809             TRANS_LOGE(TRANS_FILE, "file is too large, offset=%{public}" PRIu64,
1810                 fileInfo->fileOffset + bytesToWrite);
1811             return SOFTBUS_ERR;
1812         }
1813 
1814         if (WriteEmptyFrame(fileInfo, seqDiff) != SOFTBUS_OK) {
1815             return SOFTBUS_ERR;
1816         }
1817         if ((seq >= fileInfo->preStartSeq + FILE_SEND_ACK_INTERVAL + WAIT_FRAME_ACK_TIMEOUT_COUNT - 1) ||
1818             (frame->frameType == TRANS_SESSION_FILE_LAST_FRAME && seq > FILE_SEND_ACK_INTERVAL)) {
1819             if ((fileInfo->preSeqResult & FILE_SEND_ACK_RESULT_SUCCESS) != FILE_SEND_ACK_RESULT_SUCCESS) {
1820                 TRANS_LOGE(TRANS_FILE, "recv file fail. frame loss");
1821                 return SOFTBUS_ERR;
1822             }
1823         }
1824         fileInfo->seq = seq;
1825         fileOffset = fileInfo->fileOffset;
1826         fileInfo->seqResult |= 0x01 << bit;
1827     } else {
1828         TRANS_LOGI(TRANS_FILE, "recv retrans file frame");
1829         fileOffset = (seq - 1) * fileInfo->oneFrameLen;
1830         fileInfo->preSeqResult |= 0x01 << bit;
1831     }
1832 
1833     uint32_t frameDataLength = dataLen - FRAME_DATA_SEQ_OFFSET;
1834 
1835     if (MAX_FILE_SIZE < frameDataLength) {
1836         TRANS_LOGE(TRANS_FILE, "frameDataLength is too large, frameDataLen=%{public}" PRIu32,
1837             frameDataLength);
1838         return SOFTBUS_ERR;
1839     }
1840 
1841     if (fileOffset > MAX_FILE_SIZE - frameDataLength) {
1842         TRANS_LOGE(TRANS_FILE, "file is too large, offset=%{public}" PRIu64,
1843             fileOffset + frameDataLength);
1844         return SOFTBUS_ERR;
1845     }
1846 
1847     int64_t writeLength = SoftBusPwriteFile(fileInfo->fileFd, frame->fileData + FRAME_DATA_SEQ_OFFSET,
1848         dataLen - FRAME_DATA_SEQ_OFFSET, fileOffset);
1849     if (writeLength < 0 || (uint64_t)writeLength != dataLen - FRAME_DATA_SEQ_OFFSET) {
1850         TRANS_LOGE(TRANS_FILE, "pwrite file failed");
1851         return SOFTBUS_ERR;
1852     }
1853     if (seq >= fileInfo->startSeq) {
1854         fileInfo->fileOffset += (uint64_t)writeLength;
1855         if (fileInfo->fileOffset > MAX_FILE_SIZE) {
1856             TRANS_LOGE(TRANS_FILE, "file is too large, offset=%{public}" PRIu64,
1857                 fileInfo->fileOffset);
1858             return SOFTBUS_ERR;
1859         }
1860         fileInfo->checkSumCRC += frame->crc;
1861     }
1862     return SOFTBUS_OK;
1863 }
1864 
ProcessOneFrame(const FileFrame * fileFrame,uint32_t dataLen,int32_t crc,SingleFileInfo * fileInfo)1865 static int32_t ProcessOneFrame(const FileFrame *fileFrame, uint32_t dataLen, int32_t crc, SingleFileInfo *fileInfo)
1866 {
1867     if (fileInfo->fileStatus == NODE_ERR) {
1868         TRANS_LOGE(TRANS_FILE, "fileStatus is error");
1869         return SOFTBUS_ERR;
1870     }
1871     if (crc == APP_INFO_FILE_FEATURES_SUPPORT) {
1872         return ProcessOneFrameCRC(fileFrame, dataLen, fileInfo);
1873     } else {
1874         uint32_t frameDataLength = dataLen - FRAME_DATA_SEQ_OFFSET;
1875         fileInfo->seq = fileFrame->seq;
1876 
1877         if (MAX_FILE_SIZE < frameDataLength) {
1878             TRANS_LOGE(TRANS_FILE, "frameDataLength is too large, frameDataLen=%{public}" PRIu32,
1879                 frameDataLength);
1880             return SOFTBUS_ERR;
1881         }
1882 
1883         if (fileInfo->fileOffset > MAX_FILE_SIZE - frameDataLength) {
1884             TRANS_LOGE(TRANS_FILE, "file is too large, offset=%{public}" PRIu64,
1885                 fileInfo->fileOffset + frameDataLength);
1886             return SOFTBUS_ERR;
1887         }
1888         int64_t writeLength = SoftBusPwriteFile(fileInfo->fileFd, fileFrame->fileData + FRAME_DATA_SEQ_OFFSET,
1889             frameDataLength, fileInfo->fileOffset);
1890         if (writeLength != frameDataLength) {
1891             TRANS_LOGE(TRANS_FILE, "pwrite file failed");
1892             return SOFTBUS_ERR;
1893         }
1894         fileInfo->fileOffset += (uint64_t)writeLength;
1895         if (fileInfo->fileOffset > MAX_FILE_SIZE) {
1896             TRANS_LOGE(TRANS_FILE, "file is too large, offset=%{public}" PRIu64, fileInfo->fileOffset);
1897             return SOFTBUS_ERR;
1898         }
1899     }
1900     return SOFTBUS_OK;
1901 }
1902 
WriteFrameToFile(int32_t sessionId,const FileFrame * fileFrame)1903 static int32_t WriteFrameToFile(int32_t sessionId, const FileFrame *fileFrame)
1904 {
1905     FileRecipientInfo *recipient = GetRecipientInProcessRef(sessionId);
1906     if (recipient == NULL) {
1907         TRANS_LOGE(TRANS_FILE, "get recipient in process ref fail");
1908         return SOFTBUS_NOT_FIND;
1909     }
1910     int32_t result = SOFTBUS_ERR;
1911     SingleFileInfo *fileInfo = &recipient->recvFileInfo;
1912     uint32_t dataLen;
1913     if (UnpackFileDataFrame(recipient, (FileFrame *)fileFrame, &dataLen) != SOFTBUS_OK) {
1914         TRANS_LOGE(TRANS_FILE, "unpack file data frame fail");
1915         goto EXIT_ERR;
1916     }
1917     if (ProcessOneFrame(fileFrame, dataLen, recipient->crc, fileInfo) != SOFTBUS_OK) {
1918         TRANS_LOGE(TRANS_FILE, "write one frame error");
1919         goto EXIT_ERR;
1920     }
1921     fileInfo->timeOut = 0;
1922     if (recipient->fileListener.socketRecvCallback != NULL) {
1923         const char *fileList[] = { fileInfo->filePath };
1924         FileEvent event = {
1925             .type = FILE_EVENT_RECV_PROCESS,
1926             .files = fileList,
1927             .fileCnt = 1,
1928             .bytesProcessed = fileInfo->fileOffset,
1929             .bytesTotal = fileInfo->fileSize,
1930             .UpdateRecvPath = NULL,
1931         };
1932         recipient->fileListener.socketRecvCallback(sessionId, &event);
1933     } else if (recipient->fileListener.recvListener.OnReceiveFileProcess != NULL) {
1934         recipient->fileListener.recvListener.OnReceiveFileProcess(sessionId, fileInfo->filePath,
1935             fileInfo->fileOffset, fileInfo->fileSize);
1936     }
1937     if (recipient->crc != APP_INFO_FILE_FEATURES_SUPPORT) {
1938         if ((fileFrame->frameType == TRANS_SESSION_FILE_LAST_FRAME) ||
1939             (fileFrame->frameType == TRANS_SESSION_FILE_ONLYONE_FRAME)) {
1940             TRANS_LOGI(TRANS_FILE, "process last frame, seq=%{public}u", fileFrame->seq);
1941             SetRecipientRecvState(recipient, TRANS_FILE_RECV_IDLE_STATE);
1942             if (SoftBusMutexLock(&g_recvFileInfoLock.lock) != SOFTBUS_OK) {
1943                 TRANS_LOGE(TRANS_FILE, "mutex lock fail");
1944                 return SOFTBUS_LOCK_ERR;
1945             }
1946             (void)FileUnLock(fileInfo->fileFd);
1947             SoftBusCloseFile(fileInfo->fileFd);
1948             fileInfo->fileFd = INVALID_FD;
1949             (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
1950         }
1951     }
1952     ReleaseRecipientRef(recipient);
1953     return SOFTBUS_OK;
1954 EXIT_ERR:
1955     if (recipient->crc == APP_INFO_FILE_FEATURES_SUPPORT) {
1956         (void)SendFileTransResult(recipient->channelId, 0, result, IS_RECV_RESULT);
1957     }
1958     SetRecipientRecvState(recipient, TRANS_FILE_RECV_ERR_STATE);
1959     if (recipient->fileListener.socketRecvCallback != NULL) {
1960         FileEvent event = {.type = FILE_EVENT_RECV_ERROR};
1961         recipient->fileListener.socketRecvCallback(sessionId, &event);
1962     } else if (recipient->fileListener.recvListener.OnFileTransError != NULL) {
1963         recipient->fileListener.recvListener.OnFileTransError(sessionId);
1964     }
1965     ReleaseRecipientRef(recipient);
1966     DelRecipient(sessionId);
1967     return SOFTBUS_ERR;
1968 }
1969 
ProcessFileListData(int32_t sessionId,const FileFrame * frame)1970 static int32_t ProcessFileListData(int32_t sessionId, const FileFrame *frame)
1971 {
1972     FileRecipientInfo *recipient = GetRecipientInfo(sessionId);
1973     if (recipient == NULL) {
1974         TRANS_LOGE(TRANS_FILE, "get recipient info fail");
1975         return SOFTBUS_NOT_FIND;
1976     }
1977     int32_t ret = SOFTBUS_ERR;
1978     int32_t fileCount;
1979     char *fullRecvPath = NULL;
1980     char *absRecvPath = NULL;
1981     char *firstFilePath = BufferToFileList(frame->data, frame->frameLength, &fileCount);
1982     if (firstFilePath == NULL) {
1983         TRANS_LOGE(TRANS_FILE, "buffer to file list fail");
1984         goto EXIT_ERR;
1985     }
1986     fullRecvPath = GetFullRecvPath(firstFilePath, recipient->fileListener.rootDir);
1987     SoftBusFree(firstFilePath);
1988     if (IsPathValid(fullRecvPath) == false) {
1989         TRANS_LOGE(TRANS_FILE, "file list path is invalid");
1990         SoftBusFree(fullRecvPath);
1991         goto EXIT_ERR;
1992     }
1993     absRecvPath = (char *)SoftBusCalloc(PATH_MAX + 1);
1994     if (absRecvPath == NULL) {
1995         TRANS_LOGE(TRANS_FILE, "calloc absFullDir fail");
1996         SoftBusFree(fullRecvPath);
1997         goto EXIT_ERR;
1998     }
1999     if (GetAndCheckRealPath(fullRecvPath, absRecvPath) != SOFTBUS_OK) {
2000         TRANS_LOGE(TRANS_FILE, "get recv abs file path fail");
2001         SoftBusFree(fullRecvPath);
2002         SoftBusFree(absRecvPath);
2003         goto EXIT_ERR;
2004     }
2005     SetRecipientRecvState(recipient, TRANS_FILE_RECV_IDLE_STATE);
2006     if (recipient->fileListener.socketRecvCallback != NULL) {
2007         const char *fileList[] = { absRecvPath };
2008         FileEvent event = {
2009             .type = FILE_EVENT_RECV_FINISH,
2010             .files = fileList,
2011             .fileCnt = 1,
2012             .bytesProcessed = 0,
2013             .bytesTotal = 0,
2014         };
2015         recipient->fileListener.socketRecvCallback(sessionId, &event);
2016     } else if (recipient->fileListener.recvListener.OnReceiveFileFinished != NULL) {
2017         recipient->fileListener.recvListener.OnReceiveFileFinished(sessionId, absRecvPath, fileCount);
2018     }
2019     SoftBusFree(fullRecvPath);
2020     SoftBusFree(absRecvPath);
2021     ret = SOFTBUS_OK;
2022 EXIT_ERR:
2023     if (ret != SOFTBUS_OK) {
2024         if (recipient->fileListener.socketRecvCallback != NULL) {
2025             FileEvent event = {.type = FILE_EVENT_RECV_ERROR};
2026             recipient->fileListener.socketRecvCallback(sessionId, &event);
2027         } else if (recipient->fileListener.recvListener.OnFileTransError != NULL) {
2028             recipient->fileListener.recvListener.OnFileTransError(sessionId);
2029         }
2030         SetRecipientRecvState(recipient, TRANS_FILE_RECV_ERR_STATE);
2031     }
2032     ReleaseRecipientRef(recipient);
2033     DelRecipient(sessionId);
2034     return ret;
2035 }
2036 
ProcessFileRecvResult(int32_t sessionId,uint32_t seq,int32_t result)2037 static int32_t ProcessFileRecvResult(int32_t sessionId, uint32_t seq, int32_t result)
2038 {
2039     if (SoftBusMutexLock(&g_sendFileInfoLock.lock) != SOFTBUS_OK) {
2040         TRANS_LOGE(TRANS_FILE, "process recv result lock fail");
2041         return SOFTBUS_LOCK_ERR;
2042     }
2043     SendListenerInfo *item = NULL;
2044     SendListenerInfo *info = NULL;
2045     LIST_FOR_EACH_ENTRY(item, &g_sendListenerInfoList, SendListenerInfo, node) {
2046         if (item->sessionId == sessionId) {
2047             info = item;
2048             info->result = result;
2049             break;
2050         }
2051     }
2052     (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
2053     if (info != NULL) {
2054         (void)SetPendingPacketData(sessionId, seq, NULL);
2055         return SOFTBUS_OK;
2056     }
2057     return SOFTBUS_NOT_FIND;
2058 }
2059 
ProcessFileSendResult(int32_t sessionId,uint32_t seq,int32_t result)2060 static int32_t ProcessFileSendResult(int32_t sessionId, uint32_t seq, int32_t result)
2061 {
2062     (void)seq;
2063     if (SoftBusMutexLock(&g_recvFileInfoLock.lock) != SOFTBUS_OK) {
2064         TRANS_LOGE(TRANS_FILE, "process send result lock fail");
2065         return SOFTBUS_LOCK_ERR;
2066     }
2067     FileRecipientInfo *item = NULL;
2068     FileRecipientInfo *info = NULL;
2069     LIST_FOR_EACH_ENTRY(item, &g_recvRecipientInfoList, FileRecipientInfo, node) {
2070         if (item->sessionId == sessionId) {
2071             info = item;
2072             info->result = result;
2073             break;
2074         }
2075     }
2076     (void)SoftBusMutexUnlock(&g_recvFileInfoLock.lock);
2077     if (info != NULL) {
2078         return SOFTBUS_OK;
2079     }
2080     return SOFTBUS_NOT_FIND;
2081 }
2082 
ProcessFileTransResult(int32_t sessionId,const FileFrame * frame)2083 static int32_t ProcessFileTransResult(int32_t sessionId, const FileFrame *frame)
2084 {
2085     if (frame == NULL) {
2086         TRANS_LOGE(TRANS_FILE, "invalid param.");
2087         return SOFTBUS_INVALID_PARAM;
2088     }
2089     TRANS_LOGI(TRANS_FILE, "proxy channel send file result. sessionId=%{public}d", sessionId);
2090     uint32_t seq;
2091     int32_t result;
2092     uint32_t side;
2093     if (UnpackFileTransResultFrame(frame->data, frame->frameLength, &seq, &result, &side) != SOFTBUS_OK) {
2094         TRANS_LOGE(TRANS_FILE, "file trans fail");
2095         return SOFTBUS_ERR;
2096     }
2097     if (side == IS_RECV_RESULT) {
2098         return ProcessFileRecvResult(sessionId, seq, result);
2099     } else if (side == IS_SEND_RESULT) {
2100         return ProcessFileSendResult(sessionId, seq, result);
2101     }
2102     return SOFTBUS_OK;
2103 }
2104 
ProcessCrcCheckSumData(int32_t sessionId,const FileFrame * frame)2105 static int32_t ProcessCrcCheckSumData(int32_t sessionId, const FileFrame *frame)
2106 {
2107     if (frame == NULL) {
2108         TRANS_LOGE(TRANS_FILE, "invalid param.");
2109         return SOFTBUS_INVALID_PARAM;
2110     }
2111     TRANS_LOGI(TRANS_FILE, "proxy channel recv file crc data. sessionId=%{public}d, frameLen=%{public}d",
2112         sessionId, frame->frameLength);
2113     FileRecipientInfo *recipient = GetRecipientInProcessRef(sessionId);
2114     if (recipient == NULL) {
2115         TRANS_LOGE(TRANS_FILE, "recipient invalid");
2116         return SOFTBUS_NOT_FIND;
2117     }
2118     int32_t result = UnpackFileCrcCheckSum(recipient, (FileFrame *)frame);
2119     TRANS_LOGE(TRANS_FILE, "verification crc check sum, ret=%{public}d", result);
2120     int32_t ret = SendFileTransResult(recipient->channelId, frame->seq, result, IS_RECV_RESULT);
2121     ReleaseRecipientRef(recipient);
2122     if (result != SOFTBUS_OK || ret != SOFTBUS_OK) {
2123         SetRecipientRecvState(recipient, TRANS_FILE_RECV_ERR_STATE);
2124         DelRecipient(sessionId);
2125         return SOFTBUS_ERR;
2126     }
2127     SetRecipientRecvState(recipient, TRANS_FILE_RECV_IDLE_STATE);
2128     return SOFTBUS_OK;
2129 }
2130 
ProcessFileAckRequest(int32_t sessionId,const FileFrame * frame)2131 static int32_t ProcessFileAckRequest(int32_t sessionId, const FileFrame *frame)
2132 {
2133     if (frame == NULL) {
2134         TRANS_LOGE(TRANS_FILE, "invalid param.");
2135         return SOFTBUS_INVALID_PARAM;
2136     }
2137     TRANS_LOGI(TRANS_FILE, "proxy channel recv file ack request. sessionId=%{public}d, len=%{public}u",
2138         sessionId, frame->frameLength);
2139     FileRecipientInfo *recipient = GetRecipientInProcessRef(sessionId);
2140     if (recipient == NULL) {
2141         return SOFTBUS_NOT_FIND;
2142     }
2143     uint32_t startSeq;
2144     uint32_t value;
2145     if (UnpackAckReqAndResData((FileFrame *)frame, &startSeq, &value) != SOFTBUS_OK) {
2146         ReleaseRecipientRef(recipient);
2147         return SOFTBUS_ERR;
2148     }
2149     SingleFileInfo *file = &recipient->recvFileInfo;
2150     if (startSeq != file->startSeq) {
2151         TRANS_LOGE(TRANS_FILE, "start seq not equal. startSeq=%{public}u, curSeq=%{public}u",
2152             startSeq, file->startSeq);
2153         ReleaseRecipientRef(recipient);
2154         return SOFTBUS_ERR;
2155     }
2156     file->timeOut = 0;
2157     file->preStartSeq = startSeq;
2158     file->startSeq = startSeq + FILE_SEND_ACK_INTERVAL;
2159     value = (uint32_t)(file->seqResult & FILE_SEND_ACK_RESULT_SUCCESS);
2160     file->preSeqResult = value;
2161     file->seqResult = (file->seqResult >> FILE_SEND_ACK_INTERVAL);
2162     int32_t ret = SendFileAckReqAndResData(recipient->channelId, startSeq, value,
2163         TRANS_SESSION_FILE_ACK_RESPONSE_SENT);
2164     TRANS_LOGI(TRANS_FILE, "send file ack response, ret=%{public}d", ret);
2165     ReleaseRecipientRef(recipient);
2166     return ret;
2167 }
2168 
ProcessFileAckResponse(int32_t sessionId,const FileFrame * frame)2169 static int32_t ProcessFileAckResponse(int32_t sessionId, const FileFrame *frame)
2170 {
2171     if ((frame == NULL) || (frame->data == NULL) || (frame->frameLength == 0)) {
2172         TRANS_LOGE(TRANS_FILE, "invalid param.");
2173         return SOFTBUS_INVALID_PARAM;
2174     }
2175     AckResponseData *data = (AckResponseData *)SoftBusCalloc(sizeof(AckResponseData));
2176     if (data == NULL) {
2177         return SOFTBUS_MALLOC_ERR;
2178     }
2179     TransPendData pendData = {
2180         .data = (char *)data,
2181         .len = sizeof(AckResponseData),
2182     };
2183     if (UnpackAckReqAndResData((FileFrame *)frame, &data->startSeq, &data->seqResult) != SOFTBUS_OK) {
2184         TRANS_LOGE(TRANS_FILE, "proxy recv unpack ack response fail");
2185         SoftBusFree(data);
2186         return SOFTBUS_ERR;
2187     }
2188     TRANS_LOGI(TRANS_FILE, "recv file ack response. sessionId=%{public}d, startSeq=%{public}u, seqRet=%{public}u",
2189         sessionId, data->startSeq, data->seqResult);
2190     if (SoftBusMutexLock(&g_sendFileInfoLock.lock) != SOFTBUS_OK) {
2191         SoftBusFree(data);
2192         TRANS_LOGE(TRANS_FILE, "proxy recv ack response lock fail");
2193         return SOFTBUS_LOCK_ERR;
2194     }
2195     SendListenerInfo *item = NULL;
2196     LIST_FOR_EACH_ENTRY(item, &g_sendListenerInfoList, SendListenerInfo, node) {
2197         if (item->sessionId == sessionId) {
2198             if (SetPendingPacketData((uint32_t)sessionId, (uint64_t)(item->waitSeq), &pendData) != SOFTBUS_OK) {
2199                 TRANS_LOGE(TRANS_FILE, "proxy recv ack response set pend packet fail");
2200                 (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
2201                 SoftBusFree(data);
2202                 return SOFTBUS_ERR;
2203             }
2204             (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
2205             return SOFTBUS_OK;
2206         }
2207     }
2208     (void)SoftBusMutexUnlock(&g_sendFileInfoLock.lock);
2209     TRANS_LOGE(TRANS_FILE, "recv ack response not find. sessionId=%{public}d, startSeq=%{public}u",
2210         sessionId, data->startSeq);
2211     SoftBusFree(data);
2212     return SOFTBUS_NOT_FIND;
2213 }
2214 
ProcessRecvFileFrameData(int32_t sessionId,int32_t channelId,const FileFrame * oneFrame)2215 int32_t ProcessRecvFileFrameData(int32_t sessionId, int32_t channelId, const FileFrame *oneFrame)
2216 {
2217     if (oneFrame == NULL) {
2218         TRANS_LOGE(TRANS_FILE, "invalid param.");
2219         return SOFTBUS_INVALID_PARAM;
2220     }
2221     if (oneFrame->frameLength > PROXY_MAX_PACKET_SIZE) {
2222         TRANS_LOGE(TRANS_FILE, "len > PROXY_MAX_PACKET_SIZE");
2223         return SOFTBUS_ERR;
2224     }
2225     int32_t ret;
2226     switch (oneFrame->frameType) {
2227         case TRANS_SESSION_FILE_FIRST_FRAME:
2228             TRANS_LOGI(TRANS_FILE, "create file from frame start sessionId=%{public}d", sessionId);
2229             ret = CreateFileFromFrame(sessionId, channelId, oneFrame);
2230             TRANS_LOGI(TRANS_FILE, "create file from frame ret=%{public}d", ret);
2231             break;
2232         case TRANS_SESSION_FILE_ONGOINE_FRAME:
2233         case TRANS_SESSION_FILE_ONLYONE_FRAME:
2234         case TRANS_SESSION_FILE_LAST_FRAME:
2235             ret = WriteFrameToFile(sessionId, oneFrame);
2236             if (ret != SOFTBUS_OK) {
2237                 TRANS_LOGE(TRANS_FILE, "write frame fail ret=%{public}d", ret);
2238             }
2239             break;
2240         case TRANS_SESSION_FILE_ACK_REQUEST_SENT:
2241             ret = ProcessFileAckRequest(sessionId, oneFrame);
2242             break;
2243         case TRANS_SESSION_FILE_ACK_RESPONSE_SENT:
2244             ret = ProcessFileAckResponse(sessionId, oneFrame);
2245             break;
2246         case TRANS_SESSION_FILE_CRC_CHECK_FRAME:
2247             ret = ProcessCrcCheckSumData(sessionId, oneFrame);
2248             TRANS_LOGI(TRANS_FILE, "process crc check sum. sessionId=%{public}d, ret=%{public}d",
2249                 sessionId, ret);
2250             break;
2251         case TRANS_SESSION_FILE_RESULT_FRAME:
2252             ret = ProcessFileTransResult(sessionId, oneFrame);
2253             break;
2254         case TRANS_SESSION_FILE_ALLFILE_SENT:
2255             ret = ProcessFileListData(sessionId, oneFrame);
2256             TRANS_LOGI(TRANS_FILE, "process file list data. sessionId=%{public}d, ret=%{public}d",
2257                 sessionId, ret);
2258             break;
2259         default:
2260             TRANS_LOGE(TRANS_FILE, "frame type is invalid sessionId=%{public}d", sessionId);
2261             return SOFTBUS_ERR;
2262     }
2263     return ret;
2264 }
2265 
ProcessFileFrameData(int32_t sessionId,int32_t channelId,const char * data,uint32_t len,int32_t type)2266 int32_t ProcessFileFrameData(int32_t sessionId, int32_t channelId, const char *data, uint32_t len, int32_t type)
2267 {
2268     FileFrame oneFrame;
2269     oneFrame.frameType = type;
2270     oneFrame.frameLength = len;
2271     oneFrame.data = (uint8_t *)data;
2272     return ProcessRecvFileFrameData(sessionId, channelId, &oneFrame);
2273 }
2274 
GenerateRemoteFiles(const char * sFileList[],uint32_t fileCnt)2275 static const char **GenerateRemoteFiles(const char *sFileList[], uint32_t fileCnt)
2276 {
2277     const char **files = (const char **)SoftBusCalloc(sizeof(const char *) * fileCnt);
2278     if (files == NULL) {
2279         TRANS_LOGE(TRANS_SDK, "malloc *fileCnt oom");
2280         return NULL;
2281     }
2282     for (uint32_t i = 0; i < fileCnt; i++) {
2283         files[i] = TransGetFileName(sFileList[i]);
2284         if (files[i] == NULL) {
2285             TRANS_LOGE(TRANS_SDK, "GetFileName failed at index=%{public}" PRIu32, i);
2286             SoftBusFree(files);
2287             return NULL;
2288         }
2289     }
2290     return files;
2291 }
2292 
TransProxyChannelSendFile(int32_t channelId,const char * sFileList[],const char * dFileList[],uint32_t fileCnt)2293 int32_t TransProxyChannelSendFile(int32_t channelId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt)
2294 {
2295     if (sFileList == NULL || fileCnt == 0 || fileCnt > MAX_SEND_FILE_NUM) {
2296         TRANS_LOGE(TRANS_SDK, "input para failed! fileCnt=%{public}" PRIu32, fileCnt);
2297         return SOFTBUS_INVALID_PARAM;
2298     }
2299     const char **remoteFiles = NULL;
2300     const char **generatedRemoteFiles = NULL;
2301     if (dFileList == NULL) {
2302         generatedRemoteFiles = GenerateRemoteFiles(sFileList, fileCnt);
2303         if (generatedRemoteFiles == NULL) {
2304             return SOFTBUS_ERR;
2305         }
2306         remoteFiles = generatedRemoteFiles;
2307     } else {
2308         remoteFiles = dFileList;
2309     }
2310     int32_t ret = ProxyChannelSendFile(channelId, sFileList, remoteFiles, fileCnt);
2311     if (generatedRemoteFiles != NULL) {
2312         SoftBusFree(generatedRemoteFiles);
2313         generatedRemoteFiles = NULL;
2314     }
2315     return ret;
2316 }
2317