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 "network/softbus/softbus_agent.h"
17
18 #include <sstream>
19
20 #include "dfsu_exception.h"
21 #include "ipc/i_daemon.h"
22 #include "ipc_skeleton.h"
23 #include "network/softbus/softbus_session.h"
24 #include "network/softbus/softbus_session_dispatcher.h"
25 #include "network/softbus/softbus_session_name.h"
26 #include "session.h"
27 #include "utils_log.h"
28
29 namespace OHOS {
30 namespace Storage {
31 namespace DistributedFile {
32 namespace {
33 constexpr int MAX_RETRY_COUNT = 7;
34 }
35 using namespace std;
SoftbusAgent(weak_ptr<MountPoint> mountPoint)36 SoftbusAgent::SoftbusAgent(weak_ptr<MountPoint> mountPoint) : NetworkAgentTemplate(mountPoint)
37 {
38 auto spt = mountPoint.lock();
39 if (spt == nullptr) {
40 LOGE("mountPoint is not exist! bad weak_ptr");
41 sessionName_ = "";
42 return;
43 }
44
45 string path = spt->GetMountArgument().GetFullDst();
46 SoftbusSessionName sessionName(path);
47 sessionName_ = sessionName.ToString();
48 }
49
JoinDomain()50 void SoftbusAgent::JoinDomain()
51 {
52 ISessionListener sessionListener = {
53 .OnSessionOpened = SoftbusSessionDispatcher::OnSessionOpened,
54 .OnSessionClosed = SoftbusSessionDispatcher::OnSessionClosed,
55 .OnBytesReceived = nullptr,
56 .OnMessageReceived = nullptr,
57 .OnStreamReceived = nullptr,
58 };
59
60 SoftbusSessionDispatcher::RegisterSessionListener(sessionName_, shared_from_this());
61 int ret = ::CreateSessionServer(IDaemon::SERVICE_NAME.c_str(), sessionName_.c_str(), &sessionListener);
62 if (ret != 0) {
63 stringstream ss;
64 ss << "Failed to CreateSessionServer, errno:" << ret;
65 LOGE("%{public}s, sessionName:%{public}s", ss.str().c_str(), sessionName_.c_str());
66 throw runtime_error(ss.str());
67 }
68 LOGD("Succeed to JoinDomain, busName:%{public}s", sessionName_.c_str());
69 }
70
QuitDomain()71 void SoftbusAgent::QuitDomain()
72 {
73 int ret = ::RemoveSessionServer(IDaemon::SERVICE_NAME.c_str(), sessionName_.c_str());
74 if (ret != 0) {
75 stringstream ss;
76 ss << "Failed to RemoveSessionServer, errno:" << ret;
77 LOGE("%{public}s", ss.str().c_str());
78 throw runtime_error(ss.str());
79 }
80
81 SoftbusSessionDispatcher::UnregisterSessionListener(sessionName_.c_str());
82 LOGD("Succeed to QuitDomain, busName:%{public}s", sessionName_.c_str());
83 }
84
StopTopHalf()85 void SoftbusAgent::StopTopHalf()
86 {
87 QuitDomain();
88 }
89
StopBottomHalf()90 void SoftbusAgent::StopBottomHalf() {}
91
OpenSession(const DeviceInfo & info)92 void SoftbusAgent::OpenSession(const DeviceInfo &info)
93 {
94 SessionAttribute attr;
95 attr.dataType = TYPE_BYTES;
96
97 LOGD("Start to Open Session, cid:%{public}s", info.GetCid().c_str());
98
99 int sessionId =
100 ::OpenSession(sessionName_.c_str(), sessionName_.c_str(), info.GetCid().c_str(), "hmdfs_wifiGroup", &attr);
101 if (sessionId < 0) {
102 LOGE("Failed to open session, cid:%{public}s, sessionId:%{public}d", info.GetCid().c_str(), sessionId);
103 ThrowException(ERR_SOFTBUS_AGENT_ON_SESSION_OPENED_FAIL, "Open Session failed");
104 }
105 LOGD("Open Session SUCCESS, cid:%{public}s", info.GetCid().c_str());
106 }
107
CloseSession(shared_ptr<BaseSession> session)108 void SoftbusAgent::CloseSession(shared_ptr<BaseSession> session)
109 {
110 if (session == nullptr) {
111 LOGE("Failed to close session, error:invalid session");
112 return;
113 }
114 session->Release();
115 }
116
IsContinueRetry(const string & cid)117 bool SoftbusAgent::IsContinueRetry(const string &cid)
118 {
119 auto retriedTimesMap = OpenSessionRetriedTimesMap_.find(cid);
120 if (retriedTimesMap != OpenSessionRetriedTimesMap_.end()) {
121 if (retriedTimesMap->second >= MAX_RETRY_COUNT) {
122 return false;
123 }
124 } else {
125 OpenSessionRetriedTimesMap_[cid] = 0;
126 }
127 OpenSessionRetriedTimesMap_[cid]++;
128 return true;
129 }
130
OnSessionOpened(const int sessionId,const int result)131 int SoftbusAgent::OnSessionOpened(const int sessionId, const int result)
132 {
133 auto session = make_shared<SoftbusSession>(sessionId);
134 auto cid = session->GetCid();
135
136 DeviceInfo info;
137 info.SetCid(cid);
138 if (result != 0) {
139 LOGE("OnSessionOpened failed, Is %{public}s Side, result:%{public}d",
140 (session->IsFromServer() == true) ? "Server" : "Client", result);
141 if (!session->IsFromServer()) { // client retry
142 if (IsContinueRetry(cid)) {
143 auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, const DeviceInfo>>(
144 &NetworkAgentTemplate::ConnectDeviceAsync, info);
145 cmd->UpdateOption({.tryTimes_ = 1});
146 Recv(move(cmd));
147 } else {
148 LOGE("Exceeded the maximum number of retries, not retry");
149 }
150 }
151 return result;
152 }
153
154 auto retriedTimesMap = OpenSessionRetriedTimesMap_.find(cid);
155 if (retriedTimesMap != OpenSessionRetriedTimesMap_.end()) {
156 OpenSessionRetriedTimesMap_.erase(cid);
157 }
158
159 int socket_fd = session->GetHandle();
160 LOGI(
161 "accept sesion, sessionid:%{public}d, Is %{public}s Side, fd %{public}d, from cid %{public}s, result "
162 "%{public}d",
163 sessionId, (session->IsFromServer() == true) ? "Server" : "Client", socket_fd, cid.c_str(), result);
164 session->DisableSessionListener();
165 AcceptSession(session);
166 return 0;
167 }
168
OnSessionClosed(int sessionId)169 void SoftbusAgent::OnSessionClosed(int sessionId)
170 {
171 auto session = make_shared<SoftbusSession>(sessionId);
172 auto cid = session->GetCid();
173 LOGI("Session to %{public}s closed by unknown reason, Is %{public}s Side", cid.c_str(),
174 (session->IsFromServer() == true) ? "Server" : "Client");
175 }
176 } // namespace DistributedFile
177 } // namespace Storage
178 } // namespace OHOS
179