• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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_file.h"
17 
18 #include <securec.h>
19 #include "client_trans_file_listener.h"
20 #include "client_trans_statistics.h"
21 #include "file_adapter.h"
22 #include "nstackx_dfile.h"
23 #include "softbus_adapter_mem.h"
24 #include "softbus_adapter_thread.h"
25 #include "softbus_def.h"
26 #include "softbus_error_code.h"
27 #include "trans_log.h"
28 #include "client_trans_session_manager.h"
29 
30 #define DEFAULT_KEY_LENGTH 32
31 
32 static const UdpChannelMgrCb *g_udpChannelMgrCb = NULL;
33 
NotifySendResult(int32_t sessionId,DFileMsgType msgType,const DFileMsg * msgData,FileListener * listener)34 static void NotifySendResult(int32_t sessionId, DFileMsgType msgType,
35     const DFileMsg *msgData, FileListener *listener)
36 {
37     if (msgData == NULL || listener == NULL) {
38         return;
39     }
40 
41     switch (msgType) {
42         case DFILE_ON_FILE_SEND_SUCCESS:
43             if (listener->sendListener.OnSendFileFinished != NULL &&
44                 msgData->fileList.files != NULL && msgData->fileList.fileNum > 0) {
45                 listener->sendListener.OnSendFileFinished(sessionId, msgData->fileList.files[0]);
46             }
47             break;
48         case DFILE_ON_FILE_SEND_FAIL:
49             if (listener->sendListener.OnFileTransError != NULL) {
50                 listener->sendListener.OnFileTransError(sessionId);
51             }
52             break;
53         case DFILE_ON_TRANS_IN_PROGRESS:
54             if (listener->sendListener.OnSendFileProcess != NULL) {
55                 uint64_t bytesUpload = msgData->transferUpdate.bytesTransferred;
56                 uint64_t bytesTotal = msgData->transferUpdate.totalBytes;
57                 listener->sendListener.OnSendFileProcess(sessionId, bytesUpload, bytesTotal);
58             }
59             break;
60         default:
61             break;
62     }
63 }
64 
FillFileStatusList(const DFileMsg * msgData,FileEvent * event)65 static void FillFileStatusList(const DFileMsg *msgData, FileEvent *event)
66 {
67     if (msgData == NULL || event == NULL) {
68         TRANS_LOGI(TRANS_SDK, "invalid param.");
69         return;
70     }
71     int32_t fileNum = msgData->clearPolicyFileList.fileNum;
72     if (fileNum <= 0) {
73         TRANS_LOGI(TRANS_SDK, "invalid fileNum.");
74         return;
75     }
76 
77     event->statusList.completedList.files = (char **)SoftBusCalloc(fileNum * sizeof(char *));
78     if (event->statusList.completedList.files == NULL) {
79         TRANS_LOGE(TRANS_SDK, "mem malloc failed");
80         return;
81     }
82     event->statusList.notCompletedList.files = (char **)SoftBusCalloc(fileNum * sizeof(char *));
83     if (event->statusList.notCompletedList.files == NULL) {
84         TRANS_LOGE(TRANS_SDK, "mem malloc failed");
85         SoftBusFree(event->statusList.completedList.files);
86         return;
87     }
88     event->statusList.notStartedList.files = (char **)SoftBusCalloc(fileNum * sizeof(char *));
89     if (event->statusList.notStartedList.files == NULL) {
90         TRANS_LOGE(TRANS_SDK, "mem malloc failed");
91         SoftBusFree(event->statusList.completedList.files);
92         SoftBusFree(event->statusList.notCompletedList.files);
93         return;
94     }
95     int32_t completedIndex = 0;
96     int32_t notCompletedIndex = 0;
97     int32_t notStartedIndex = 0;
98     for (int32_t i = 0; i < fileNum; i++) {
99         if (msgData->clearPolicyFileList.fileInfo[i].stat == FILE_STAT_COMPLETE) {
100             event->statusList.completedList.files[completedIndex] = msgData->clearPolicyFileList.fileInfo[i].file;
101             completedIndex++;
102         } else if (msgData->clearPolicyFileList.fileInfo[i].stat == FILE_STAT_NOT_COMPLETE) {
103             event->statusList.notCompletedList.files[notCompletedIndex] = msgData->clearPolicyFileList.fileInfo[i].file;
104             notCompletedIndex++;
105         } else if (msgData->clearPolicyFileList.fileInfo[i].stat == FILE_STAT_NOT_START) {
106             event->statusList.notStartedList.files[notStartedIndex] = msgData->clearPolicyFileList.fileInfo[i].file;
107             notStartedIndex++;
108         }
109     }
110     event->statusList.completedList.fileCnt = (uint32_t)completedIndex;
111     event->statusList.notCompletedList.fileCnt = (uint32_t)notCompletedIndex;
112     event->statusList.notStartedList.fileCnt = (uint32_t)notStartedIndex;
113     TRANS_LOGI(TRANS_SDK,
114         "status list totalFileNum=%{public}d, completedNum=%{public}u, notCompletedNum=%{public}u, "
115         "notStartedNum=%{public}u",
116         fileNum, event->statusList.completedList.fileCnt, event->statusList.notCompletedList.fileCnt,
117         event->statusList.notStartedList.fileCnt);
118 }
119 
FreeFileStatusList(FileEvent * event)120 static void FreeFileStatusList(FileEvent *event)
121 {
122     if (event == NULL) {
123         return;
124     }
125     if (event->statusList.completedList.files != NULL) {
126         SoftBusFree(event->statusList.completedList.files);
127         event->statusList.completedList.files = NULL;
128     }
129     if (event->statusList.notCompletedList.files != NULL) {
130         SoftBusFree(event->statusList.notCompletedList.files);
131         event->statusList.notCompletedList.files = NULL;
132     }
133     if (event->statusList.notStartedList.files != NULL) {
134         SoftBusFree(event->statusList.notStartedList.files);
135         event->statusList.notStartedList.files = NULL;
136     }
137 }
138 
FillFileEventErrorCode(const DFileMsg * msgData,FileEvent * event)139 static void FillFileEventErrorCode(const DFileMsg *msgData, FileEvent *event)
140 {
141     switch (msgData->errorCode) {
142         case NSTACKX_EOK:
143             event->errorCode = SOFTBUS_OK;
144             break;
145         case NSTACKX_EPERM:
146             event->errorCode = SOFTBUS_TRANS_FILE_PERMISSION_DENIED;
147             break;
148         case NSTACKX_EDQUOT:
149             event->errorCode = SOFTBUS_TRANS_FILE_DISK_QUOTA_EXCEEDED;
150             break;
151         case NSTACKX_ENOMEM:
152             event->errorCode = SOFTBUS_TRANS_FILE_NO_MEMORY;
153             break;
154         case NSTACKX_ENETDOWN:
155             event->errorCode = SOFTBUS_TRANS_FILE_NETWORK_ERROR;
156             break;
157         case NSTACKX_ENOENT:
158             event->errorCode = SOFTBUS_TRANS_FILE_NOT_FOUND;
159             break;
160         case NSTACKX_EEXIST:
161             event->errorCode = SOFTBUS_TRANS_FILE_EXISTED;
162             break;
163         default:
164             event->errorCode = msgData->errorCode;
165             break;
166     }
167 }
168 
NotifySocketSendResult(int32_t socket,DFileMsgType msgType,const DFileMsg * msgData,const FileListener * listener)169 static void NotifySocketSendResult(
170     int32_t socket, DFileMsgType msgType, const DFileMsg *msgData, const FileListener *listener)
171 {
172     if (msgData == NULL || listener == NULL || listener->socketSendCallback == NULL) {
173         TRANS_LOGE(TRANS_SDK, "param invalid");
174         return;
175     }
176     FileEvent event;
177     (void)memset_s(&event, sizeof(FileEvent), 0, sizeof(FileEvent));
178     switch (msgType) {
179         case DFILE_ON_TRANS_IN_PROGRESS:
180             event.type = FILE_EVENT_SEND_PROCESS;
181             break;
182         case DFILE_ON_FILE_SEND_SUCCESS:
183             event.type = FILE_EVENT_SEND_FINISH;
184             break;
185         case DFILE_ON_FILE_SEND_FAIL:
186             event.type = FILE_EVENT_SEND_ERROR;
187             break;
188         case DFILE_ON_CLEAR_POLICY_FILE_LIST:
189             event.type = FILE_EVENT_TRANS_STATUS;
190             break;
191         default:
192             return;
193     }
194     TRANS_LOGD(TRANS_SDK, "sendNotify socket=%{public}d type=%{public}d", socket, event.type);
195     event.files = msgData->fileList.files;
196     event.fileCnt = msgData->fileList.fileNum;
197     event.bytesProcessed = msgData->transferUpdate.bytesTransferred;
198     event.bytesTotal = msgData->transferUpdate.totalBytes;
199     event.UpdateRecvPath = NULL;
200     if (event.type == FILE_EVENT_TRANS_STATUS || event.type == FILE_EVENT_SEND_ERROR) {
201         FillFileStatusList(msgData, &event);
202     } else if (event.type == FILE_EVENT_SEND_PROCESS) {
203         event.rate = msgData->rate;
204     }
205     FillFileEventErrorCode(msgData, &event);
206     listener->socketSendCallback(socket, &event);
207     UpdateChannelStatistics(socket, (int64_t)msgData->transferUpdate.totalBytes);
208     FreeFileStatusList(&event);
209 }
210 
IsParmasValid(DFileMsgType msgType,const DFileMsg * msgData)211 static bool IsParmasValid(DFileMsgType msgType, const DFileMsg *msgData)
212 {
213     if (msgData == NULL || msgType == DFILE_ON_BIND || msgType == DFILE_ON_SESSION_IN_PROGRESS ||
214         msgType == DFILE_ON_SESSION_TRANSFER_RATE) {
215         TRANS_LOGE(TRANS_SDK, "param invalid");
216         return false;
217     }
218     return true;
219 }
220 
FileSendErrorEvent(UdpChannel * udpChannel,FileListener * fileListener,const DFileMsg * msgData,DFileMsgType msgType,int32_t sessionId)221 static void FileSendErrorEvent(UdpChannel *udpChannel, FileListener *fileListener, const DFileMsg *msgData,
222     DFileMsgType msgType, int32_t sessionId)
223 {
224     if (fileListener->socketSendCallback != NULL) {
225         FileEvent event;
226         (void)memset_s(&event, sizeof(FileEvent), 0, sizeof(FileEvent));
227         event.type = FILE_EVENT_SEND_ERROR;
228         FillFileStatusList(msgData, &event);
229         FillFileEventErrorCode(msgData, &event);
230         fileListener->socketSendCallback(sessionId, &event);
231         FreeFileStatusList(&event);
232     } else if (fileListener->sendListener.OnFileTransError != NULL) {
233         fileListener->sendListener.OnFileTransError(sessionId);
234     }
235     TRANS_LOGI(TRANS_SDK, "OnFile error. msgType=%{public}d", msgType);
236     TransOnUdpChannelClosed(udpChannel->channelId, SHUTDOWN_REASON_SEND_FILE_ERR);
237     return;
238 }
239 
FileSendListener(int32_t dfileId,DFileMsgType msgType,const DFileMsg * msgData)240 static void FileSendListener(int32_t dfileId, DFileMsgType msgType, const DFileMsg *msgData)
241 {
242     if (!IsParmasValid(msgType, msgData)) {
243         TRANS_LOGE(TRANS_SDK, "Invalid parameter, dfileId=%{public}d, type=%{public}d", dfileId, msgType);
244         return;
245     }
246     UdpChannel udpChannel;
247     (void)memset_s(&udpChannel, sizeof(UdpChannel), 0, sizeof(UdpChannel));
248     if (TransGetUdpChannelByFileId(dfileId, &udpChannel) != SOFTBUS_OK) {
249         TRANS_LOGE(TRANS_SDK, "trans get udp channel failed, dfileId=%{public}d, type=%{public}d", dfileId, msgType);
250         return;
251     }
252     if (msgType == DFILE_ON_CONNECT_SUCCESS) {
253         SocketAccessInfo accessInfo = { 0 };
254         g_udpChannelMgrCb->OnUdpChannelOpened(udpChannel.channelId, &accessInfo);
255         TRANS_LOGE(TRANS_SDK, "msgType failed, dfileId=%{public}d, type=%{public}d", dfileId, msgType);
256         return;
257     }
258 
259     FileListener fileListener;
260     (void)memset_s(&fileListener, sizeof(FileListener), 0, sizeof(FileListener));
261     if (TransGetFileListener(udpChannel.info.mySessionName, &fileListener) != SOFTBUS_OK) {
262         TRANS_LOGE(TRANS_SDK, "TransGetFileListener failed, dfileId=%{public}d, type=%{public}d", dfileId, msgType);
263         return;
264     }
265     if (msgType == DFILE_ON_CLEAR_POLICY_FILE_LIST) {
266         if (fileListener.socketSendCallback != NULL) {
267             NotifySocketSendResult(udpChannel.sessionId, msgType, msgData, &fileListener);
268         }
269         TRANS_LOGI(TRANS_SDK, "notify DFILE_ON_CLEAR_POLICY_FILE_LIST success.");
270         return;
271     }
272 
273     int32_t sessionId = -1;
274     if (g_udpChannelMgrCb->OnFileGetSessionId(udpChannel.channelId, &sessionId) != SOFTBUS_OK) {
275         TRANS_LOGE(TRANS_SDK, "get sessionId failed, dfileId=%{public}d, type=%{public}d", dfileId, msgType);
276         return;
277     }
278 
279     if (msgType == DFILE_ON_CONNECT_FAIL || msgType == DFILE_ON_FATAL_ERROR) {
280         TRANS_LOGE(TRANS_SDK, "FileSendErrorEvent, dfileId=%{public}d, type=%{public}d", dfileId, msgType);
281         FileSendErrorEvent(&udpChannel, &fileListener, msgData, msgType, sessionId);
282         return;
283     }
284     (void)g_udpChannelMgrCb->OnIdleTimeoutReset(sessionId);
285     if (fileListener.socketSendCallback != NULL) {
286         NotifySocketSendResult(sessionId, msgType, msgData, &fileListener);
287     } else {
288         NotifySendResult(sessionId, msgType, msgData, &fileListener);
289     }
290 }
291 
NotifyRecvResult(int32_t sessionId,DFileMsgType msgType,const DFileMsg * msgData,FileListener * listener)292 static void NotifyRecvResult(int32_t sessionId, DFileMsgType msgType, const DFileMsg *msgData,
293     FileListener *listener)
294 {
295     if (msgData == NULL || listener == NULL || msgData->fileList.fileNum <= 0) {
296         TRANS_LOGE(TRANS_SDK, "param invalid");
297         return;
298     }
299 
300     const char *firstFile = msgData->fileList.files[0];
301     uint32_t fileNum = msgData->fileList.fileNum;
302     switch (msgType) {
303         case DFILE_ON_FILE_LIST_RECEIVED:
304             if (listener->recvListener.OnReceiveFileStarted != NULL) {
305                 listener->recvListener.OnReceiveFileStarted(sessionId, firstFile, fileNum);
306             }
307             break;
308         case DFILE_ON_FILE_RECEIVE_SUCCESS:
309             if (listener->recvListener.OnReceiveFileFinished != NULL) {
310                 listener->recvListener.OnReceiveFileFinished(sessionId, firstFile, fileNum);
311             }
312             break;
313         case DFILE_ON_FILE_RECEIVE_FAIL:
314             if (listener->recvListener.OnFileTransError != NULL) {
315                 listener->recvListener.OnFileTransError(sessionId);
316             }
317             break;
318         case DFILE_ON_TRANS_IN_PROGRESS:
319             if (listener->recvListener.OnReceiveFileProcess != NULL) {
320                 uint64_t bytesUpload = msgData->transferUpdate.bytesTransferred;
321                 uint64_t bytesTotal = msgData->transferUpdate.totalBytes;
322                 listener->recvListener.OnReceiveFileProcess(sessionId, firstFile, bytesUpload, bytesTotal);
323             }
324             break;
325         default:
326             break;
327     }
328 }
329 
NotifySocketRecvResult(int32_t socket,DFileMsgType msgType,const DFileMsg * msgData,const FileListener * listener)330 static void NotifySocketRecvResult(
331     int32_t socket, DFileMsgType msgType, const DFileMsg *msgData, const FileListener *listener)
332 {
333     if (msgData == NULL || listener == NULL || listener->socketRecvCallback == NULL) {
334         TRANS_LOGE(TRANS_SDK, "param invalid");
335         return;
336     }
337     FileEvent event;
338     (void)memset_s(&event, sizeof(FileEvent), 0, sizeof(FileEvent));
339     switch (msgType) {
340         case DFILE_ON_FILE_LIST_RECEIVED:
341             event.type = FILE_EVENT_RECV_START;
342             break;
343         case DFILE_ON_TRANS_IN_PROGRESS:
344             event.type = FILE_EVENT_RECV_PROCESS;
345             break;
346         case DFILE_ON_FILE_RECEIVE_SUCCESS:
347             event.type = FILE_EVENT_RECV_FINISH;
348             break;
349         case DFILE_ON_FILE_RECEIVE_FAIL:
350             event.type = FILE_EVENT_RECV_ERROR;
351             break;
352         case DFILE_ON_CLEAR_POLICY_FILE_LIST:
353             event.type = FILE_EVENT_TRANS_STATUS;
354             break;
355         default:
356             return;
357     }
358     TRANS_LOGD(TRANS_SDK, "recvNotify socket=%{public}d type=%{public}d", socket, event.type);
359     event.files = msgData->fileList.files;
360     event.fileCnt = msgData->fileList.fileNum;
361     event.bytesProcessed = msgData->transferUpdate.bytesTransferred;
362     event.bytesTotal = msgData->transferUpdate.totalBytes;
363     event.UpdateRecvPath = NULL;
364     if (event.type == FILE_EVENT_TRANS_STATUS || event.type == FILE_EVENT_RECV_ERROR) {
365         FillFileStatusList(msgData, &event);
366     } else if (event.type == FILE_EVENT_RECV_PROCESS) {
367         event.rate = msgData->rate;
368     }
369     FillFileEventErrorCode(msgData, &event);
370     listener->socketRecvCallback(socket, &event);
371     FreeFileStatusList(&event);
372 }
373 
FileRecvErrorEvent(UdpChannel * udpChannel,FileListener * fileListener,const DFileMsg * msgData,DFileMsgType msgType,int32_t sessionId)374 static void FileRecvErrorEvent(UdpChannel *udpChannel, FileListener *fileListener, const DFileMsg *msgData,
375     DFileMsgType msgType, int32_t sessionId)
376 {
377     if (fileListener->socketRecvCallback != NULL) {
378         FileEvent event;
379         (void)memset_s(&event, sizeof(FileEvent), 0, sizeof(FileEvent));
380         event.type = FILE_EVENT_RECV_ERROR;
381         FillFileStatusList(msgData, &event);
382         FillFileEventErrorCode(msgData, &event);
383         fileListener->socketRecvCallback(sessionId, &event);
384         FreeFileStatusList(&event);
385     } else if (fileListener->recvListener.OnFileTransError != NULL) {
386         fileListener->recvListener.OnFileTransError(sessionId);
387     }
388     TransOnUdpChannelClosed(udpChannel->channelId, SHUTDOWN_REASON_RECV_FILE_ERR);
389     return;
390 }
391 
FileReceiveListener(int32_t dfileId,DFileMsgType msgType,const DFileMsg * msgData)392 static void FileReceiveListener(int32_t dfileId, DFileMsgType msgType, const DFileMsg *msgData)
393 {
394     TRANS_LOGD(TRANS_FILE, "recv dfileId=%{public}d, type=%{public}d", dfileId, msgType);
395     if (!IsParmasValid(msgType, msgData)) {
396         return;
397     }
398     UdpChannel udpChannel;
399     (void)memset_s(&udpChannel, sizeof(UdpChannel), 0, sizeof(UdpChannel));
400     if (TransGetUdpChannelByFileId(dfileId, &udpChannel) != SOFTBUS_OK) {
401         TRANS_LOGE(TRANS_SDK, "get udp channel failed");
402         return;
403     }
404 
405     FileListener fileListener;
406     (void)memset_s(&fileListener, sizeof(FileListener), 0, sizeof(FileListener));
407     if (TransGetFileListener(udpChannel.info.mySessionName, &fileListener) != SOFTBUS_OK) {
408         TRANS_LOGE(TRANS_SDK, "get listener failed");
409         return;
410     }
411     if (msgType == DFILE_ON_CLEAR_POLICY_FILE_LIST) {
412         if (fileListener.socketRecvCallback != NULL) {
413             NotifySocketRecvResult(udpChannel.sessionId, msgType, msgData, &fileListener);
414         }
415         TRANS_LOGI(TRANS_SDK, "notify DFILE_ON_CLEAR_POLICY_FILE_LIST success.");
416         return;
417     }
418     int32_t sessionId = -1;
419     if (g_udpChannelMgrCb->OnFileGetSessionId(udpChannel.channelId, &sessionId) != SOFTBUS_OK) {
420         TRANS_LOGE(TRANS_SDK, "get sessionId failed");
421         return;
422     }
423     if (msgType == DFILE_ON_CONNECT_FAIL || msgType == DFILE_ON_FATAL_ERROR) {
424         FileRecvErrorEvent(&udpChannel, &fileListener, msgData, msgType, sessionId);
425         return;
426     }
427     (void)g_udpChannelMgrCb->OnIdleTimeoutReset(sessionId);
428     if (fileListener.socketRecvCallback != NULL) {
429         NotifySocketRecvResult(sessionId, msgType, msgData, &fileListener);
430     } else {
431         NotifyRecvResult(sessionId, msgType, msgData, &fileListener);
432     }
433 }
434 
UpdateFileRecvPath(int32_t channelId,FileListener * fileListener,int32_t fileSession)435 static int32_t UpdateFileRecvPath(int32_t channelId, FileListener *fileListener, int32_t fileSession)
436 {
437     int32_t sessionId = -1;
438     int32_t ret = g_udpChannelMgrCb->OnFileGetSessionId(channelId, &sessionId);
439     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "get sessionId by channelId failed");
440 
441     if (fileListener->socketRecvCallback != NULL) {
442         FileEvent event;
443         (void)memset_s(&event, sizeof(FileEvent), 0, sizeof(FileEvent));
444         event.type = FILE_EVENT_RECV_UPDATE_PATH;
445         fileListener->socketRecvCallback(sessionId, &event);
446         if (event.UpdateRecvPath == NULL) {
447             TRANS_LOGE(TRANS_SDK, "UpdateRecvPath is null");
448             return SOFTBUS_FILE_ERR;
449         }
450 
451         const char *rootDir = event.UpdateRecvPath();
452         char *absPath = realpath(rootDir, NULL);
453         if (absPath == NULL) {
454             TRANS_LOGE(TRANS_SDK,
455                 "rootDir not exist, rootDir=%{private}s, errno=%{public}d.",
456                 (rootDir == NULL ? "null" : rootDir), errno);
457             return SOFTBUS_FILE_ERR;
458         }
459 
460         if (strcpy_s(fileListener->rootDir, FILE_RECV_ROOT_DIR_SIZE_MAX, absPath) != EOK) {
461             TRANS_LOGE(TRANS_SDK, "strcpy rootDir failed");
462             SoftBusFree(absPath);
463             return SOFTBUS_STRCPY_ERR;
464         }
465         SoftBusFree(absPath);
466     }
467 
468     if (NSTACKX_DFileSetStoragePath(fileSession, fileListener->rootDir) != SOFTBUS_OK) {
469         NSTACKX_DFileClose(fileSession);
470         TRANS_LOGE(TRANS_SDK, "set storage path failed. rootDir=%{private}s", fileListener->rootDir);
471         return SOFTBUS_FILE_ERR;
472     }
473     return SOFTBUS_OK;
474 }
475 
RenameHook(DFileRenamePara * renamePara)476 static void RenameHook(DFileRenamePara *renamePara)
477 {
478     if (renamePara == NULL) {
479         TRANS_LOGE(TRANS_SDK, "invalid param renamePara.");
480         return;
481     }
482     (void)strcpy_s(renamePara->newFileName, NSTACKX_MAX_REMOTE_PATH_LEN, renamePara->initFileName);
483     TRANS_LOGD(TRANS_FILE, "default rename hook.");
484 }
485 
TransOnFileChannelOpened(const char * sessionName,const ChannelInfo * channel,int32_t * filePort,SocketAccessInfo * accessInfo)486 int32_t TransOnFileChannelOpened(
487     const char *sessionName, const ChannelInfo *channel, int32_t *filePort, SocketAccessInfo *accessInfo)
488 {
489     if (channel == NULL || filePort == NULL) {
490         TRANS_LOGW(TRANS_FILE, "invalid param.");
491         return SOFTBUS_INVALID_PARAM;
492     }
493     int32_t fileSession;
494 
495     uint32_t capabilityValue = channel->isUdpFile ? NSTACKX_WLAN_CAT_DIRECT : NSTACKX_WLAN_CAT_TCP;
496     (void)NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_UDP_GSO | NSTACKX_CAPS_WLAN_CATAGORY, capabilityValue);
497     if (channel->isServer) {
498         FileListener fileListener;
499         (void)memset_s(&fileListener, sizeof(FileListener), 0, sizeof(FileListener));
500         int32_t ret = TransGetFileListener(sessionName, &fileListener);
501         TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_FILE, "get file listener failed");
502 
503         fileSession = StartNStackXDFileServer(channel->myIp, (uint8_t *)channel->sessionKey,
504             DEFAULT_KEY_LENGTH, FileReceiveListener, filePort);
505         if (fileSession < 0) {
506             TRANS_LOGE(TRANS_FILE, "start file channel as server failed");
507             return SOFTBUS_FILE_ERR;
508         }
509         ret = g_udpChannelMgrCb->OnUdpChannelOpened(channel->channelId, accessInfo);
510         if (ret != SOFTBUS_OK) {
511             TRANS_LOGE(TRANS_FILE, "udp channel open failed.");
512             NSTACKX_DFileClose(fileSession);
513             *filePort = 0;
514             return ret;
515         }
516         if (UpdateFileRecvPath(channel->channelId, &fileListener, fileSession)) {
517             TRANS_LOGE(TRANS_FILE, "update receive file path failed");
518             NSTACKX_DFileClose(fileSession);
519             *filePort = 0;
520             return SOFTBUS_FILE_ERR;
521         }
522         if (NSTACKX_DFileSetRenameHook(fileSession, RenameHook) != NSTACKX_EOK) {
523             TRANS_LOGE(TRANS_FILE, "set rename hook failed, fileSession=%{public}d, channelId=%{public}d", fileSession,
524                 channel->channelId);
525         }
526     } else {
527         fileSession = StartNStackXDFileClient(channel->peerIp, channel->peerPort,
528             (uint8_t *)channel->sessionKey, DEFAULT_KEY_LENGTH, FileSendListener);
529         if (fileSession < 0) {
530             TRANS_LOGE(TRANS_FILE, "start file channel as client failed");
531             return SOFTBUS_FILE_ERR;
532         }
533     }
534     return fileSession;
535 }
536 
TransCloseDFileProcTask(void * args)537 static void *TransCloseDFileProcTask(void *args)
538 {
539     int32_t *dfileId = (int32_t *)args;
540     TRANS_LOGI(TRANS_FILE, "rsync close dfileId=%{public}d.", *dfileId);
541     NSTACKX_DFileClose(*dfileId);
542     SoftBusFree(dfileId);
543     return NULL;
544 }
545 
TransCloseFileChannel(int32_t dfileId)546 void TransCloseFileChannel(int32_t dfileId)
547 {
548     TRANS_LOGI(TRANS_FILE, "start close file channel, dfileId=%{public}d.", dfileId);
549     SoftBusThreadAttr threadAttr;
550     SoftBusThread tid;
551     int32_t ret = SoftBusThreadAttrInit(&threadAttr);
552     if (ret != SOFTBUS_OK) {
553         TRANS_LOGE(TRANS_FILE, "thread attr init failed, ret=%{public}d.", ret);
554         return;
555     }
556     int32_t *args = (int32_t *)SoftBusCalloc(sizeof(int32_t));
557     if (args == NULL) {
558         TRANS_LOGE(TRANS_FILE, "close dfile calloc failed. dfileId=%{public}d", dfileId);
559         return;
560     }
561     *args = dfileId;
562     threadAttr.detachState = SOFTBUS_THREAD_DETACH;
563     ret = SoftBusThreadCreate(&tid, &threadAttr, TransCloseDFileProcTask, args);
564     if (ret != SOFTBUS_OK) {
565         TRANS_LOGE(TRANS_FILE, "create closed file thread failed, ret=%{public}d.", ret);
566         SoftBusFree(args);
567         return;
568     }
569 }
570 
RegisterFileCb(const UdpChannelMgrCb * fileCb)571 void RegisterFileCb(const UdpChannelMgrCb *fileCb)
572 {
573     if (fileCb == NULL) {
574         TRANS_LOGE(TRANS_FILE, "param invalid");
575         g_udpChannelMgrCb = NULL;
576         return;
577     }
578     if (g_udpChannelMgrCb != NULL) {
579         TRANS_LOGE(TRANS_FILE, "g_udpChannelMgrCb is null");
580         return;
581     }
582     g_udpChannelMgrCb = fileCb;
583 }
584 
TransSendFile(int32_t dfileId,const char * sFileList[],const char * dFileList[],uint32_t fileCnt)585 int32_t TransSendFile(int32_t dfileId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt)
586 {
587     if (dFileList == NULL) {
588         return NSTACKX_DFileSendFiles(dfileId, sFileList, fileCnt, NULL);
589     }
590     return NSTACKX_DFileSendFilesWithRemotePath(dfileId, sFileList, dFileList, fileCnt, NULL);
591 }
592 
NotifyTransLimitChanged(int32_t channelId,uint8_t tos)593 int32_t NotifyTransLimitChanged(int32_t channelId, uint8_t tos)
594 {
595     char sessionName[SESSION_NAME_SIZE_MAX + 1] = { 0 };
596     int32_t ret = ClientGetSessionNameByChannelId(channelId, CHANNEL_TYPE_UDP, sessionName, SESSION_NAME_SIZE_MAX);
597     if (ret != SOFTBUS_OK) {
598         TRANS_LOGE(TRANS_FILE, "failed to get sessionName, channelId=%{public}d", channelId);
599         return ret;
600     }
601     FileListener fileListener;
602     (void)memset_s(&fileListener, sizeof(FileListener), 0, sizeof(FileListener));
603     ret = TransGetFileListener(sessionName, &fileListener);
604     if (ret != SOFTBUS_OK) {
605         TRANS_LOGE(TRANS_FILE, "get file listener failed");
606         return ret;
607     }
608     int32_t sessionId = INVALID_SESSION_ID;
609     ret = ClientGetSessionIdByChannelId(channelId, CHANNEL_TYPE_UDP, &sessionId, false);
610     if (ret != SOFTBUS_OK) {
611         TRANS_LOGE(TRANS_FILE, "get file listener failed");
612         return ret;
613     }
614     if (fileListener.socketSendCallback != NULL) {
615         FileEvent event;
616         (void)memset_s(&event, sizeof(FileEvent), 0, sizeof(FileEvent));
617         event.type = FILE_EVENT_TRANS_LIMIT_CHANGED;
618         if (tos == FILE_PRIORITY_BE) {
619             event.filePriority = FILE_PRIORITY_TYPE_DEFAUT;
620         } else {
621             event.filePriority = FILE_PRIORITY_TYPE_LOW;
622         }
623         fileListener.socketSendCallback(sessionId, &event);
624         TRANS_LOGI(TRANS_FILE, "notify trans limit changed, file priority=%{public}d", event.filePriority);
625     }
626     return ret;
627 }
628