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