• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "softbus_adapter.h"
17 
18 #include <cinttypes>
19 #include <cstddef>
20 #include <mutex>
21 
22 #include "dfs_error.h"
23 #include "utils_log.h"
24 
25 
26 namespace OHOS::FileManagement::CloudSync {
27 using namespace std;
28 constexpr int MIN_BW = 1024 * 1024 * 40;
29 constexpr int MAX_WAIT_TIMEOUT = 10000;
30 constexpr int MIN_LATENCY = 1000;
31 const string SERVICE_NAME = "OHOS.Filemanagement.Dfs.ICloudSyncService";
32 const std::string HMDFS_PERV_PATH = "/mnt/hmdfs/";
33 const std::string DATA_DIR_PATH = "/account/device_view/local/data/";
GetInstance()34 SoftbusAdapter &SoftbusAdapter::GetInstance()
35 {
36     static SoftbusAdapter instance;
37     return instance;
38 }
39 
CreateSessionServer(const char * packageName,const char * sessionName)40 int32_t SoftbusAdapter::CreateSessionServer(const char *packageName, const char *sessionName)
41 {
42     SocketInfo info = {
43         .name = const_cast<char*>(sessionName),
44         .pkgName = const_cast<char*>(packageName),
45     };
46     int socket = ::Socket(info);
47     if (socket <= 0) {
48         LOGE("Failed to CreateSessionServer ret:%{public}d, sessionName:%{public}s", socket, sessionName);
49         return ERR_BAD_VALUE;
50     }
51     std::string saveKey = std::string(sessionName) + std::string(packageName);
52     {
53         lock_guard<mutex> lock(sessionMutex_);
54         auto sessionAndPackage = sessionAndPackageMap_.find(socket);
55         if (sessionAndPackage == sessionAndPackageMap_.end()) {
56             sessionAndPackageMap_.insert({socket, saveKey});
57         }
58     }
59     QosTV serverQos[] = {
60         { .qos = QOS_TYPE_MIN_BW,            .value = MIN_BW},
61         { .qos = QOS_TYPE_MAX_WAIT_TIMEOUT,      .value = MAX_WAIT_TIMEOUT },
62         { .qos = QOS_TYPE_MIN_LATENCY,       .value = MIN_LATENCY},
63     };
64 
65     ISocketListener listener = {
66         .OnBind = SoftbusAdapter::OnBind,
67         .OnShutdown = SoftbusAdapter::OnShutdown,
68         .OnBytes = SoftbusAdapter::OnBytes,
69         .OnMessage = nullptr,
70         .OnStream = nullptr,
71         .OnFile = SoftbusAdapter::OnFile,
72     };
73 
74     int32_t ret = ::Listen(socket, serverQos, QOS_COUNT, &listener);
75     if (ret != 0) {
76         LOGE("Failed to CreateSessionServer sessionName:%{public}s", sessionName);
77         return ret;
78     }
79     LOGD("Succeed to CreateSessionServer, sessionName:%{public}s", sessionName);
80     return E_OK;
81 }
82 
RemoveSessionServer(const char * packageName,const char * sessionName)83 int32_t SoftbusAdapter::RemoveSessionServer(const char *packageName, const char *sessionName)
84 {
85     std::string val = std::string(sessionName) + std::string(packageName);
86     int32_t socket = SoftbusAdapter::GetInstance().GetSocketNameFromMap(val);
87     string existSessionName = SoftbusAdapter::GetInstance().GetSessionNameFromMap(socket);
88     if (strcmp(existSessionName.c_str(), sessionName) != 0) {
89         LOGE("Failed to RemoveSessionServer sessionName:%{public}s", sessionName);
90         return ERR_BAD_VALUE;
91     }
92     SoftbusAdapter::GetInstance().RemoveSesion(socket);
93     ::Shutdown(socket);
94     LOGD("Succeed to RemoveSessionServer, sessionName:%{public}s", sessionName);
95     return E_OK;
96 }
97 
OnBind(int socket,PeerSocketInfo info)98 void SoftbusAdapter::OnBind(int socket, PeerSocketInfo info)
99 {
100     string sessionName = info.name;
101     string networkId = info.networkId;
102     if (sessionName.empty()) {
103         LOGE("get session name failed");
104         return;
105     }
106 
107     auto listener = SoftbusAdapter::GetInstance().GetListener(sessionName);
108     if (!listener) {
109         LOGD("UnRegisterListener for session %{public}d", socket);
110         return;
111     }
112 
113     listener->OnSessionOpened(socket, 0);
114     SoftbusAdapter::GetInstance().AcceptSesion(socket, sessionName, networkId);
115 }
116 
OnShutdown(int32_t socket,ShutdownReason reason)117 void SoftbusAdapter::OnShutdown(int32_t socket, ShutdownReason reason)
118 {
119     LOGD("Session OnShutdown, sessionId:%{public}d, reason:%{public}d", socket, reason);
120     string sessionName = SoftbusAdapter::GetInstance().GetSessionNameFromMap(socket);
121     if (sessionName.empty()) {
122         LOGE("get session name failed");
123         return;
124     }
125 
126     auto listener = SoftbusAdapter::GetInstance().GetListener(sessionName);
127     if (!listener) {
128         LOGD("UnRegisterListener for session %{public}d", socket);
129         return;
130     }
131 
132     listener->OnSessionClosed(socket);
133     SoftbusAdapter::GetInstance().RemoveSesion(socket);
134 }
135 
OnBytes(int socket,const void * data,unsigned int dataLen)136 void SoftbusAdapter::OnBytes(int socket, const void *data, unsigned int dataLen)
137 {
138     LOGD("OnBytes invoked, dataLen:%{public}d", dataLen);
139     string sessionName = SoftbusAdapter::GetInstance().GetSessionNameFromMap(socket);
140     if (sessionName.empty()) {
141         LOGE("get session name failed");
142         return;
143     }
144 
145     string peerDeviceId = SoftbusAdapter::GetInstance().GetPeerNetworkId(socket);
146     if (peerDeviceId.empty()) {
147         LOGE("get peerDeviceId name failed");
148         return;
149     }
150 
151     auto listener = SoftbusAdapter::GetInstance().GetListener(sessionName);
152     if (!listener) {
153         LOGD("UnRegisterListener for session %{public}d", socket);
154         return;
155     }
156 
157     listener->OnDataReceived(peerDeviceId, socket, data, dataLen);
158 }
159 
OnReceiveFileProcess(int sessionId,const char * firstFile,uint64_t bytesUpload,uint64_t bytesTotal)160 int SoftbusAdapter::OnReceiveFileProcess(int sessionId,
161                                          const char *firstFile,
162                                          uint64_t bytesUpload,
163                                          uint64_t bytesTotal)
164 {
165     LOGD(
166         "File receive process sessionId = %{public}d, first file:%{public}s, bytesUpload:%{public}" PRIu64 ", "
167         "bytesTotal:%{public}" PRIu64 "",
168         sessionId, GetAnonyString(firstFile).c_str(), bytesUpload, bytesTotal);
169     return E_OK;
170 }
171 
OnReceiveFileFinished(int sessionId,const char * files,int fileCnt)172 void SoftbusAdapter::OnReceiveFileFinished(int sessionId, const char *files, int fileCnt)
173 {
174     LOGD("OnReceiveFileFinished invoked, files:%{public}s, fileCnt:%{public}d", files, fileCnt);
175     string sessionName = SoftbusAdapter::GetInstance().GetSessionNameFromMap(sessionId);
176     if (sessionName.empty()) {
177         LOGE("get session name failed");
178         return;
179     }
180 
181     string peerNetworkId = SoftbusAdapter::GetInstance().GetPeerNetworkId(sessionId);
182     if (peerNetworkId.empty()) {
183         LOGE("get peerDeviceId name failed");
184         return;
185     }
186 
187     auto listener = SoftbusAdapter::GetInstance().GetListener(sessionName);
188     if (!listener) {
189         LOGD("UnRegisterListener for session %{public}d", sessionId);
190         return;
191     }
192 
193     listener->OnFileReceived(peerNetworkId, files, E_OK);
194 }
195 
GetRecvPath()196 const char* SoftbusAdapter::GetRecvPath()
197 {
198     const char *path = pathDir_.c_str();
199     return path;
200 }
201 
OnFile(int32_t socket,FileEvent * event)202 void SoftbusAdapter::OnFile(int32_t socket, FileEvent *event)
203 {
204     if (event->type == FILE_EVENT_RECV_UPDATE_PATH) {
205         event->UpdateRecvPath = GetRecvPath;
206     }
207 }
208 
OpenSession(char * sessionName,char * peerDeviceId,char * groupId,TransDataType dataType)209 int SoftbusAdapter::OpenSession(char *sessionName,
210                                 char *peerDeviceId,
211                                 char *groupId,
212                                 TransDataType dataType)
213 {
214     SocketInfo info = {
215         .name = sessionName,
216         .peerName = sessionName,
217         .peerNetworkId = peerDeviceId,
218         .pkgName = const_cast<char*>(SERVICE_NAME.c_str()),
219         .dataType = dataType,
220     };
221     int32_t socket = Socket(info);
222     if (socket <= 0) {
223         return ERR_BAD_VALUE;
224     }
225     std::string saveKey = std::string(sessionName) + std::string(SERVICE_NAME);
226     {
227         lock_guard<mutex> lock(sessionMutex_);
228         auto sessionAndPackage = sessionAndPackageMap_.find(socket);
229         if (sessionAndPackage == sessionAndPackageMap_.end()) {
230             sessionAndPackageMap_.insert({socket, saveKey});
231         }
232     }
233     QosTV clientQos[] = {
234         { .qos = QOS_TYPE_MIN_BW,            .value = MIN_BW},
235         { .qos = QOS_TYPE_MAX_WAIT_TIMEOUT,      .value = MAX_WAIT_TIMEOUT },
236         { .qos = QOS_TYPE_MIN_LATENCY,       .value = MIN_LATENCY},
237     };
238 
239     ISocketListener listener = {
240         .OnBind = SoftbusAdapter::OnBind,
241         .OnShutdown = SoftbusAdapter::OnShutdown,
242         .OnBytes = SoftbusAdapter::OnBytes,
243         .OnFile = SoftbusAdapter::OnFile,
244     };
245     SoftbusAdapter::GetInstance().AcceptSesion(socket, sessionName, peerDeviceId);
246     int32_t ret = ::Bind(socket, clientQos, QOS_COUNT, &listener);
247     if (ret != 0) {
248         ::Shutdown(socket);
249     }
250     return socket;
251 }
252 
OpenSessionByP2P(char * sessionName,char * peerDeviceId,char * groupId,bool isFileType)253 int SoftbusAdapter::OpenSessionByP2P(char *sessionName,
254                                      char *peerDeviceId,
255                                      char *groupId,
256                                      bool isFileType)
257 {
258     TransDataType dataType;
259     if (isFileType) {
260         dataType = DATA_TYPE_FILE;
261     } else {
262         dataType = DATA_TYPE_BYTES;
263     }
264     return OpenSession(sessionName, peerDeviceId, groupId, dataType);
265 }
266 
CloseSession(int sessionId)267 void SoftbusAdapter::CloseSession(int sessionId)
268 {
269     ::CloseSession(sessionId);
270 }
271 
SendBytes(int sessionId,const void * data,unsigned int dataLen)272 int SoftbusAdapter::SendBytes(int sessionId, const void *data, unsigned int dataLen)
273 {
274     return ::SendBytes(sessionId, data, dataLen);
275 }
276 
SendFile(int sessionId,const std::vector<std::string> & sFileList,const std::vector<std::string> & dFileList)277 int SoftbusAdapter::SendFile(int sessionId,
278                              const std::vector<std::string> &sFileList,
279                              const std::vector<std::string> &dFileList)
280 {
281     vector<const char *> sourceFileList;
282     vector<const char *> destFileList;
283 
284     for (const string &file : sFileList) {
285         sourceFileList.push_back(file.data());
286     }
287 
288     for (const string &file : dFileList) {
289         destFileList.push_back(file.data());
290     }
291 
292     return ::SendFile(sessionId, sourceFileList.data(), destFileList.data(), sourceFileList.size());
293 }
294 
295 /* should use this interface when session closed */
GetSessionNameFromMap(int sessionId)296 std::string SoftbusAdapter::GetSessionNameFromMap(int sessionId)
297 {
298     lock_guard<mutex> lock(sessionMutex_);
299     auto iter = sessionNameMap_.find(sessionId);
300     if (iter != sessionNameMap_.end()) {
301         return iter->second;
302     }
303     return "";
304 }
305 
GetSocketNameFromMap(std::string sessionAndPack)306 int32_t SoftbusAdapter::GetSocketNameFromMap(std::string sessionAndPack)
307 {
308     lock_guard<mutex> lock(sessionMutex_);
309     int32_t socket = -1;
310     for (const auto& pair : sessionAndPackageMap_) {
311         if (pair.second == sessionAndPack) {
312             socket = pair.first;
313             break;
314         }
315     }
316     return socket;
317 }
318 
GetPeerNetworkId(int sessionId)319 std::string SoftbusAdapter::GetPeerNetworkId(int sessionId)
320 {
321     lock_guard<mutex> lock(sessionMutex_);
322     auto iter = networkIdMap_.find(sessionId);
323     if (iter != networkIdMap_.end()) {
324         return iter->second;
325     }
326     return "";
327 }
328 
RegisterSessionListener(std::string sessionName,std::shared_ptr<ISoftbusListener> listener)329 void SoftbusAdapter::RegisterSessionListener(std::string sessionName, std::shared_ptr<ISoftbusListener> listener)
330 {
331     std::unique_lock<shared_mutex> lock(listenerMutex_);
332     listeners_[sessionName] = listener;
333 }
334 
UnRegisterSessionListener(std::string sessionName)335 void SoftbusAdapter::UnRegisterSessionListener(std::string sessionName)
336 {
337     std::unique_lock<shared_mutex> lock(listenerMutex_);
338     listeners_.erase(sessionName);
339 }
340 
GetListener(std::string sessionName)341 std::shared_ptr<ISoftbusListener> SoftbusAdapter::GetListener(std::string sessionName)
342 {
343     shared_lock<shared_mutex> lock(listenerMutex_);
344     if (listeners_.count(sessionName) == 0) {
345         return nullptr;
346     }
347     return listeners_[sessionName];
348 }
349 
IsSessionOpened(int sessionId)350 bool SoftbusAdapter::IsSessionOpened(int sessionId)
351 {
352     lock_guard<mutex> lock(sessionMutex_);
353     auto iter = sessionOpenedMap_.find(sessionId);
354     if (iter == sessionOpenedMap_.end()) {
355         return false;
356     }
357     return iter->second;
358 }
359 
AcceptSesion(int sessionId,const std::string & sessionName,const std::string & networkId)360 void SoftbusAdapter::AcceptSesion(int sessionId, const std::string &sessionName, const std::string &networkId)
361 {
362     lock_guard<mutex> lock(sessionMutex_);
363     auto iter = sessionOpenedMap_.find(sessionId);
364     if (iter == sessionOpenedMap_.end()) {
365         sessionOpenedMap_.insert({sessionId, true});
366     }
367 
368     auto sessionNameMap = sessionNameMap_.find(sessionId);
369     if (sessionNameMap == sessionNameMap_.end()) {
370         sessionNameMap_.insert({sessionId, sessionName});
371     }
372 
373     auto networkIdMap = networkIdMap_.find(sessionId);
374     if (networkIdMap == networkIdMap_.end()) {
375         networkIdMap_.insert({sessionId, networkId});
376     }
377 }
378 
RemoveSesion(int sessionId)379 void SoftbusAdapter::RemoveSesion(int sessionId)
380 {
381     lock_guard<mutex> lock(sessionMutex_);
382     auto iter = sessionOpenedMap_.find(sessionId);
383     if (iter != sessionOpenedMap_.end()) {
384         sessionOpenedMap_.erase(iter);
385     }
386 
387     auto sessionNameMap = sessionNameMap_.find(sessionId);
388     if (sessionNameMap != sessionNameMap_.end()) {
389         sessionNameMap_.erase(sessionNameMap);
390     }
391 
392     auto networkIdMap = networkIdMap_.find(sessionId);
393     if (networkIdMap != networkIdMap_.end()) {
394         networkIdMap_.erase(networkIdMap);
395     }
396 }
397 
UpdateFileRecvPath(const std::string & bundleName,int32_t userId)398 void SoftbusAdapter::UpdateFileRecvPath(const std::string &bundleName, int32_t userId)
399 {
400     pathDir_ = HMDFS_PERV_PATH + std::to_string(userId) + DATA_DIR_PATH + bundleName;
401     LOGI("recv path: %{public}s", GetAnonyString(pathDir_).c_str());
402 }
403 } // namespace OHOS::FileManagement::CloudSync