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