• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "network/softbus/softbus_agent.h"
17 
18 #include <sstream>
19 
20 #include "device_manager.h"
21 #include "dfs_daemon_event_dfx.h"
22 #include "dfs_error.h"
23 #include "dfsu_exception.h"
24 #include "dm_device_info.h"
25 #include "ipc_skeleton.h"
26 #include "ipc/i_daemon.h"
27 #include "network/softbus/softbus_session_dispatcher.h"
28 #include "network/softbus/softbus_session_name.h"
29 #include "network/softbus/softbus_session.h"
30 #include "softbus_error_code.h"
31 #include "utils_directory.h"
32 #include "utils_log.h"
33 
34 namespace OHOS {
35 namespace Storage {
36 namespace DistributedFile {
37 namespace {
38     constexpr int MAX_RETRY_COUNT = 7;
39 }
40 using namespace std;
41 const int32_t DFS_QOS_TYPE_MIN_BW = 90 * 1024 * 1024;
42 const int32_t DFS_QOS_TYPE_MAX_LATENCY = 10000;
43 const int32_t DFS_QOS_TYPE_MIN_LATENCY = 2000;
44 const std::string SESSION_NAME = "DistributedFileService/mnt/hmdfs/100/account";
45 #ifdef SUPPORT_SAME_ACCOUNT
46 const uint32_t MAX_ONLINE_DEVICE_SIZE = 10000;
47 #endif
SoftbusAgent(weak_ptr<MountPoint> mountPoint)48 SoftbusAgent::SoftbusAgent(weak_ptr<MountPoint> mountPoint) : NetworkAgentTemplate(mountPoint)
49 {
50     sessionName_ = SESSION_NAME;
51 }
52 
IsSameAccount(const std::string & networkId)53 bool SoftbusAgent::IsSameAccount(const std::string &networkId)
54 {
55 #ifdef SUPPORT_SAME_ACCOUNT
56     std::vector<DistributedHardware::DmDeviceInfo> deviceList;
57     DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(IDaemon::SERVICE_NAME, "", deviceList);
58     if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
59         LOGE("trust device list size is invalid, size=%zu", deviceList.size());
60         return false;
61     }
62     for (const auto &deviceInfo : deviceList) {
63         if (std::string(deviceInfo.networkId) == networkId) {
64             return (deviceInfo.authForm == DistributedHardware::DmAuthForm::IDENTICAL_ACCOUNT);
65         }
66     }
67     LOGI("The source and sink device is not same account, not support.");
68     return false;
69 #else
70     return true;
71 #endif
72 }
73 
JudgeNetworkTypeIsWifi(const DeviceInfo & info)74 int32_t SoftbusAgent::JudgeNetworkTypeIsWifi(const DeviceInfo &info)
75 {
76     int32_t networkType;
77     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
78     int errCode = deviceManager.GetNetworkTypeByNetworkId(IDaemon::SERVICE_NAME, info.GetCid(), networkType);
79     if (errCode) {
80         LOGE("failed to get network type by network id errCode = %{public}d", errCode);
81         return FileManagement::ERR_BAD_VALUE;
82     }
83     if (!(static_cast<uint32_t>(networkType) & (1 << DistributedHardware::BIT_NETWORK_TYPE_WIFI))) {
84         LOGI("not wifi network networkType = %{public}d == %{public}d", networkType,
85              1 << DistributedHardware::BIT_NETWORK_TYPE_WIFI);
86         return FileManagement::ERR_BAD_VALUE;
87     }
88     return FileManagement::ERR_OK;
89 }
90 
JoinDomain()91 void SoftbusAgent::JoinDomain()
92 {
93     LOGI("JoinDomain Enter.");
94     ISocketListener sessionListener = {
95         .OnBind = SoftbusSessionDispatcher::OnSessionOpened,
96         .OnShutdown = SoftbusSessionDispatcher::OnSessionClosed,
97         .OnBytes = nullptr,
98         .OnMessage = nullptr,
99         .OnStream = nullptr,
100     };
101 
102     SoftbusSessionDispatcher::RegisterSessionListener(sessionName_, shared_from_this());
103     SocketInfo serverInfo = {
104         .name = const_cast<char*>(sessionName_.c_str()),
105         .pkgName = const_cast<char*>(IDaemon::SERVICE_NAME.c_str()),
106         .dataType = DATA_TYPE_BYTES,
107     };
108     int32_t socketId = Socket(serverInfo);
109     if (socketId < 0) {
110         LOGE("Create Socket fail socketId, socketId = %{public}d", socketId);
111         return;
112     }
113     QosTV qos[] = {
114         {.qos = QOS_TYPE_MIN_BW,        .value = DFS_QOS_TYPE_MIN_BW},
115         {.qos = QOS_TYPE_MAX_LATENCY,        .value = DFS_QOS_TYPE_MAX_LATENCY},
116         {.qos = QOS_TYPE_MIN_LATENCY,        .value = DFS_QOS_TYPE_MIN_LATENCY},
117     };
118 
119     int32_t ret = Listen(socketId, qos, sizeof(qos) / sizeof(qos[0]), &sessionListener);
120     if (ret != FileManagement::E_OK) {
121         Shutdown(socketId);
122         stringstream ss;
123         ss << "Failed to CreateSessionServer, errno:" << ret;
124         LOGE("%{public}s, sessionName:%{public}s", ss.str().c_str(), sessionName_.c_str());
125         throw runtime_error(ss.str());
126     }
127     {
128         std::lock_guard<std::mutex> lock(serverIdMapMutex_);
129         serverIdMap_.insert(std::make_pair(sessionName_, socketId));
130     }
131     LOGI("Succeed to JoinDomain, busName:%{public}s", sessionName_.c_str());
132 }
133 
QuitDomain()134 void SoftbusAgent::QuitDomain()
135 {
136     std::lock_guard<std::mutex> lock(serverIdMapMutex_);
137     if (!serverIdMap_.empty()) {
138         for (auto it = serverIdMap_.begin(); it != serverIdMap_.end(); it++) {
139             if ((it->first).find(sessionName_) != std::string::npos) {
140                 int32_t serverId = serverIdMap_[sessionName_];
141                 Shutdown(serverId);
142                 LOGI("RemoveSessionServer success.");
143             }
144         }
145     }
146     SoftbusSessionDispatcher::UnregisterSessionListener(sessionName_.c_str());
147     LOGI("Succeed to QuitDomain, busName:%{public}s", sessionName_.c_str());
148 }
149 
StopTopHalf()150 void SoftbusAgent::StopTopHalf()
151 {
152     QuitDomain();
153 }
154 
StopBottomHalf()155 void SoftbusAgent::StopBottomHalf() {}
156 
OpenSession(const DeviceInfo & info,const uint8_t & linkType)157 int32_t SoftbusAgent::OpenSession(const DeviceInfo &info, const uint8_t &linkType)
158 {
159     LOGI("Start to OpenSession, cid:%{public}s", Utils::GetAnonyString(info.GetCid()).c_str());
160     if (!IsSameAccount(info.GetCid())) {
161         return FileManagement::E_INVAL_ARG;
162     }
163     ISocketListener sessionListener = {
164         .OnBind = SoftbusSessionDispatcher::OnSessionOpened,
165         .OnShutdown = SoftbusSessionDispatcher::OnSessionClosed,
166         .OnBytes = nullptr,
167         .OnMessage = nullptr,
168         .OnStream = nullptr,
169     };
170     QosTV qos[] = {
171         {.qos = QOS_TYPE_MIN_BW,        .value = DFS_QOS_TYPE_MIN_BW},
172         {.qos = QOS_TYPE_MAX_LATENCY,        .value = DFS_QOS_TYPE_MAX_LATENCY},
173         {.qos = QOS_TYPE_MIN_LATENCY,        .value = DFS_QOS_TYPE_MIN_LATENCY},
174     };
175     SocketInfo clientInfo = {
176         .name = const_cast<char*>((sessionName_.c_str())),
177         .peerName = const_cast<char*>(sessionName_.c_str()),
178         .peerNetworkId = const_cast<char*>(info.GetCid().c_str()),
179         .pkgName = const_cast<char*>(IDaemon::SERVICE_NAME.c_str()),
180         .dataType = DATA_TYPE_BYTES,
181     };
182     int32_t socketId = Socket(clientInfo);
183     if (socketId < FileManagement::E_OK) {
184         LOGE("Create OpenSoftbusChannel Socket error");
185         return FileManagement::E_CONTEXT;
186     }
187     if (FindSocketId(socketId)) {
188         LOGW("Has find socketId:%{public}d", socketId);
189         return FileManagement::E_OK;
190     }
191     int32_t ret = Bind(socketId, qos, sizeof(qos) / sizeof(qos[0]), &sessionListener);
192     if (ret != FileManagement::E_OK) {
193         LOGE("Bind SocketClient error");
194         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_FAILED,
195             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
196             RadarReporter::BIND_SOCKET_ERROR, RadarReporter::PACKAGE_NAME, RadarReporter::dSoftBus + to_string(ret));
197         Shutdown(socketId);
198         return FileManagement::E_CONTEXT;
199     }
200     auto session = make_shared<SoftbusSession>(socketId, info.GetCid());
201     session->DisableSessionListener();
202     session->SetFromServer(false);
203     AcceptSession(session, "Client");
204     LOGI("Suc OpenSession socketId:%{public}d, cid:%{public}s", socketId, Utils::GetAnonyString(info.GetCid()).c_str());
205     return FileManagement::E_OK;
206 }
207 
CloseSession(shared_ptr<BaseSession> session)208 void SoftbusAgent::CloseSession(shared_ptr<BaseSession> session)
209 {
210     if (session == nullptr) {
211         LOGE("Failed to close session, error:invalid session");
212         return;
213     }
214     session->Release();
215 }
216 
IsContinueRetry(const string & cid)217 bool SoftbusAgent::IsContinueRetry(const string &cid)
218 {
219     auto retriedTimesMap = OpenSessionRetriedTimesMap_.find(cid);
220     if (retriedTimesMap != OpenSessionRetriedTimesMap_.end()) {
221         if (retriedTimesMap->second >= MAX_RETRY_COUNT) {
222             return false;
223         }
224     } else {
225         OpenSessionRetriedTimesMap_[cid] = 0;
226     }
227     OpenSessionRetriedTimesMap_[cid]++;
228     return true;
229 }
230 
OnSessionOpened(const int32_t sessionId,PeerSocketInfo info)231 void SoftbusAgent::OnSessionOpened(const int32_t sessionId, PeerSocketInfo info)
232 {
233     LOGI("OnSessionOpened sessionId = %{public}d", sessionId);
234     std::string peerDeviceId = info.networkId;
235     auto session = make_shared<SoftbusSession>(sessionId, peerDeviceId);
236     session->DisableSessionListener();
237     session->SetFromServer(true);
238     AcceptSession(session, "Server");
239 }
240 
OnSessionClosed(int32_t sessionId,const std::string peerDeviceId)241 void SoftbusAgent::OnSessionClosed(int32_t sessionId, const std::string peerDeviceId)
242 {
243     LOGI("OnSessionClosed Enter.");
244     Shutdown(sessionId);
245 }
246 } // namespace DistributedFile
247 } // namespace Storage
248 } // namespace OHOS
249