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