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 }