• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_file.h"
17 
18 #include <securec.h>
19 #include "client_trans_file_listener.h"
20 #include "file_adapter.h"
21 #include "nstackx_dfile.h"
22 #include "softbus_adapter_mem.h"
23 #include "softbus_adapter_thread.h"
24 #include "softbus_errcode.h"
25 #include "softbus_log.h"
26 #include "softbus_utils.h"
27 
28 #define DEFAULT_KEY_LENGTH 32
29 
30 static const UdpChannelMgrCb *g_udpChannelMgrCb = NULL;
31 
FileSendListener(int32_t dfileId,DFileMsgType msgType,const DFileMsg * msgData)32 static void FileSendListener(int32_t dfileId, DFileMsgType msgType, const DFileMsg *msgData)
33 {
34     if (msgData == NULL || msgType == DFILE_ON_BIND || msgType == DFILE_ON_SESSION_IN_PROGRESS ||
35         msgType == DFILE_ON_SESSION_TRANSFER_RATE) {
36         return;
37     }
38     UdpChannel udpChannel;
39     (void)memset_s(&udpChannel, sizeof(UdpChannel), 0, sizeof(UdpChannel));
40     if (TransGetUdpChannelByFileId(dfileId, &udpChannel) != SOFTBUS_OK) {
41         return;
42     }
43     if (msgType == DFILE_ON_CONNECT_SUCCESS) {
44         g_udpChannelMgrCb->OnUdpChannelOpened(udpChannel.channelId);
45         return;
46     }
47     if (msgType == DFILE_ON_CONNECT_FAIL || msgType == DFILE_ON_FATAL_ERROR) {
48         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "send dfileId=%d type=%d fatal error.", dfileId, msgType);
49         TransOnUdpChannelClosed(udpChannel.channelId);
50         return;
51     }
52     FileListener fileListener;
53     (void)memset_s(&fileListener, sizeof(FileListener), 0, sizeof(FileListener));
54     if (TransGetFileListener(udpChannel.info.mySessionName, &fileListener) != SOFTBUS_OK) {
55         return;
56     }
57 
58     int32_t sessionId = -1;
59     if (g_udpChannelMgrCb->OnFileGetSessionId(udpChannel.channelId, &sessionId) != SOFTBUS_OK) {
60         return;
61     }
62 
63     switch (msgType) {
64         case DFILE_ON_FILE_SEND_SUCCESS:
65             if (fileListener.sendListener.OnSendFileFinished != NULL) {
66                 fileListener.sendListener.OnSendFileFinished(sessionId, msgData->fileList.files[0]);
67             }
68             break;
69         case DFILE_ON_FILE_SEND_FAIL:
70             if (fileListener.sendListener.OnFileTransError != NULL) {
71                 fileListener.sendListener.OnFileTransError(sessionId);
72             }
73             break;
74         case DFILE_ON_TRANS_IN_PROGRESS:
75             if (fileListener.sendListener.OnSendFileProcess != NULL) {
76                 uint64_t bytesUpload = msgData->transferUpdate.bytesTransferred;
77                 uint64_t bytesTotal = msgData->transferUpdate.totalBytes;
78                 fileListener.sendListener.OnSendFileProcess(sessionId, bytesUpload, bytesTotal);
79             }
80             break;
81         default:
82             break;
83     }
84 }
85 
GetUdpChannel(int32_t dfileId,UdpChannel * udpChannel)86 static int32_t GetUdpChannel(int32_t dfileId, UdpChannel *udpChannel)
87 {
88     if (udpChannel == NULL) {
89         return SOFTBUS_INVALID_PARAM;
90     }
91     (void)memset_s(udpChannel, sizeof(UdpChannel), 0, sizeof(UdpChannel));
92     if (TransGetUdpChannelByFileId(dfileId, udpChannel) != SOFTBUS_OK) {
93         return SOFTBUS_ERR;
94     }
95     return SOFTBUS_OK;
96 }
97 
FileReceiveListener(int32_t dfileId,DFileMsgType msgType,const DFileMsg * msgData)98 static void FileReceiveListener(int32_t dfileId, DFileMsgType msgType, const DFileMsg *msgData)
99 {
100     if (msgData == NULL || msgType == DFILE_ON_BIND || msgType == DFILE_ON_SESSION_IN_PROGRESS ||
101         msgType == DFILE_ON_SESSION_TRANSFER_RATE) {
102         return;
103     }
104     UdpChannel udpChannel;
105     if (GetUdpChannel(dfileId, &udpChannel) != SOFTBUS_OK) {
106         return;
107     }
108     if (msgType == DFILE_ON_CONNECT_FAIL || msgType == DFILE_ON_FATAL_ERROR) {
109         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "recv dfileId=%d type=%d fatal error.", dfileId, msgType);
110         TransOnUdpChannelClosed(udpChannel.channelId);
111         return;
112     }
113     FileListener fileListener;
114     (void)memset_s(&fileListener, sizeof(FileListener), 0, sizeof(FileListener));
115     if (TransGetFileListener(udpChannel.info.mySessionName, &fileListener) != SOFTBUS_OK) {
116         return;
117     }
118     int32_t sessionId = -1;
119     if (g_udpChannelMgrCb->OnFileGetSessionId(udpChannel.channelId, &sessionId) != SOFTBUS_OK) {
120         return;
121     }
122     const char *firstFile = msgData->fileList.files[0];
123     uint32_t fileNum = msgData->fileList.fileNum;
124     switch (msgType) {
125         case DFILE_ON_FILE_LIST_RECEIVED:
126             if (fileListener.recvListener.OnReceiveFileStarted != NULL) {
127                 fileListener.recvListener.OnReceiveFileStarted(sessionId, firstFile, fileNum);
128             }
129             break;
130         case DFILE_ON_FILE_RECEIVE_SUCCESS:
131             if (fileListener.recvListener.OnReceiveFileFinished != NULL) {
132                 fileListener.recvListener.OnReceiveFileFinished(sessionId, firstFile, fileNum);
133             }
134             break;
135         case DFILE_ON_FILE_RECEIVE_FAIL:
136             if (fileListener.recvListener.OnFileTransError != NULL) {
137                 fileListener.recvListener.OnFileTransError(sessionId);
138             }
139             break;
140         case DFILE_ON_TRANS_IN_PROGRESS:
141             if (fileListener.recvListener.OnReceiveFileProcess != NULL) {
142                 uint64_t bytesUpload = msgData->transferUpdate.bytesTransferred;
143                 uint64_t bytesTotal = msgData->transferUpdate.totalBytes;
144                 fileListener.recvListener.OnReceiveFileProcess(sessionId, firstFile, bytesUpload, bytesTotal);
145             }
146             break;
147         default:
148             break;
149     }
150 }
151 
TransOnFileChannelOpened(const char * sessionName,const ChannelInfo * channel,int32_t * filePort)152 int32_t TransOnFileChannelOpened(const char *sessionName, const ChannelInfo *channel, int32_t *filePort)
153 {
154     if (channel == NULL || filePort == NULL) {
155         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "%s:invalid param.", __func__);
156         return SOFTBUS_INVALID_PARAM;
157     }
158     int32_t fileSession;
159 
160     uint32_t capabilityValue = channel->isUdpFile? NSTACKX_WLAN_CAT_DIRECT : NSTACKX_WLAN_CAT_TCP;
161     (void)NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_UDP_GSO | NSTACKX_CAPS_WLAN_CATAGORY, capabilityValue);
162     if (channel->isServer) {
163         FileListener fileListener;
164         (void)memset_s(&fileListener, sizeof(FileListener), 0, sizeof(FileListener));
165         if (TransGetFileListener(sessionName, &fileListener) != SOFTBUS_OK) {
166             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get file listener failed");
167             return SOFTBUS_ERR;
168         }
169         fileSession = StartNStackXDFileServer(channel->myIp, (uint8_t *)channel->sessionKey,
170             DEFAULT_KEY_LENGTH, FileReceiveListener, filePort);
171         if (fileSession < 0) {
172             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "start file channel as server failed");
173             return SOFTBUS_ERR;
174         }
175         if (NSTACKX_DFileSetStoragePath(fileSession, fileListener.rootDir) != SOFTBUS_OK) {
176             NSTACKX_DFileClose(fileSession);
177             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "set storage path failed");
178             return SOFTBUS_ERR;
179         }
180         g_udpChannelMgrCb->OnUdpChannelOpened(channel->channelId);
181     } else {
182         fileSession = StartNStackXDFileClient(channel->peerIp, channel->peerPort,
183             (uint8_t *)channel->sessionKey, DEFAULT_KEY_LENGTH, FileSendListener);
184         if (fileSession < 0) {
185             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "start file channel as client failed");
186             return SOFTBUS_ERR;
187         }
188     }
189     return fileSession;
190 }
191 
TransCloseDFileProcTask(void * args)192 static void *TransCloseDFileProcTask(void *args)
193 {
194     int32_t *dfileId = (int32_t *)args;
195     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "rsync close dfile=%d.", *dfileId);
196     NSTACKX_DFileClose(*dfileId);
197     SoftBusFree(dfileId);
198     return NULL;
199 }
200 
TransCloseFileChannel(int32_t dfileId)201 void TransCloseFileChannel(int32_t dfileId)
202 {
203     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "start close file channel, dfile=%d.", dfileId);
204     SoftBusThreadAttr threadAttr;
205     SoftBusThread tid;
206     int32_t ret = SoftBusThreadAttrInit(&threadAttr);
207     if (ret != SOFTBUS_OK) {
208         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "thread attr init failed, ret=%d.", ret);
209         return;
210     }
211     int32_t *args = (int32_t *)SoftBusCalloc(sizeof(int32_t));
212     if (args == NULL) {
213         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "close dfile %d calloc failed.", dfileId);
214         return;
215     }
216     *args = dfileId;
217     threadAttr.detachState = SOFTBUS_THREAD_DETACH;
218     ret = SoftBusThreadCreate(&tid, &threadAttr, TransCloseDFileProcTask, args);
219     if (ret != SOFTBUS_OK) {
220         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "create closedfile thread failed, ret=%d.", ret);
221         SoftBusFree(args);
222         return;
223     }
224 }
225 
RegisterFileCb(const UdpChannelMgrCb * fileCb)226 void RegisterFileCb(const UdpChannelMgrCb *fileCb)
227 {
228     if (fileCb == NULL) {
229         g_udpChannelMgrCb = NULL;
230         return;
231     }
232     if (g_udpChannelMgrCb != NULL) {
233         return;
234     }
235     g_udpChannelMgrCb = fileCb;
236 }
237 
TransSendFile(int32_t sessionId,const char * sFileList[],const char * dFileList[],uint32_t fileCnt)238 int32_t TransSendFile(int32_t sessionId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt)
239 {
240     if (dFileList == NULL) {
241         return NSTACKX_DFileSendFiles(sessionId, sFileList, fileCnt, NULL);
242     }
243     return NSTACKX_DFileSendFilesWithRemotePath(sessionId, sFileList, dFileList, fileCnt, NULL);
244 }