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 "session_service_impl.h"
17 
18 #include "session_impl.h"
19 #include "session_mock.h"
20 #include "softbus_bus_center.h"
21 #include "softbus_def.h"
22 #include "softbus_errcode.h"
23 #include "trans_log.h"
24 
25 namespace Communication {
26 namespace SoftBus {
27 std::shared_mutex ISessionService::instanceMutex_;
28 std::shared_ptr<ISessionService> ISessionService::instance_ = nullptr;
29 std::mutex SessionServiceImpl::listenerMutex_;
30 std::map<std::string, std::shared_ptr<ISessionListener>> SessionServiceImpl::listenerMap_;
31 std::mutex SessionServiceImpl::sessionMutex_;
32 std::map<int32_t, std::shared_ptr<Session>> SessionServiceImpl::sessionMap_;
33 
GetInstance()34 std::shared_ptr<ISessionService> ISessionService::GetInstance()
35 {
36     std::shared_ptr<ISessionService> tmp = instance_;
37     if (tmp == nullptr) {
38         std::unique_lock<std::shared_mutex> instanceLock(instanceMutex_);
39         tmp = instance_;
40         if (tmp == nullptr) {
41             tmp = std::make_shared<SessionServiceImpl>();
42             instance_ = tmp;
43         }
44     }
45     return instance_;
46 }
47 
CreateSessionServer(const std::string & pkgName,const std::string & sessionName,std::shared_ptr<ISessionListener> listener)48 int32_t SessionServiceImpl::CreateSessionServer(
49     const std::string &pkgName, const std::string &sessionName, std::shared_ptr<ISessionListener> listener)
50 {
51     if (pkgName.empty() || sessionName.empty() || listener == nullptr) {
52         TRANS_LOGE(TRANS_SDK, "pkgName or sessionName or listener invalid");
53         return SOFTBUS_INVALID_PARAM;
54     }
55 
56     std::lock_guard<std::mutex> autoLock(listenerMutex_);
57     int32_t ret = CreateSessionServerInner(pkgName.c_str(), sessionName.c_str());
58     if (ret == SOFTBUS_OK) {
59         listenerMap_.insert(std::pair<std::string, std::shared_ptr<ISessionListener>>(sessionName, listener));
60     }
61     return ret;
62 }
63 
RemoveSessionServer(const std::string & pkgName,const std::string & sessionName)64 int32_t SessionServiceImpl::RemoveSessionServer(const std::string &pkgName, const std::string &sessionName)
65 {
66     if (pkgName.empty() || sessionName.empty()) {
67         TRANS_LOGE(TRANS_SDK, "pkgName or sessionName invalid");
68         return SOFTBUS_INVALID_PARAM;
69     }
70 
71     std::lock_guard<std::mutex> autoLock(listenerMutex_);
72     auto iter = listenerMap_.find(sessionName);
73     if (iter != listenerMap_.end()) {
74         listenerMap_.erase(iter);
75         return RemoveSessionServerInner(pkgName.c_str(), sessionName.c_str());
76     }
77     TRANS_LOGE(TRANS_SDK, "not find session server");
78     return SOFTBUS_TRANS_SESSION_SERVER_NOINIT;
79 }
80 
OpenSession(const std::string & mySessionName,const std::string & peerSessionName,const std::string & peerNetworkId,const std::string & groupId,int32_t flags)81 std::shared_ptr<Session> SessionServiceImpl::OpenSession(const std::string &mySessionName,
82     const std::string &peerSessionName, const std::string &peerNetworkId, const std::string &groupId, int32_t flags)
83 {
84     TRANS_LOGD(TRANS_SDK, "enter.");
85     if (mySessionName.empty() || peerSessionName.empty() || peerNetworkId.empty()) {
86         return nullptr;
87     }
88     int32_t sessionId =
89         OpenSessionInner(mySessionName.c_str(), peerSessionName.c_str(), peerNetworkId.c_str(), groupId.c_str(), flags);
90     if (sessionId <= 0) {
91         TRANS_LOGE(TRANS_SDK, "invalid sessionId.");
92         return nullptr;
93     }
94 
95     std::shared_ptr<Session> session;
96     std::lock_guard<std::mutex> autoLock(sessionMutex_);
97     auto iter = sessionMap_.find(sessionId);
98     if (iter != sessionMap_.end()) {
99         session = iter->second;
100         TRANS_LOGE(TRANS_SDK, "Session find");
101     }
102     TRANS_LOGD(TRANS_SDK, "ok");
103     return session;
104 }
105 
CloseSession(std::shared_ptr<Session> session)106 int32_t SessionServiceImpl::CloseSession(std::shared_ptr<Session> session)
107 {
108     if (session == nullptr) {
109         TRANS_LOGE(TRANS_SDK, "invalid param session");
110         return SOFTBUS_INVALID_PARAM;
111     }
112     int32_t sessionId = session->GetSessionId();
113     if (sessionId <= 0) {
114         TRANS_LOGE(TRANS_SDK, "invalid sessionId. sessionId=%{public}d", sessionId);
115         return SOFTBUS_TRANS_INVALID_SESSION_ID;
116     }
117     CloseSessionInner(sessionId);
118     std::lock_guard<std::mutex> autoLock(sessionMutex_);
119     auto iter = sessionMap_.find(sessionId);
120     if (iter != sessionMap_.end()) {
121         sessionMap_.erase(sessionId);
122     }
123     return SOFTBUS_OK;
124 }
125 
GrantPermission(int32_t uid,int32_t pid,const std::string & busName)126 int32_t SessionServiceImpl::GrantPermission(int32_t uid, int32_t pid, const std::string &busName)
127 {
128     if (uid < 0 || pid < 0 || busName.empty()) {
129         TRANS_LOGE(TRANS_SDK, "invalid uid or pid or busName");
130         return SOFTBUS_INVALID_PARAM;
131     }
132     return GrantPermissionInner(uid, pid, busName.c_str());
133 }
134 
RemovePermission(const std::string & busName)135 int32_t SessionServiceImpl::RemovePermission(const std::string &busName)
136 {
137     if (busName.empty()) {
138         TRANS_LOGE(TRANS_SDK, "busName invalid");
139         return SOFTBUS_INVALID_PARAM;
140     }
141     return RemovePermissionInner(busName.c_str());
142 }
143 
CreateSession(int32_t sessionId,const std::shared_ptr<Session> & session)144 int32_t SessionServiceImpl::CreateSession(int32_t sessionId, const std::shared_ptr<Session> &session)
145 {
146     TRANS_LOGD(TRANS_SDK, "enter.");
147     int32_t isServer;
148     int32_t ret = IsServerSideInner(sessionId, &isServer);
149     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "server side failed!");
150 
151     session->SetSessionId(sessionId);
152 
153     char str[SESSION_NAME_SIZE_MAX];
154 
155     ret = GetMySessionNameInner(sessionId, str, SESSION_NAME_SIZE_MAX);
156     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "get session name failed!");
157 
158     std::string mySessionName(str);
159     session->SetMySessionName(mySessionName);
160 
161     ret = GetPeerSessionNameInner(sessionId, str, SESSION_NAME_SIZE_MAX);
162     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "get peer session name failed!");
163 
164     std::string peerSessionName(str);
165     session->SetPeerSessionName(peerSessionName);
166 
167     char networkId[DEVICE_ID_SIZE_MAX];
168     ret = GetPeerDeviceIdInner(sessionId, networkId, DEVICE_ID_SIZE_MAX);
169     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "get peer device id failed!");
170 
171     std::string peerNetworkId(networkId);
172     session->SetPeerDeviceId(peerNetworkId);
173     session->SetIsServer(isServer);
174 
175     std::lock_guard<std::mutex> autoLock(sessionMutex_);
176     sessionMap_.insert(std::pair<int32_t, std::shared_ptr<Session>>(sessionId, session));
177 
178     return SOFTBUS_OK;
179 }
180 
OpenSessionCallback(int32_t sessionId)181 int32_t SessionServiceImpl::OpenSessionCallback(int32_t sessionId)
182 {
183     std::shared_ptr<Session> session = std::make_shared<SessionImpl>();
184 
185     int32_t ret = CreateSession(sessionId, session);
186     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "create session failed!");
187 
188     std::shared_ptr<ISessionListener> listener;
189     ret = GetSessionListenerOnSessionOpened(sessionId, listener, session);
190     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "get session listener failed!");
191 
192     NodeBasicInfo info;
193     char pkgName[PKG_NAME_SIZE_MAX];
194     ret = GetPkgNameInner(sessionId, pkgName, PKG_NAME_SIZE_MAX);
195     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "get pkgName failed!");
196 
197     ret = GetLocalNodeDeviceInfo(pkgName, &info);
198     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "get deviceInfo failed!");
199 
200     session->SetDeviceId(info.networkId);
201 
202     int32_t tmp;
203     ret = GetPeerUidInner(sessionId, &tmp);
204     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "get peer uid failed!");
205 
206     session->SetPeerUid(static_cast<uid_t>(tmp));
207     ret = GetPeerPidInner(sessionId, &tmp);
208     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "get peer pid failed!");
209     session->SetPeerPid(static_cast<pid_t>(tmp));
210 
211     TRANS_LOGD(TRANS_SDK, "Ok");
212     return listener->OnSessionOpened(session);
213 }
214 
CloseSessionCallback(int32_t sessionId)215 void SessionServiceImpl::CloseSessionCallback(int32_t sessionId)
216 {
217     std::shared_ptr<ISessionListener> listener;
218     std::shared_ptr<Session> session;
219     if (GetSessionListener(sessionId, listener, session) != SOFTBUS_OK) {
220         return;
221     }
222     listener->OnSessionClosed(session);
223 }
224 
BytesReceivedCallback(int32_t sessionId,const void * data,uint32_t len)225 void SessionServiceImpl::BytesReceivedCallback(int32_t sessionId, const void *data, uint32_t len)
226 {
227     std::shared_ptr<ISessionListener> listener;
228     std::shared_ptr<Session> session;
229     if (GetSessionListener(sessionId, listener, session) != SOFTBUS_OK) {
230         return;
231     }
232     const char *msg = static_cast<const char *>(data);
233     ssize_t lenMsg = static_cast<ssize_t>(len);
234     listener->OnBytesReceived(session, msg, lenMsg);
235 }
236 
MessageReceivedCallback(int32_t sessionId,const void * data,uint32_t len)237 void SessionServiceImpl::MessageReceivedCallback(int32_t sessionId, const void *data, uint32_t len)
238 {
239     std::shared_ptr<ISessionListener> listener;
240     std::shared_ptr<Session> session;
241     if (GetSessionListener(sessionId, listener, session) != SOFTBUS_OK) {
242         return;
243     }
244     const char *msg = static_cast<const char *>(data);
245     ssize_t lenMsg = static_cast<ssize_t>(len);
246     listener->OnMessageReceived(session, msg, lenMsg);
247 }
248 
GetSessionListener(int32_t sessionId,std::shared_ptr<ISessionListener> & listener,std::shared_ptr<Session> & session)249 int32_t SessionServiceImpl::GetSessionListener(
250     int32_t sessionId, std::shared_ptr<ISessionListener> &listener, std::shared_ptr<Session> &session)
251 {
252     std::lock_guard<std::mutex> autoLock(sessionMutex_);
253     auto iter = sessionMap_.find(sessionId);
254     if (iter != sessionMap_.end()) {
255         session = iter->second;
256         std::lock_guard<std::mutex> autoLock(listenerMutex_);
257         auto iterListener = listenerMap_.find(session->GetMySessionName());
258         if (iterListener != listenerMap_.end()) {
259             listener = iterListener->second;
260             return SOFTBUS_OK;
261         }
262     }
263     return SOFTBUS_NOT_FIND;
264 }
265 
GetSessionListenerOnSessionOpened(int32_t sessionId,std::shared_ptr<ISessionListener> & listener,std::shared_ptr<Session> & session)266 int32_t SessionServiceImpl::GetSessionListenerOnSessionOpened(
267     int32_t sessionId, std::shared_ptr<ISessionListener> &listener, std::shared_ptr<Session> &session)
268 {
269     (void)session;
270     char str[SESSION_NAME_SIZE_MAX];
271     int32_t ret = GetMySessionNameInner(sessionId, str, SESSION_NAME_SIZE_MAX);
272     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "get my session name failed!");
273 
274     std::string mySessionName(str);
275 
276     std::lock_guard<std::mutex> autoLock(listenerMutex_);
277     auto iterListener = listenerMap_.find(mySessionName);
278     if (iterListener != listenerMap_.end()) {
279         listener = iterListener->second;
280         return SOFTBUS_OK;
281     }
282     return SOFTBUS_NOT_FIND;
283 }
284 } // namespace SoftBus
285 } // namespace Communication
286