1 /*
2 * Copyright (c) 2021 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_manager.h"
17
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <limits.h>
21 #include <securec.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25
26 #include "client_trans_session_manager.h"
27 #include "client_trans_tcp_direct_message.h"
28 #include "softbus_adapter_mem.h"
29 #include "softbus_adapter_timer.h"
30 #include "softbus_conn_interface.h"
31 #include "softbus_errcode.h"
32 #include "softbus_feature_config.h"
33 #include "softbus_log.h"
34 #include "softbus_utils.h"
35 #include "trans_server_proxy.h"
36
37 static IClientSessionCallBack g_sessionCb;
38 static uint32_t g_authMaxByteBufSize;
39 static uint32_t g_authMaxMessageBufSize;
40 static SendFileInfo g_sendFileInfo = {
41 .seqCount = 0,
42 .seqLockInitFlag = false,
43 };
44
45 static RecvFileInfo g_recvFileInfo = {
46 .sessionId = 0,
47 };
48
49 static void ProxyFileTransTimerProc(void);
50
51 #define BYTE_INT_NUM 4
52 #define BIT_INT_NUM 32
53 #define BIT_BYTE_NUM 8
54 #define SEND_DELAY_TIME 20
55
ClinetTransProxyInit(const IClientSessionCallBack * cb)56 int32_t ClinetTransProxyInit(const IClientSessionCallBack *cb)
57 {
58 if (cb == NULL) {
59 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ClinetTransProxyInit cb param is null!");
60 return SOFTBUS_INVALID_PARAM;
61 }
62
63 g_sessionCb = *cb;
64 if (g_sendFileInfo.seqLockInitFlag == false) {
65 if (SoftBusMutexInit(&g_sendFileInfo.lock, NULL) != SOFTBUS_OK) {
66 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sendfile mutex init fail!");
67 return SOFTBUS_ERR;
68 }
69 g_sendFileInfo.seqLockInitFlag = true;
70 }
71
72 if (SoftBusMutexInit(&g_recvFileInfo.lock, NULL) != SOFTBUS_OK) {
73 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "recvfile mutex init fail!");
74 return SOFTBUS_ERR;
75 }
76
77 if (RegisterTimeoutCallback(SOFTBUS_PROXY_SENDFILE_TIMER_FUN, ProxyFileTransTimerProc) != SOFTBUS_OK) {
78 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "register sendfile timer fail");
79 }
80
81 if (SoftbusGetConfig(SOFTBUS_INT_AUTH_MAX_BYTES_LENGTH,
82 (unsigned char*)&g_authMaxByteBufSize, sizeof(g_authMaxByteBufSize)) != SOFTBUS_OK) {
83 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "get auth proxy channel max bytes length fail");
84 }
85 if (SoftbusGetConfig(SOFTBUS_INT_AUTH_MAX_MESSAGE_LENGTH,
86 (unsigned char*)&g_authMaxMessageBufSize, sizeof(g_authMaxMessageBufSize)) != SOFTBUS_OK) {
87 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "get auth proxy channel max message length fail");
88 }
89 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "proxy auth byteSize[%u], messageSize[%u]",
90 g_authMaxByteBufSize, g_authMaxMessageBufSize);
91 return SOFTBUS_OK;
92 }
93
ClientTransProxyDeinit(void)94 void ClientTransProxyDeinit(void)
95 {
96 if (SoftBusMutexDestroy(&g_sendFileInfo.lock) != SOFTBUS_OK) {
97 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "destroy send file lock fail");
98 return;
99 }
100 if (SoftBusMutexDestroy(&g_recvFileInfo.lock) != SOFTBUS_OK) {
101 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "destroy recv file lock fail");
102 return;
103 }
104 }
105
ClientTransProxyOnChannelOpened(const char * sessionName,const ChannelInfo * channel)106 int32_t ClientTransProxyOnChannelOpened(const char *sessionName, const ChannelInfo *channel)
107 {
108 if (sessionName == NULL || channel == NULL) {
109 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ClientTransProxyOnChannelOpened invalid param.");
110 return SOFTBUS_INVALID_PARAM;
111 }
112
113 int ret = g_sessionCb.OnSessionOpened(sessionName, channel, TYPE_MESSAGE);
114 if (ret != SOFTBUS_OK) {
115 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "notify session open fail, sessionName=[%s].", sessionName);
116 return ret;
117 }
118
119 return SOFTBUS_OK;
120 }
121
ClientTransProxyOnChannelClosed(int32_t channelId)122 int32_t ClientTransProxyOnChannelClosed(int32_t channelId)
123 {
124 int ret = g_sessionCb.OnSessionClosed(channelId, CHANNEL_TYPE_PROXY);
125 if (ret != SOFTBUS_OK) {
126 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "notify session closed err[%d], cId[%d].", ret, channelId);
127 return ret;
128 }
129 return SOFTBUS_OK;
130 }
131
ClientTransProxyOnChannelOpenFailed(int32_t channelId)132 int32_t ClientTransProxyOnChannelOpenFailed(int32_t channelId)
133 {
134 int ret = g_sessionCb.OnSessionOpenFailed(channelId, CHANNEL_TYPE_PROXY);
135 if (ret != SOFTBUS_OK) {
136 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "notify session openfail cId[%d].", channelId);
137 return ret;
138 }
139
140 return SOFTBUS_OK;
141 }
142
ClientTransProxyOnDataReceived(int32_t channelId,const void * data,uint32_t len,SessionPktType type)143 int32_t ClientTransProxyOnDataReceived(int32_t channelId,
144 const void *data, uint32_t len, SessionPktType type)
145 {
146 if (data == NULL) {
147 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR,
148 "ClientTransProxyOnDataReceived cId[%d] data null.", channelId);
149 return SOFTBUS_INVALID_PARAM;
150 }
151 int ret = g_sessionCb.OnDataReceived(channelId, CHANNEL_TYPE_PROXY, data, len, type);
152 if (ret != SOFTBUS_OK) {
153 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "notify data recv err, cId[%d].", channelId);
154 return ret;
155 }
156 return SOFTBUS_OK;
157 }
158
ClientTransProxyCloseChannel(int32_t channelId)159 void ClientTransProxyCloseChannel(int32_t channelId)
160 {
161 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "TransCloseProxyChannel, channelId [%d]", channelId);
162 if (ServerIpcCloseChannel(channelId, CHANNEL_TYPE_PROXY) != SOFTBUS_OK) {
163 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "server close channel[%d] err.", channelId);
164 }
165 }
166
TransProxyChannelSendBytes(int32_t channelId,const void * data,uint32_t len)167 int32_t TransProxyChannelSendBytes(int32_t channelId, const void *data, uint32_t len)
168 {
169 #define PROXY_MAX_BYTES_LEN (4 * 1024)
170 int32_t encryp = 0;
171 int32_t ret = GetEncryptByChannelId(channelId, CHANNEL_TYPE_PROXY, &encryp);
172 if (ret != SOFTBUS_OK) {
173 return SOFTBUS_ERR;
174 }
175 if (encryp == 1) {
176 if (len > PROXY_MAX_BYTES_LEN) {
177 return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
178 }
179 } else {
180 if (len > g_authMaxByteBufSize) {
181 return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
182 }
183 }
184 ret = ServerIpcSendMessage(channelId, CHANNEL_TYPE_PROXY, data, len, TRANS_SESSION_BYTES);
185 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send bytes: channelId=%d, ret=%d", channelId, ret);
186 return ret;
187 }
188
TransProxyChannelSendMessage(int32_t channelId,const void * data,uint32_t len)189 int32_t TransProxyChannelSendMessage(int32_t channelId, const void *data, uint32_t len)
190 {
191 #define PROXY_MAX_MESSAGE_LEN (1 * 1024)
192 int32_t encryp = 0;
193 int32_t ret = GetEncryptByChannelId(channelId, CHANNEL_TYPE_PROXY, &encryp);
194 if (ret != SOFTBUS_OK) {
195 return SOFTBUS_ERR;
196 }
197 if (encryp == 1) {
198 if (len > PROXY_MAX_MESSAGE_LEN) {
199 return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
200 }
201 } else {
202 if (len > g_authMaxMessageBufSize) {
203 return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
204 }
205 }
206 ret = ServerIpcSendMessage(channelId, CHANNEL_TYPE_PROXY, data, len, TRANS_SESSION_MESSAGE);
207 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send msg: channelId=%d, ret=%d", channelId, ret);
208 return ret;
209 }
210
IntToByte(uint32_t value,char * buffer,uint32_t len)211 static bool IntToByte(uint32_t value, char *buffer, uint32_t len)
212 {
213 if ((buffer == NULL) || (len < sizeof(uint32_t))) {
214 return false;
215 }
216
217 for (uint32_t i = 0; i < BYTE_INT_NUM; i++) {
218 uint32_t offset = BIT_INT_NUM - (i + 1) * BIT_BYTE_NUM;
219 buffer[i] = (char)((value >> offset) & 0xFF);
220 }
221 return true;
222 }
223
ByteToInt(char * buffer,uint32_t len,uint32_t * outValue)224 static bool ByteToInt(char *buffer, uint32_t len, uint32_t *outValue)
225 {
226 if ((outValue == NULL) || (buffer == NULL) || (len < sizeof(uint32_t))) {
227 return false;
228 }
229 uint32_t value = 0;
230 for (int32_t i = 0; i < BYTE_INT_NUM; i++) {
231 value <<= BIT_BYTE_NUM;
232 value |= buffer[i] & 0xFF;
233 }
234
235 *outValue = value;
236 return true;
237 }
238
GetIdleIndexNode(int32_t * index)239 static int32_t GetIdleIndexNode(int32_t *index)
240 {
241 if (index == NULL) {
242 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "input index is null");
243 return SOFTBUS_ERR;
244 }
245 int32_t i;
246 for (i = 0; i < MAX_RECV_FILE_NUM; i++) {
247 if (g_recvFileInfo.recvFileInfo[i].fileStatus == NODE_IDLE) {
248 *index = i;
249 return SOFTBUS_OK;
250 }
251 }
252
253 if (i == MAX_RECV_FILE_NUM) {
254 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "there is no idle node");
255 *index = INVALID_NODE_INDEX;
256 return SOFTBUS_ERR;
257 }
258
259 return SOFTBUS_OK;
260 }
261
GetRecvFileInfoBySeq(uint32_t seq,SingleFileInfo * fileInfo)262 static int32_t GetRecvFileInfoBySeq(uint32_t seq, SingleFileInfo *fileInfo)
263 {
264 if (fileInfo == NULL) {
265 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fd is null");
266 return SOFTBUS_ERR;
267 }
268
269 int32_t i;
270 for (i = 0; i < MAX_RECV_FILE_NUM; i++) {
271 if (g_recvFileInfo.recvFileInfo[i].seq == seq) {
272 fileInfo->index = g_recvFileInfo.recvFileInfo[i].index;
273 fileInfo->seq = seq;
274 fileInfo->fileFd = g_recvFileInfo.recvFileInfo[i].fileFd;
275 fileInfo->fileStatus = g_recvFileInfo.recvFileInfo[i].fileStatus;
276 fileInfo->fileOffset = g_recvFileInfo.recvFileInfo[i].fileOffset;
277 if (memcpy_s(fileInfo->filePath, MAX_FILE_PATH_NAME_LEN, g_recvFileInfo.recvFileInfo[i].filePath,
278 MAX_FILE_PATH_NAME_LEN) != EOK) {
279 return SOFTBUS_ERR;
280 }
281 return SOFTBUS_OK;
282 }
283 }
284
285 if (i == MAX_RECV_FILE_NUM) {
286 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "there is no match seq to get");
287 return SOFTBUS_ERR;
288 }
289
290 return SOFTBUS_OK;
291 }
292
RemoveFromRecvListBySeq(uint32_t seq)293 static int32_t RemoveFromRecvListBySeq(uint32_t seq)
294 {
295 int32_t i;
296 for (i = 0; i < MAX_RECV_FILE_NUM; i++) {
297 if (g_recvFileInfo.recvFileInfo[i].seq == seq) {
298 g_recvFileInfo.recvFileInfo[i].index = 0;
299 g_recvFileInfo.recvFileInfo[i].seq = 0;
300 g_recvFileInfo.recvFileInfo[i].fileFd = INVALID_FD;
301 g_recvFileInfo.recvFileInfo[i].fileStatus = NODE_IDLE;
302 g_recvFileInfo.recvFileInfo[i].fileOffset = 0;
303 g_recvFileInfo.recvFileInfo[i].timeOut = 0;
304 memset_s(g_recvFileInfo.recvFileInfo[i].filePath, MAX_FILE_PATH_NAME_LEN, 0, MAX_FILE_PATH_NAME_LEN);
305 memset_s(&g_recvFileInfo.fileListener, sizeof(FileListener), 0, sizeof(FileListener));
306 return SOFTBUS_OK;
307 }
308 }
309
310 if (i == MAX_RECV_FILE_NUM) {
311 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "there is no match seq to clear");
312 return SOFTBUS_ERR;
313 }
314
315 return SOFTBUS_OK;
316 }
317
CheckRecvFileExist(const char * absFullPath)318 static bool CheckRecvFileExist(const char *absFullPath)
319 {
320 if (absFullPath == NULL) {
321 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "absFullPath is null");
322 return false;
323 }
324
325 int32_t i;
326 for (i = 0; i < MAX_RECV_FILE_NUM; i++) {
327 if ((strcmp(g_recvFileInfo.recvFileInfo[i].filePath, absFullPath) == 0) &&
328 (g_recvFileInfo.recvFileInfo[i].fileStatus == NODE_BUSY)) {
329 return true;
330 }
331 }
332
333 return false;
334 }
335
PutToRecvList(int32_t fd,uint32_t seq,const char * destFilePath,FileListener fileListener,int32_t sessionId)336 static int32_t PutToRecvList(int32_t fd, uint32_t seq, const char *destFilePath, FileListener fileListener,
337 int32_t sessionId)
338 {
339 if (destFilePath == NULL) {
340 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "destFilePath is null");
341 return SOFTBUS_ERR;
342 }
343 int index = 0;
344 if (GetIdleIndexNode(&index) != SOFTBUS_OK) {
345 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "GetIdleIndexNode fail");
346 return SOFTBUS_ERR;
347 }
348 g_recvFileInfo.sessionId = sessionId;
349 g_recvFileInfo.recvFileInfo[index].index = index;
350 g_recvFileInfo.recvFileInfo[index].seq = seq;
351 g_recvFileInfo.recvFileInfo[index].fileFd = fd;
352 g_recvFileInfo.recvFileInfo[index].fileStatus = NODE_BUSY;
353 g_recvFileInfo.recvFileInfo[index].fileOffset = 0;
354 g_recvFileInfo.recvFileInfo[index].timeOut = 0;
355 if (memcpy_s(g_recvFileInfo.recvFileInfo[index].filePath, MAX_FILE_PATH_NAME_LEN,
356 destFilePath, MAX_FILE_PATH_NAME_LEN) != EOK) {
357 return SOFTBUS_ERR;
358 }
359 if (memcpy_s(&g_recvFileInfo.fileListener, sizeof(FileListener),
360 &fileListener, sizeof(FileListener)) != EOK) {
361 return SOFTBUS_ERR;
362 }
363 return SOFTBUS_OK;
364 }
365
UpdateRecvInfo(SingleFileInfo fileInfo)366 static int32_t UpdateRecvInfo(SingleFileInfo fileInfo)
367 {
368 int index = fileInfo.index;
369 if (index >= MAX_RECV_FILE_NUM) {
370 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fileInfo.index is large than MAX_RECV_FILE_NUM");
371 return SOFTBUS_ERR;
372 }
373 g_recvFileInfo.sessionId = 0;
374 g_recvFileInfo.recvFileInfo[index].index = fileInfo.index;
375 g_recvFileInfo.recvFileInfo[index].seq = fileInfo.seq;
376 g_recvFileInfo.recvFileInfo[index].fileFd = fileInfo.fileFd;
377 g_recvFileInfo.recvFileInfo[index].fileStatus = fileInfo.fileStatus;
378 g_recvFileInfo.recvFileInfo[index].fileOffset = fileInfo.fileOffset;
379 g_recvFileInfo.recvFileInfo[index].timeOut = fileInfo.timeOut;
380 if (memcpy_s(g_recvFileInfo.recvFileInfo[index].filePath, MAX_FILE_PATH_NAME_LEN, fileInfo.filePath,
381 MAX_FILE_PATH_NAME_LEN) != EOK) {
382 return SOFTBUS_ERR;
383 }
384 return SOFTBUS_OK;
385 }
386
IsValidFileString(const char * str[],uint32_t fileNum,size_t maxLen)387 static bool IsValidFileString(const char *str[], uint32_t fileNum, size_t maxLen)
388 {
389 if (str == NULL || fileNum == 0) {
390 return false;
391 }
392 for (uint32_t i = 0; i < fileNum; i++) {
393 if (str[i] == NULL) {
394 return false;
395 }
396 size_t len = strlen(str[i]);
397 if (len == 0 || len > (maxLen - 1)) {
398 return false;
399 }
400 }
401 return true;
402 }
403
FrameIndexToType(uint64_t index,uint64_t frameNumber)404 static int32_t FrameIndexToType(uint64_t index, uint64_t frameNumber)
405 {
406 #define FRAME_NUM_0 0
407 #define FRAME_NUM_1 1
408 #define FRAME_NUM_2 2
409 if (index == FRAME_NUM_0) {
410 return FILE_FIRST_FRAME;
411 }
412
413 if ((index == FRAME_NUM_1) && (frameNumber == FRAME_NUM_2)) {
414 return FILE_ONLYONE_FRAME;
415 }
416
417 if (index == (frameNumber - 1)) {
418 return FILE_LAST_FRAME;
419 }
420
421 return FILE_ONGOINE_FRAME;
422 }
423
ProxyChannelSendFileStream(int32_t channelId,const char * data,uint32_t len,int32_t type)424 static int32_t ProxyChannelSendFileStream(int32_t channelId, const char *data, uint32_t len, int32_t type)
425 {
426 #define FILE_RETRY_DELAY_TIME 100
427 #define FILE_RETRY_COUNT 3
428 int32_t retry = FILE_RETRY_COUNT;
429 int32_t ret;
430 while (retry) {
431 ret = ServerIpcSendMessage(channelId, CHANNEL_TYPE_PROXY, data, len, type);
432 if (ret == SOFTBUS_CONNECTION_ERR_SENDQUEUE_FULL) {
433 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "send queue full %d", ret);
434 SoftBusSleepMs(FILE_RETRY_DELAY_TIME);
435 retry--;
436 continue;
437 }
438 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send msg(%d): type=%d, ret=%d", channelId, type, ret);
439 return ret;
440 }
441 return ret;
442 }
443
FrameTypeToSessionType(int32_t type)444 static int32_t FrameTypeToSessionType(int32_t type)
445 {
446 switch (type) {
447 case FILE_FIRST_FRAME:
448 return TRANS_SESSION_FILE_FIRST_FRAME;
449 case FILE_ONGOINE_FRAME:
450 return TRANS_SESSION_FILE_ONGOINE_FRAME;
451 case FILE_LAST_FRAME:
452 return TRANS_SESSION_FILE_LAST_FRAME;
453 case FILE_ONLYONE_FRAME:
454 return TRANS_SESSION_FILE_ONLYONE_FRAME;
455 case FILE_ALLFILE_SENT:
456 return TRANS_SESSION_FILE_ALLFILE_SENT;
457 default:
458 return SOFTBUS_ERR;
459 }
460 }
461
DoTransErrorCallBack(void)462 static void DoTransErrorCallBack(void)
463 {
464 if (g_recvFileInfo.fileListener.recvListener.OnFileTransError != NULL) {
465 g_recvFileInfo.fileListener.recvListener.OnFileTransError(g_recvFileInfo.sessionId);
466 }
467 }
468
ProxyFileTransTimerProc(void)469 static void ProxyFileTransTimerProc(void)
470 {
471 #define FILE_TRANS_TIMEOUT 10
472 if (SoftBusMutexLock(&g_recvFileInfo.lock) != SOFTBUS_OK) {
473 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock file timer failed");
474 return;
475 }
476
477 for (int32_t index = 0; index < MAX_RECV_FILE_NUM; index++) {
478 int32_t status = g_recvFileInfo.recvFileInfo[index].fileStatus;
479 int32_t timeOut = g_recvFileInfo.recvFileInfo[index].timeOut;
480 if (status == NODE_BUSY) {
481 if (timeOut >= FILE_TRANS_TIMEOUT) {
482 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "file %s recv timeout",
483 g_recvFileInfo.recvFileInfo[index].filePath);
484 g_recvFileInfo.recvFileInfo[index].fileStatus = NODE_ERR;
485 g_recvFileInfo.recvFileInfo[index].timeOut = 0;
486 close(g_recvFileInfo.recvFileInfo[index].fileFd);
487 remove(g_recvFileInfo.recvFileInfo[index].filePath);
488 DoTransErrorCallBack();
489 } else {
490 g_recvFileInfo.recvFileInfo[index].timeOut++;
491 }
492 }
493 }
494
495 SoftBusMutexUnlock(&g_recvFileInfo.lock);
496 return;
497 }
498
GetAndCheckRealPath(const char * filePath,char * absPath)499 static char *GetAndCheckRealPath(const char *filePath, char *absPath)
500 {
501 if ((filePath == NULL) || (absPath == NULL)) {
502 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "input invalid");
503 return NULL;
504 }
505
506 char *realPath = NULL;
507 if (realpath(filePath, absPath) == NULL) {
508 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "realpath failed, err[%s]", strerror(errno));
509 return NULL;
510 } else {
511 realPath = absPath;
512 }
513
514 if (strstr(realPath, "..") != NULL) {
515 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "real path is not canonical form");
516 return NULL;
517 }
518
519 int32_t pathLength = strlen(realPath);
520 if ((pathLength > (MAX_FILE_PATH_NAME_LEN - 1)) || (pathLength > PATH_MAX)) {
521 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "pathLength[%d] is too large", pathLength);
522 return NULL;
523 }
524
525 return realPath;
526 }
527
GetAndCheckFileSize(const char * sourceFile,uint64_t * fileSize)528 static int32_t GetAndCheckFileSize(const char *sourceFile, uint64_t *fileSize)
529 {
530 if ((sourceFile == NULL) || (fileSize == NULL)) {
531 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sourceFile or fileSize is null");
532 return SOFTBUS_FILE_ERR;
533 }
534 struct stat statbuff;
535 if (stat(sourceFile, &statbuff) < 0) {
536 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "stat file fail");
537 return SOFTBUS_FILE_ERR;
538 } else {
539 *fileSize = statbuff.st_size;
540 }
541
542 if (*fileSize > MAX_FILE_SIZE) {
543 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "file is too large, filesize : %llu", *fileSize);
544 return SOFTBUS_FILE_ERR;
545 }
546
547 return SOFTBUS_OK;
548 }
549
SendOneFrame(int32_t channelId,FileFrame fileFrame)550 static int32_t SendOneFrame(int32_t channelId, FileFrame fileFrame)
551 {
552 if (fileFrame.data == NULL) {
553 return SOFTBUS_ERR;
554 }
555 int32_t type = FrameTypeToSessionType(fileFrame.frameType);
556 if (type == SOFTBUS_ERR) {
557 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "Frame Type To Session Type fail %d", fileFrame.frameType);
558 return SOFTBUS_ERR;
559 }
560 int32_t ret = ProxyChannelSendFileStream(channelId, (char *)fileFrame.data, fileFrame.frameLength, type);
561 if (ret != SOFTBUS_OK) {
562 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "conn send buf fail %d", ret);
563 return ret;
564 }
565 return SOFTBUS_OK;
566 }
567
FileToFrame(SendListenerInfo sendInfo,uint64_t frameNum,int32_t fd,const char * destFile,uint64_t fileSize)568 static int32_t FileToFrame(SendListenerInfo sendInfo, uint64_t frameNum, int32_t fd,
569 const char *destFile, uint64_t fileSize)
570 {
571 FileFrame fileFrame;
572 uint8_t *buffer = (uint8_t *)SoftBusCalloc(PROXY_MAX_PACKET_SIZE);
573 if (buffer == NULL) {
574 return SOFTBUS_ERR;
575 }
576 uint64_t fileOffset = 0;
577 uint64_t remainedSendSize = fileSize;
578 uint64_t frameDataSize = PROXY_MAX_PACKET_SIZE - FRAME_DATA_SEQ_OFFSET;
579 for (uint64_t index = 0; index < frameNum; index++) {
580 fileFrame.frameType = FrameIndexToType(index, frameNum);
581 fileFrame.data = buffer;
582 if (memcpy_s(fileFrame.data, FRAME_DATA_SEQ_OFFSET, (char *)&sendInfo.channelId,
583 FRAME_DATA_SEQ_OFFSET) != EOK) {
584 goto EXIT_ERR;
585 }
586 if (index == 0) {
587 uint32_t dNameSize = strlen(destFile);
588 if (memcpy_s(fileFrame.data + FRAME_DATA_SEQ_OFFSET, dNameSize, destFile, dNameSize) != SOFTBUS_OK) {
589 goto EXIT_ERR;
590 }
591 fileFrame.frameLength = FRAME_DATA_SEQ_OFFSET + dNameSize;
592 } else {
593 uint64_t readLength = (remainedSendSize < frameDataSize) ? remainedSendSize : frameDataSize;
594 int32_t len = pread(fd, fileFrame.data + FRAME_DATA_SEQ_OFFSET, readLength, fileOffset);
595 if (len >= 0) {
596 fileOffset += readLength;
597 fileFrame.frameLength = readLength + FRAME_DATA_SEQ_OFFSET;
598 remainedSendSize -= readLength;
599 } else {
600 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "pread src file failed");
601 goto EXIT_ERR;
602 }
603 }
604
605 if (sendInfo.fileListener.sendListener.OnSendFileProcess != NULL) {
606 sendInfo.fileListener.sendListener.OnSendFileProcess(sendInfo.channelId, fileOffset, fileSize);
607 }
608 if (SendOneFrame(sendInfo.channelId, fileFrame) != SOFTBUS_OK) {
609 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "send one frame failed");
610 goto EXIT_ERR;
611 }
612 memset_s(fileFrame.data, PROXY_MAX_PACKET_SIZE, 0, PROXY_MAX_PACKET_SIZE);
613 SoftBusSleepMs(SEND_DELAY_TIME);
614 }
615 SoftBusFree(fileFrame.data);
616 return SOFTBUS_OK;
617 EXIT_ERR:
618 SoftBusFree(fileFrame.data);
619 return SOFTBUS_ERR;
620 }
621
622
CheckDestFilePathValid(const char * destFile)623 static bool CheckDestFilePathValid(const char *destFile)
624 {
625 if (destFile == NULL) {
626 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "destFile is null");
627 return false;
628 }
629 int32_t len = strlen(destFile);
630 if ((len == 0) || (destFile[0] == PATH_SEPARATOR)) {
631 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "destFile first char is '/'");
632 return false;
633 }
634
635 if (strstr(destFile, "..") != NULL) {
636 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "dest path is not canonical form");
637 return false;
638 }
639 return true;
640 }
641
FileToFrameAndSendFile(SendListenerInfo sendInfo,const char * sourceFile,const char * destFile)642 static int32_t FileToFrameAndSendFile(SendListenerInfo sendInfo, const char *sourceFile, const char *destFile)
643 {
644 uint64_t fileSize = 0;
645 char *absSrcPath = (char *)SoftBusCalloc(PATH_MAX + 1);
646 if (absSrcPath == NULL) {
647 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc absFullDir failed");
648 return SOFTBUS_ERR;
649 }
650 const char *realSrcPath = GetAndCheckRealPath(sourceFile, absSrcPath);
651 if (realSrcPath == NULL) {
652 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get src abs file failed");
653 goto EXIT_ERR;
654 }
655
656 if (CheckDestFilePathValid(destFile) == false) {
657 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "dest path's form is wrong");
658 goto EXIT_ERR;
659 }
660
661 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "srcPath:%s, srcAbsPath:%s, destPath:%s",
662 sourceFile, realSrcPath, destFile);
663
664 if (GetAndCheckFileSize(realSrcPath, &fileSize) != SOFTBUS_OK) {
665 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sourcefile size err");
666 goto EXIT_ERR;
667 }
668 int32_t fd = open(realSrcPath, O_RDONLY);
669 if (fd < 0) {
670 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "open file fail");
671 goto EXIT_ERR;
672 }
673 if (PROXY_MAX_PACKET_SIZE <= FRAME_DATA_SEQ_OFFSET) {
674 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "stat file fail");
675 goto EXIT_ERR;
676 }
677 uint64_t frameDataSize = PROXY_MAX_PACKET_SIZE - FRAME_DATA_SEQ_OFFSET;
678 uint64_t frameNum = fileSize / frameDataSize;
679 if ((fileSize % frameDataSize) != 0) {
680 frameNum++;
681 }
682
683 /* add 1 means reserve frame to send destFile string */
684 frameNum++;
685 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO,
686 "channelId:%d, fileName:%s, fileSize:%llu, frameNum:%llu, destPath:%s",
687 sendInfo.channelId, realSrcPath, fileSize, frameNum, destFile);
688 if (FileToFrame(sendInfo, frameNum, fd, destFile, fileSize) != SOFTBUS_OK) {
689 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "File To Frame fail");
690 goto EXIT_ERR;
691 }
692 SoftBusFree(absSrcPath);
693 return SOFTBUS_OK;
694 EXIT_ERR:
695 SoftBusFree(absSrcPath);
696 return SOFTBUS_ERR;
697 }
698
GetDestFilePath(FileFrame fileFrame)699 static char *GetDestFilePath(FileFrame fileFrame)
700 {
701 if (fileFrame.frameLength <= FRAME_DATA_SEQ_OFFSET) {
702 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "CreateFileFromFrame framelength less then offset");
703 return NULL;
704 }
705
706 uint32_t filePathSize = fileFrame.frameLength - FRAME_DATA_SEQ_OFFSET + 1;
707 if (filePathSize > MAX_FILE_PATH_NAME_LEN) {
708 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath is too long");
709 return NULL;
710 }
711 char *filePath = (char *)SoftBusCalloc(filePathSize);
712 if (filePath == NULL) {
713 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc filePath failed");
714 return NULL;
715 }
716 if (memcpy_s(filePath, filePathSize, fileFrame.data + FRAME_DATA_SEQ_OFFSET,
717 fileFrame.frameLength - FRAME_DATA_SEQ_OFFSET) != SOFTBUS_OK) {
718 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "memcpy_s failed");
719 SoftBusFree(filePath);
720 return NULL;
721 }
722
723 if (CheckDestFilePathValid(filePath) == false) {
724 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "recv file path[%s] form is wrong", filePath);
725 SoftBusFree(filePath);
726 return NULL;
727 }
728 return filePath;
729 }
730
GetDestFileFrameSeq(FileFrame fileFrame,uint32_t * seq)731 static int32_t GetDestFileFrameSeq(FileFrame fileFrame, uint32_t *seq)
732 {
733 if (seq == NULL) {
734 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "seq is null");
735 return SOFTBUS_ERR;
736 }
737 if (fileFrame.frameLength <= FRAME_DATA_SEQ_OFFSET) {
738 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "CreateFileFromFrame framelength less then offset");
739 return SOFTBUS_ERR;
740 }
741
742 if (memcpy_s(seq, FRAME_DATA_SEQ_OFFSET, fileFrame.data, FRAME_DATA_SEQ_OFFSET) != EOK) {
743 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "memcpy_s failed");
744 return SOFTBUS_ERR;
745 }
746
747 return SOFTBUS_OK;
748 }
749
IsPathValid(char * filePath)750 static bool IsPathValid(char *filePath)
751 {
752 if (filePath == NULL) {
753 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath is null");
754 return false;
755 }
756 if ((strlen(filePath) == 0) || (strlen(filePath) > (MAX_FILE_PATH_NAME_LEN - 1))) {
757 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath size[%d] is wrong", (int32_t)strlen(filePath));
758 return false;
759 }
760
761 if (filePath[strlen(filePath) - 1] == PATH_SEPARATOR) {
762 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath is end with '/' ");
763 return false;
764 }
765
766 return true;
767 }
768
GetDirPath(const char * fullPath,char * dirPath,int32_t dirPathLen)769 static int32_t GetDirPath(const char *fullPath, char *dirPath, int32_t dirPathLen)
770 {
771 if ((fullPath == NULL) || (strlen(fullPath) < 1) || (fullPath[strlen(fullPath) - 1] == PATH_SEPARATOR)) {
772 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "invalid input param");
773 return SOFTBUS_ERR;
774 }
775 int32_t i = 0;
776 int32_t dirFullLen = (int32_t)strlen(fullPath);
777 for (i = dirFullLen - 1; i >= 0; i--) {
778 if (fullPath[i] == PATH_SEPARATOR) {
779 i++;
780 break;
781 }
782 if (i == 0) {
783 break;
784 }
785 }
786 int32_t dirLen = i;
787 if (dirLen >= dirPathLen) {
788 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "dirLen[%d] >= dirPathLen[%d]", dirLen, dirPathLen);
789 return SOFTBUS_ERR;
790 }
791
792 if (strncpy_s(dirPath, dirPathLen, fullPath, dirLen) != EOK) {
793 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "strcpy_s dir path error, dirLen[%d]", dirLen);
794 return SOFTBUS_ERR;
795 }
796
797 return SOFTBUS_OK;
798 }
799
GetFileName(const char * fullPath,char * fileName,int32_t fileNameLen)800 static int32_t GetFileName(const char *fullPath, char *fileName, int32_t fileNameLen)
801 {
802 if ((fullPath == NULL) || (strlen(fullPath) < 1) || (fullPath[strlen(fullPath) - 1] == PATH_SEPARATOR)) {
803 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "invalid input param");
804 return SOFTBUS_ERR;
805 }
806 int32_t i;
807 int32_t dirFullLen = (int32_t)strlen(fullPath);
808 for (i = dirFullLen - 1; i >= 0; i--) {
809 if (fullPath[i] == PATH_SEPARATOR) {
810 i++;
811 break;
812 }
813 if (i == 0) {
814 break;
815 }
816 }
817
818 if (strcpy_s(fileName, fileNameLen, fullPath + i) != EOK) {
819 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "strcpy_s filename error, fileNameLen[%d]", fileNameLen);
820 return SOFTBUS_ERR;
821 }
822
823 return SOFTBUS_OK;
824 }
825
GetAbsFullPath(const char * fullPath,char * recvAbsPath,int32_t pathSize)826 static int32_t GetAbsFullPath(const char *fullPath, char *recvAbsPath, int32_t pathSize)
827 {
828 char dirPath[MAX_FILE_PATH_NAME_LEN] = { 0 };
829 char fileName[MAX_FILE_PATH_NAME_LEN] = { 0 };
830 if (GetDirPath(fullPath, dirPath, sizeof(dirPath)) != SOFTBUS_OK) {
831 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get dir path failed");
832 return SOFTBUS_ERR;
833 }
834 if (GetFileName(fullPath, fileName, sizeof(fileName)) != SOFTBUS_OK) {
835 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get file name failed");
836 return SOFTBUS_ERR;
837 }
838
839 char *absFullDir = (char *)SoftBusCalloc(PATH_MAX + 1);
840 if (absFullDir == NULL) {
841 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc absFullDir failed");
842 return SOFTBUS_ERR;
843 }
844 const char *realFullDir = GetAndCheckRealPath(dirPath, absFullDir);
845 if (realFullDir == NULL) {
846 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get full abs file failed");
847 SoftBusFree(absFullDir);
848 return SOFTBUS_ERR;
849 }
850
851 int32_t fileNameLength = strlen(fileName);
852 int32_t dirPathLength = strlen(realFullDir);
853 if (pathSize < (fileNameLength + dirPathLength + 1)) {
854 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "copy name is too large, dirLen:%d, fileNameLen:%d",
855 dirPathLength, fileNameLength);
856 SoftBusFree(absFullDir);
857 return SOFTBUS_ERR;
858 }
859 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "dirPath[%s]len[%d], fileName[%s][%d], realFullDir[%s]",
860 dirPath, dirPathLength, fileName, fileNameLength, realFullDir);
861
862 if (sprintf_s(recvAbsPath, pathSize, "%s/%s", realFullDir, fileName) == -1) {
863 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "memcpy filename error");
864 SoftBusFree(absFullDir);
865 return SOFTBUS_ERR;
866 }
867
868 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "recvAbsPath[%s]", recvAbsPath);
869 SoftBusFree(absFullDir);
870 return SOFTBUS_OK;
871 }
872
CreateDirAndGetAbsPath(const char * filePath,char * recvAbsPath,int32_t pathSize)873 static int32_t CreateDirAndGetAbsPath(const char *filePath, char *recvAbsPath, int32_t pathSize)
874 {
875 if ((filePath == NULL) || (recvAbsPath == NULL)) {
876 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "invalid input");
877 return SOFTBUS_ERR;
878 }
879 uint32_t len = (uint32_t)strlen(filePath);
880 int32_t ret;
881 char *tempPath = (char *)SoftBusCalloc(len + 1);
882 if (tempPath == NULL) {
883 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc tempPath failed");
884 return SOFTBUS_ERR;
885 }
886 for (uint32_t i = 0; i < len; i++) {
887 tempPath[i] = filePath[i];
888 if (tempPath[i] != PATH_SEPARATOR) {
889 continue;
890 }
891 if (access(tempPath, 0) == -1) {
892 ret = mkdir(tempPath, DEFAULT_NEW_PATH_AUTHORITY);
893 if (ret == -1 && errno != EEXIST) {
894 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "mkdir failed(%d)", errno);
895 SoftBusFree(tempPath);
896 return SOFTBUS_ERR;
897 }
898 }
899 }
900
901 SoftBusFree(tempPath);
902 if (GetAbsFullPath(filePath, recvAbsPath, pathSize) != SOFTBUS_OK) {
903 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "dest dir is invalid");
904 return SOFTBUS_ERR;
905 }
906 return SOFTBUS_OK;
907 }
908
GetFullRecvPath(const char * filePath,const char * recvRootDir)909 static char *GetFullRecvPath(const char *filePath, const char *recvRootDir)
910 {
911 if ((filePath == NULL) || (recvRootDir == NULL)) {
912 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "filePath is null or rootDir is null");
913 return NULL;
914 }
915
916 int32_t rootDirLength = strlen(recvRootDir);
917 int32_t filePathLength = strlen(filePath);
918 bool isNeedAddSep = true;
919 if (((filePathLength > 0) && (filePath[0] == PATH_SEPARATOR)) ||
920 ((rootDirLength > 0) && (recvRootDir[rootDirLength - 1] == PATH_SEPARATOR))) {
921 isNeedAddSep = false;
922 }
923
924 int32_t destFullPathLength = (isNeedAddSep) ? (rootDirLength + sizeof('/') + filePathLength) :
925 (rootDirLength + filePathLength);
926 char *recvFullPath = (char *)SoftBusCalloc(destFullPathLength + 1);
927 if (recvFullPath == NULL) {
928 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "recvFullPath is null");
929 return NULL;
930 }
931
932 int32_t ret;
933 if (isNeedAddSep) {
934 ret = sprintf_s(recvFullPath, destFullPathLength + 1, "%s%c%s", recvRootDir, PATH_SEPARATOR, filePath);
935 } else {
936 ret = sprintf_s(recvFullPath, destFullPathLength + 1, "%s%s", recvRootDir, filePath);
937 }
938 if (ret == -1) {
939 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "create fullPath fail");
940 SoftBusFree(recvFullPath);
941 return NULL;
942 }
943 return recvFullPath;
944 }
945
GetFileAbsPathAndSeq(FileFrame fileFrame,const char * rootDir,uint32_t * seq)946 static char *GetFileAbsPathAndSeq(FileFrame fileFrame, const char *rootDir, uint32_t *seq)
947 {
948 if (seq == NULL) {
949 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "seq is null");
950 return NULL;
951 }
952
953 if (GetDestFileFrameSeq(fileFrame, seq) != SOFTBUS_OK) {
954 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "open destFile fail");
955 return NULL;
956 }
957
958 char *destFilePath = GetDestFilePath(fileFrame);
959 if (destFilePath == NULL) {
960 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "GetDestFilePath failed");
961 return NULL;
962 }
963
964 if (strstr(rootDir, "..") != NULL) {
965 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "rootDir[%s] is not cannoical form", rootDir);
966 SoftBusFree(destFilePath);
967 return NULL;
968 }
969
970 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "destFilePath[%s], rootDir[%s]", destFilePath, rootDir);
971
972 char *fullRecvPath = GetFullRecvPath(destFilePath, rootDir);
973 if (IsPathValid(fullRecvPath) == false) {
974 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "destFilePath is invalid");
975 SoftBusFree(destFilePath);
976 SoftBusFree(fullRecvPath);
977 return NULL;
978 }
979
980 SoftBusFree(destFilePath);
981 int32_t pathSize = strlen(fullRecvPath) + 1;
982 char *absFullPath = (char *)SoftBusCalloc(pathSize);
983 if (absFullPath == NULL) {
984 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "absFullPath is null");
985 SoftBusFree(fullRecvPath);
986 return NULL;
987 }
988 if (CreateDirAndGetAbsPath(fullRecvPath, absFullPath, pathSize) != SOFTBUS_OK) {
989 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "create dest dir failed");
990 SoftBusFree(fullRecvPath);
991 SoftBusFree(absFullPath);
992 return NULL;
993 }
994 SoftBusFree(fullRecvPath);
995 return absFullPath;
996 }
997
CreateFileFromFrame(int32_t sessionId,FileFrame fileFrame,FileListener fileListener)998 static int32_t CreateFileFromFrame(int32_t sessionId, FileFrame fileFrame, FileListener fileListener)
999 {
1000 if (SoftBusMutexLock(&g_recvFileInfo.lock) != SOFTBUS_OK) {
1001 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock fileFromFrame fail");
1002 return SOFTBUS_ERR;
1003 }
1004 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "create file from frame start");
1005 uint32_t seq = 0;
1006
1007 char *fullRecvPath = GetFileAbsPathAndSeq(fileFrame, fileListener.rootDir, &seq);
1008 if (fullRecvPath == NULL) {
1009 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fullRecvPath is null");
1010 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1011 return SOFTBUS_ERR;
1012 }
1013
1014 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "fullRecvPath %s, seq:%u", fullRecvPath, seq);
1015 if (CheckRecvFileExist(fullRecvPath) == true) {
1016 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "file is already exist and busy");
1017 goto EXIT_ERR;
1018 }
1019
1020 int32_t fd = open(fullRecvPath, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
1021 if (fd < 0) {
1022 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "open destFile fail");
1023 goto EXIT_ERR;
1024 }
1025
1026 if (PutToRecvList(fd, seq, fullRecvPath, fileListener, sessionId) != SOFTBUS_OK) {
1027 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "put seq[%u] failed", seq);
1028 close(fd);
1029 remove(fullRecvPath);
1030 if (RemoveFromRecvListBySeq(seq) != SOFTBUS_OK) {
1031 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "remove from list failed");
1032 }
1033 goto EXIT_ERR;
1034 }
1035
1036 if (fileListener.recvListener.OnReceiveFileStarted != NULL) {
1037 fileListener.recvListener.OnReceiveFileStarted(sessionId, fullRecvPath, 1);
1038 }
1039 SoftBusFree(fullRecvPath);
1040 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1041 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "create file from frame success");
1042 return SOFTBUS_OK;
1043 EXIT_ERR:
1044 SoftBusFree(fullRecvPath);
1045 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1046 return SOFTBUS_ERR;
1047 }
1048
ProcessOneFrame(FileFrame fileFrame,SingleFileInfo fileInfo,int32_t seq)1049 static int32_t ProcessOneFrame(FileFrame fileFrame, SingleFileInfo fileInfo, int32_t seq)
1050 {
1051 uint32_t frameLength = fileFrame.frameLength;
1052 if (fileFrame.frameLength <= FRAME_DATA_SEQ_OFFSET) {
1053 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "WriteFrameToFile framelength less then offset");
1054 return SOFTBUS_ERR;
1055 }
1056
1057 uint32_t frameDataLength = frameLength - FRAME_DATA_SEQ_OFFSET;
1058 int32_t writeLength = pwrite(fileInfo.fileFd, fileFrame.data + FRAME_DATA_SEQ_OFFSET, frameDataLength,
1059 (uint64_t)fileInfo.fileOffset);
1060 if (writeLength < 0) {
1061 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "pwrite file failed");
1062 return SOFTBUS_ERR;
1063 }
1064 fileInfo.fileOffset += (uint64_t)writeLength;
1065
1066 if (fileInfo.fileOffset > MAX_FILE_SIZE) {
1067 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "file is too large, offset:%llu", fileInfo.fileOffset);
1068 return SOFTBUS_ERR;
1069 }
1070 if (UpdateRecvInfo(fileInfo) != SOFTBUS_OK) {
1071 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "UpdateRecvInfo fail");
1072 return SOFTBUS_ERR;
1073 }
1074 int32_t frameType = fileFrame.frameType;
1075
1076 /* last frame */
1077 if ((frameType == FILE_LAST_FRAME) || (frameType == FILE_ONLYONE_FRAME)) {
1078 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "process last frame, seq:%d", seq);
1079 close(fileInfo.fileFd);
1080 if (RemoveFromRecvListBySeq(seq) != SOFTBUS_OK) {
1081 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ClearRecvFileInfoBySeq fail");
1082 remove(fileInfo.filePath);
1083 return SOFTBUS_ERR;
1084 }
1085 }
1086 return SOFTBUS_OK;
1087 }
1088
WriteFrameToFile(FileFrame fileFrame)1089 static int32_t WriteFrameToFile(FileFrame fileFrame)
1090 {
1091 if (SoftBusMutexLock(&g_recvFileInfo.lock) != SOFTBUS_OK) {
1092 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock write frame fail");
1093 return SOFTBUS_ERR;
1094 }
1095 uint32_t seq = 0;
1096 SingleFileInfo fileInfo = {0};
1097 if (GetDestFileFrameSeq(fileFrame, &seq) != SOFTBUS_OK) {
1098 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get dest file frame failed");
1099 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1100 return SOFTBUS_ERR;
1101 }
1102
1103 if (GetRecvFileInfoBySeq(seq, &fileInfo) != SOFTBUS_OK) {
1104 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "GetFileFdBySeq fail");
1105 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1106 return SOFTBUS_ERR;
1107 }
1108
1109 if (fileInfo.fileStatus == NODE_ERR) {
1110 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fileStatus is error");
1111 goto EXIT_ERR;
1112 }
1113 if (ProcessOneFrame(fileFrame, fileInfo, seq) != SOFTBUS_OK) {
1114 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "write one frame error");
1115 goto EXIT_ERR;
1116 }
1117 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1118 return SOFTBUS_OK;
1119 EXIT_ERR:
1120 close(fileInfo.fileFd);
1121 remove(fileInfo.filePath);
1122 if (RemoveFromRecvListBySeq(seq) != SOFTBUS_OK) {
1123 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "WriteFrameToFile remove fail");
1124 }
1125 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1126 return SOFTBUS_ERR;
1127 }
1128
ProcessFileFrameData(int32_t sessionId,FileListener fileListener,const char * data,uint32_t len,int32_t type)1129 int32_t ProcessFileFrameData(int32_t sessionId, FileListener fileListener, const char *data, uint32_t len,
1130 int32_t type)
1131 {
1132 int32_t ret;
1133 FileFrame oneFrame;
1134 oneFrame.frameType = type;
1135 oneFrame.frameLength = len;
1136 oneFrame.data = (uint8_t *)data;
1137 switch (oneFrame.frameType) {
1138 case FILE_FIRST_FRAME:
1139 ret = CreateFileFromFrame(sessionId, oneFrame, fileListener);
1140 if (ret != SOFTBUS_OK) {
1141 if (fileListener.recvListener.OnFileTransError != NULL) {
1142 fileListener.recvListener.OnFileTransError(sessionId);
1143 }
1144 }
1145 break;
1146 case FILE_ONGOINE_FRAME:
1147 case FILE_ONLYONE_FRAME:
1148 case FILE_LAST_FRAME:
1149 ret = WriteFrameToFile(oneFrame);
1150 if (ret != SOFTBUS_OK) {
1151 if (fileListener.recvListener.OnFileTransError != NULL) {
1152 fileListener.recvListener.OnFileTransError(sessionId);
1153 }
1154 }
1155 break;
1156 default:
1157 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "frame type is invalid");
1158 return SOFTBUS_ERR;
1159 }
1160 return ret;
1161 }
1162
FileListToBuffer(const char ** destFile,uint32_t fileCnt,FileListBuffer * outbufferInfo)1163 static int32_t FileListToBuffer(const char **destFile, uint32_t fileCnt, FileListBuffer *outbufferInfo)
1164 {
1165 if (outbufferInfo == NULL) {
1166 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "outbufferInfo is NULL");
1167 return SOFTBUS_ERR;
1168 }
1169 outbufferInfo->buffer = NULL;
1170 outbufferInfo->bufferSize = 0;
1171 uint32_t totalLength = 0;
1172 uint32_t offset = 0;
1173 uint32_t index;
1174 for (index = 0; index < fileCnt; index++) {
1175 totalLength += strlen(destFile[index]);
1176 }
1177
1178 uint32_t fileNameSize = 0;
1179 uint32_t indexSize = sizeof(index);
1180 uint32_t bufferSize = totalLength + (indexSize + sizeof(fileNameSize)) * fileCnt;
1181 uint8_t *buffer = (uint8_t *)SoftBusCalloc(bufferSize);
1182 if (buffer == NULL) {
1183 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc filelist failed");
1184 return SOFTBUS_ERR;
1185 }
1186
1187 char byteBuff[sizeof(int32_t)] = {0};
1188 for (index = 0; index < fileCnt; index++) {
1189 if (IntToByte(index, byteBuff, indexSize) == false) {
1190 goto EXIT;
1191 }
1192 if (memcpy_s(buffer + offset, indexSize, byteBuff, indexSize) != EOK) {
1193 goto EXIT;
1194 }
1195 offset += indexSize;
1196 fileNameSize = strlen(destFile[index]);
1197 if (IntToByte(fileNameSize, byteBuff, indexSize) == false) {
1198 goto EXIT;
1199 }
1200 if (memcpy_s(buffer + offset, sizeof(fileNameSize), byteBuff, sizeof(fileNameSize)) != EOK) {
1201 goto EXIT;
1202 }
1203 offset += sizeof(fileNameSize);
1204 if (memcpy_s(buffer + offset, fileNameSize, destFile[index], fileNameSize) != EOK) {
1205 goto EXIT;
1206 }
1207 offset += fileNameSize;
1208 }
1209
1210 outbufferInfo->buffer = buffer;
1211 outbufferInfo->bufferSize = offset;
1212 return SOFTBUS_OK;
1213 EXIT:
1214 SoftBusFree(buffer);
1215 return SOFTBUS_ERR;
1216 }
1217
BufferToFileList(FileListBuffer bufferInfo,char * firstFile,int32_t * fileCount)1218 static int32_t BufferToFileList(FileListBuffer bufferInfo, char *firstFile, int32_t *fileCount)
1219 {
1220 if ((bufferInfo.buffer == NULL) || (firstFile == NULL) || (fileCount == NULL)) {
1221 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "BufferToFileList input invalid");
1222 return SOFTBUS_ERR;
1223 }
1224 *fileCount = 0;
1225 uint8_t *buffer = bufferInfo.buffer;
1226 uint32_t offset = 0;
1227 int32_t count = 0;
1228 uint32_t fileNameLength = 0;
1229 uint32_t byteLen = sizeof(uint32_t);
1230 char byteBuff[sizeof(int32_t)] = {0};
1231 while (offset < bufferInfo.bufferSize) {
1232 offset += sizeof(uint32_t);
1233
1234 if (memcpy_s(byteBuff, sizeof(byteBuff), buffer + offset, byteLen) != EOK) {
1235 return SOFTBUS_ERR;
1236 }
1237 if (ByteToInt(byteBuff, byteLen, &fileNameLength) == false) {
1238 return SOFTBUS_ERR;
1239 }
1240 offset += byteLen;
1241 if (fileNameLength > bufferInfo.bufferSize - offset) {
1242 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "BufferToFileList invalid fileLength");
1243 return SOFTBUS_ERR;
1244 }
1245 /* only output first file path */
1246 if (count == 0) {
1247 if (memcpy_s(firstFile, fileNameLength, buffer + offset, fileNameLength) != EOK) {
1248 return SOFTBUS_ERR;
1249 }
1250 }
1251 offset += fileNameLength;
1252 count++;
1253 }
1254
1255 *fileCount = count;
1256 return SOFTBUS_OK;
1257 }
1258
ProcessFileListData(int32_t sessionId,FileListener fileListener,const char * data,uint32_t len)1259 int32_t ProcessFileListData(int32_t sessionId, FileListener fileListener, const char *data, uint32_t len)
1260 {
1261 if (SoftBusMutexLock(&g_recvFileInfo.lock) != SOFTBUS_OK) {
1262 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock filelist data fail");
1263 return SOFTBUS_ERR;
1264 }
1265
1266 FileListBuffer bufferInfo;
1267 char firstFilePath[MAX_FILE_PATH_NAME_LEN] = {0};
1268 int32_t fileCount = 0;
1269 bufferInfo.buffer = (uint8_t *)data;
1270 bufferInfo.bufferSize = len;
1271 int32_t ret = BufferToFileList(bufferInfo, firstFilePath, &fileCount);
1272 if (ret != SOFTBUS_OK) {
1273 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "Buffer To File List failed");
1274 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1275 return SOFTBUS_ERR;
1276 }
1277 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "rootDir:%s, firstFilePath:%s", fileListener.rootDir, firstFilePath);
1278 char *fullRecvPath = GetFullRecvPath(firstFilePath, fileListener.rootDir);
1279 if (IsPathValid(fullRecvPath) == false) {
1280 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fullRecvPath is invalid");
1281 SoftBusFree(fullRecvPath);
1282 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1283 return SOFTBUS_ERR;
1284 }
1285
1286 char *absRecvPath = (char *)SoftBusCalloc(PATH_MAX + 1);
1287 if (absRecvPath == NULL) {
1288 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "calloc absFullDir failed");
1289 SoftBusFree(fullRecvPath);
1290 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1291 return SOFTBUS_ERR;
1292 }
1293 const char *realRecvPath = GetAndCheckRealPath(fullRecvPath, absRecvPath);
1294 if (realRecvPath == NULL) {
1295 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get recv abs file path failed");
1296 SoftBusFree(fullRecvPath);
1297 SoftBusFree(absRecvPath);
1298 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1299 return SOFTBUS_ERR;
1300 }
1301 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "fullRecvPath:%s", realRecvPath);
1302
1303 if (fileListener.recvListener.OnReceiveFileFinished != NULL) {
1304 fileListener.recvListener.OnReceiveFileFinished(sessionId, realRecvPath, fileCount);
1305 }
1306
1307 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "Process File List Data success!!!");
1308 SoftBusFree(fullRecvPath);
1309 SoftBusFree(absRecvPath);
1310 SoftBusMutexUnlock(&g_recvFileInfo.lock);
1311 return SOFTBUS_OK;
1312 }
1313
SendFileList(int32_t channelId,const char ** destFile,uint32_t fileCnt)1314 static int32_t SendFileList(int32_t channelId, const char **destFile, uint32_t fileCnt)
1315 {
1316 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "SendFileList begin");
1317 FileListBuffer bufferInfo;
1318 int32_t ret = FileListToBuffer(destFile, fileCnt, &bufferInfo);
1319 if (ret != SOFTBUS_OK) {
1320 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "FileListToBuffer failed");
1321 SoftBusFree(bufferInfo.buffer);
1322 return SOFTBUS_ERR;
1323 }
1324
1325 /* send file list */
1326 int32_t type = TRANS_SESSION_FILE_ALLFILE_SENT;
1327 ret = ProxyChannelSendFileStream(channelId, (char *)bufferInfo.buffer, bufferInfo.bufferSize, type);
1328 if (ret < 0) {
1329 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "conn send buf fail %d", ret);
1330 SoftBusFree(bufferInfo.buffer);
1331 return ret;
1332 }
1333
1334 SoftBusFree(bufferInfo.buffer);
1335 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "SendFileList success");
1336
1337 return SOFTBUS_OK;
1338 }
1339
SendSingleFile(SendListenerInfo sendInfo,const char * sourceFile,const char * destFile)1340 static int32_t SendSingleFile(SendListenerInfo sendInfo, const char *sourceFile, const char *destFile)
1341 {
1342 if ((sourceFile == NULL) || (destFile == NULL)) {
1343 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sourfile or dstfile is null");
1344 return SOFTBUS_ERR;
1345 }
1346 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send file[%s] begin, dest is :%s", sourceFile, destFile);
1347
1348 int32_t ret;
1349 ret = FileToFrameAndSendFile(sendInfo, sourceFile, destFile);
1350 if (ret != SOFTBUS_OK) {
1351 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "FileToFrameAndSendFile failed");
1352 return SOFTBUS_ERR;
1353 }
1354
1355 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "send file[%s] success", sourceFile);
1356
1357 return SOFTBUS_OK;
1358 }
1359
ProxySendFile(SendListenerInfo sendInfo,const char * sFileList[],const char * dFileList[],uint32_t fileCnt)1360 static int32_t ProxySendFile(SendListenerInfo sendInfo, const char *sFileList[], const char *dFileList[],
1361 uint32_t fileCnt)
1362 {
1363 int32_t ret;
1364 if ((fileCnt == 0) || (fileCnt > MAX_FILE_NUM)) {
1365 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sendfile arg filecnt[%d] error", fileCnt);
1366 return SOFTBUS_ERR;
1367 }
1368
1369 if (!IsValidFileString(sFileList, fileCnt, MAX_FILE_PATH_NAME_LEN) ||
1370 !IsValidFileString(dFileList, fileCnt, MAX_FILE_PATH_NAME_LEN)) {
1371 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "sendfile invalid arg input");
1372 return SOFTBUS_ERR;
1373 }
1374
1375 for (uint32_t index = 0; index < fileCnt; index++) {
1376 ret = SendSingleFile(sendInfo, sFileList[index], dFileList[index]);
1377 if (ret != SOFTBUS_OK) {
1378 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "send file %s, failed", sFileList[index]);
1379 return SOFTBUS_ERR;
1380 }
1381 }
1382
1383 ret = SendFileList(sendInfo.channelId, dFileList, fileCnt);
1384 if (ret != SOFTBUS_OK) {
1385 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "SendFileList failed");
1386 return SOFTBUS_ERR;
1387 }
1388
1389 if (sendInfo.fileListener.sendListener.OnSendFileFinished != NULL) {
1390 sendInfo.fileListener.sendListener.OnSendFileFinished(sendInfo.sessionId, dFileList[0]);
1391 }
1392 return SOFTBUS_OK;
1393 }
1394
TransProxyChannelSendFile(int32_t channelId,const char * sFileList[],const char * dFileList[],uint32_t fileCnt)1395 int32_t TransProxyChannelSendFile(int32_t channelId, const char *sFileList[], const char *dFileList[],
1396 uint32_t fileCnt)
1397 {
1398 if (SoftBusMutexLock(&g_sendFileInfo.lock) != 0) {
1399 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock mutex failed");
1400 return SOFTBUS_ERR;
1401 }
1402 SendListenerInfo sendInfo;
1403 memset_s(&sendInfo, sizeof(sendInfo), 0, sizeof(sendInfo));
1404 int32_t sessionId;
1405 int32_t ret = ClientGetSessionIdByChannelId(channelId, CHANNEL_TYPE_PROXY, &sessionId);
1406 if (ret != SOFTBUS_OK) {
1407 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get sessionId failed, channelId [%d]", channelId);
1408 goto EXIT_ERR;
1409 }
1410
1411 char sessionName[SESSION_NAME_SIZE_MAX] = { 0 };
1412 if (ClientGetSessionDataById(sessionId, sessionName, SESSION_NAME_SIZE_MAX, KEY_SESSION_NAME)
1413 != SOFTBUS_OK) {
1414 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get sessionId name failed");
1415 goto EXIT_ERR;
1416 }
1417
1418 sendInfo.channelId = channelId;
1419 sendInfo.sessionId = sessionId;
1420 if (TransGetFileListener(sessionName, &sendInfo.fileListener) != SOFTBUS_OK) {
1421 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get file listener failed");
1422 goto EXIT_ERR;
1423 }
1424 if (ProxySendFile(sendInfo, sFileList, dFileList, fileCnt) != SOFTBUS_OK) {
1425 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "proxy send file failed");
1426 goto EXIT_ERR;
1427 }
1428 SoftBusMutexUnlock(&g_sendFileInfo.lock);
1429 return SOFTBUS_OK;
1430 EXIT_ERR:
1431 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "send file trans error failed");
1432 if (sendInfo.fileListener.sendListener.OnFileTransError != NULL) {
1433 sendInfo.fileListener.sendListener.OnFileTransError(sendInfo.sessionId);
1434 }
1435 SoftBusMutexUnlock(&g_sendFileInfo.lock);
1436 return SOFTBUS_ERR;
1437 }
1438