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