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