1 /*
2 * Copyright (c) 2022-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 "softbus_adapter.h"
17
18 #include <securec.h>
19 #include <unistd.h>
20
21 #include "softbus_bus_center.h"
22 #include "softbus_common.h"
23
24 #include "dscreen_errcode.h"
25 #include "dscreen_hisysevent.h"
26 #include "dscreen_util.h"
27
28 namespace OHOS {
29 namespace DistributedHardware {
30 IMPLEMENT_SINGLE_INSTANCE(SoftbusAdapter);
ScreenOnSoftbusSessionOpened(int32_t sessionId,PeerSocketInfo info)31 static void ScreenOnSoftbusSessionOpened(int32_t sessionId, PeerSocketInfo info)
32 {
33 SoftbusAdapter::GetInstance().OnSoftbusSessionOpened(sessionId, info);
34 }
35
ScreenOnSoftbusSessionClosed(int32_t sessionId,ShutdownReason reason)36 static void ScreenOnSoftbusSessionClosed(int32_t sessionId, ShutdownReason reason)
37 {
38 SoftbusAdapter::GetInstance().OnSoftbusSessionClosed(sessionId, reason);
39 }
40
ScreenOnBytesReceived(int32_t sessionId,const void * data,uint32_t dataLen)41 static void ScreenOnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen)
42 {
43 SoftbusAdapter::GetInstance().OnBytesReceived(sessionId, data, dataLen);
44 }
45
ScreenOnStreamReceived(int32_t sessionId,const StreamData * data,const StreamData * ext,const StreamFrameInfo * frameInfo)46 static void ScreenOnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext,
47 const StreamFrameInfo *frameInfo)
48 {
49 SoftbusAdapter::GetInstance().OnStreamReceived(sessionId, data, ext, frameInfo);
50 }
51
ScreenOnMessageReceived(int sessionId,const void * data,unsigned int dataLen)52 static void ScreenOnMessageReceived(int sessionId, const void *data, unsigned int dataLen)
53 {
54 SoftbusAdapter::GetInstance().OnMessageReceived(sessionId, data, dataLen);
55 }
56
SoftbusAdapter()57 SoftbusAdapter::SoftbusAdapter()
58 {
59 DHLOGI("SoftbusAdapter");
60 sessListener_.OnBind = ScreenOnSoftbusSessionOpened;
61 sessListener_.OnShutdown = ScreenOnSoftbusSessionClosed;
62 sessListener_.OnBytes = ScreenOnBytesReceived;
63 sessListener_.OnStream = ScreenOnStreamReceived;
64 sessListener_.OnMessage = ScreenOnMessageReceived;
65 sessListener_.OnFile = nullptr;
66 sessListener_.OnQos = nullptr;
67 sessListener_.OnError = nullptr;
68 sessListener_.OnNegotiate = nullptr;
69 }
70
~SoftbusAdapter()71 SoftbusAdapter::~SoftbusAdapter()
72 {
73 DHLOGI("~SoftbusAdapter");
74 }
75
RegisterSoftbusListener(const std::shared_ptr<ISoftbusListener> & listener,const std::string & sessionName,const std::string & peerDevId)76 int32_t SoftbusAdapter::RegisterSoftbusListener(const std::shared_ptr<ISoftbusListener> &listener,
77 const std::string &sessionName, const std::string &peerDevId)
78 {
79 if (listener == nullptr) {
80 DHLOGE("%{public}s: listener is nullptr.", DSCREEN_LOG_TAG);
81 return ERR_DH_SCREEN_ADAPTER_REGISTER_SOFTBUS_LISTENER_FAIL;
82 }
83 DHLOGI("%{public}s: RegisterListener sess:%{public}s id:%{public}s.", DSCREEN_LOG_TAG, sessionName.c_str(),
84 GetAnonyString(peerDevId).c_str());
85 std::string strListenerKey = sessionName + "_" + peerDevId;
86 std::lock_guard<std::mutex> lisLock(listenerMtx_);
87 if (mapListeners_.find(strListenerKey) != mapListeners_.end()) {
88 DHLOGE("%{public}s: Session listener already register.", DSCREEN_LOG_TAG);
89 return ERR_DH_SCREEN_ADAPTER_REGISTER_SOFTBUS_LISTENER_FAIL;
90 }
91 mapListeners_.insert(std::make_pair(strListenerKey, listener));
92
93 return DH_SUCCESS;
94 }
95
UnRegisterSoftbusListener(const std::string & sessionName,const std::string & peerDevId)96 int32_t SoftbusAdapter::UnRegisterSoftbusListener(const std::string &sessionName, const std::string &peerDevId)
97 {
98 DHLOGI("%{public}s: UnRegisterListener sess:%{public}s id:%{public}s.", DSCREEN_LOG_TAG, sessionName.c_str(),
99 GetAnonyString(peerDevId).c_str());
100 std::string strListenerKey = sessionName + "_" + peerDevId;
101
102 std::lock_guard<std::mutex> lisLock(listenerMtx_);
103 mapListeners_.erase(strListenerKey);
104
105 return DH_SUCCESS;
106 }
107
CreateSoftbusSessionServer(const std::string & pkgname,const std::string & sessionName,const std::string & peerDevId)108 int32_t SoftbusAdapter::CreateSoftbusSessionServer(const std::string &pkgname, const std::string &sessionName,
109 const std::string &peerDevId)
110 {
111 DHLOGI("%{public}s: CreateSessionServer sess:%{public}s id:%{public}s.", DSCREEN_LOG_TAG, sessionName.c_str(),
112 GetAnonyString(peerDevId).c_str());
113 {
114 std::lock_guard<std::mutex> lock(serverIdMapMutex_);
115 std::string idMapValue = sessionName + "_" + peerDevId;
116 for (auto it = serverIdMap_.begin(); it != serverIdMap_.end(); it++) {
117 if (((it->second).find(idMapValue) != std::string::npos)) {
118 DHLOGI("%{public}s: Session already create.", sessionName.c_str());
119 return DH_SUCCESS;
120 }
121 }
122 }
123
124 SocketInfo serverInfo = {
125 .name = const_cast<char*>(sessionName.c_str()),
126 .pkgName = const_cast<char*>(pkgname.c_str()),
127 .dataType = DATA_TYPE_VIDEO_STREAM,
128 };
129 int32_t socketId = Socket(serverInfo);
130 if (socketId < 0) {
131 DHLOGE("Create Socket fail socketId:%{public}" PRId32, socketId);
132 return ERR_DH_SCREEN_ADAPTER_BAD_VALUE;
133 }
134 QosTV qos[] = {
135 {.qos = QOS_TYPE_MIN_BW, .value = 40 * 1024 * 1024},
136 {.qos = QOS_TYPE_MAX_LATENCY, .value = 8000},
137 {.qos = QOS_TYPE_MIN_LATENCY, .value = 2000},
138 };
139
140 int32_t ret = Listen(socketId, qos, sizeof(qos) / sizeof(qos[0]), &sessListener_);
141 if (ret != DH_SUCCESS) {
142 DHLOGE("Listen socket error for sessionName:%{public}s", sessionName.c_str());
143 return ERR_DH_SCREEN_ADAPTER_BAD_VALUE;
144 }
145 {
146 std::lock_guard<std::mutex> lock(serverIdMapMutex_);
147 serverIdMap_.insert(std::make_pair(socketId, sessionName + "_" + peerDevId));
148 }
149 DHLOGI("%{public}s: CreateSessionServer success sessionId. %{public}" PRId32, DSCREEN_LOG_TAG, socketId);
150 return DH_SUCCESS;
151 }
152
RemoveSoftbusSessionServer(const std::string & pkgname,const std::string & sessionName,const std::string & peerDevId)153 int32_t SoftbusAdapter::RemoveSoftbusSessionServer(const std::string &pkgname, const std::string &sessionName,
154 const std::string &peerDevId)
155 {
156 (void)pkgname;
157 if (sessionName.empty() || peerDevId.empty()) {
158 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
159 }
160 DHLOGI("%{public}s: RemoveSessionServer sess:%{public}s id:%{public}s", DSCREEN_LOG_TAG, sessionName.c_str(),
161 GetAnonyString(peerDevId).c_str());
162 int32_t serverSocketId = INVALID_SESSION_ID;
163 {
164 std::lock_guard<std::mutex> lock(serverIdMapMutex_);
165 std::string idMapValue = sessionName + "_" + peerDevId;
166 for (auto it = serverIdMap_.begin(); it != serverIdMap_.end();) {
167 if (((it->second).find(idMapValue) != std::string::npos)) {
168 serverSocketId = it->first;
169 it = serverIdMap_.erase(it);
170 } else {
171 ++it;
172 }
173 }
174 }
175 Shutdown(serverSocketId);
176 DHLOGI("%{public}s: RemoveSessionServer success.", DSCREEN_LOG_TAG);
177 return DH_SUCCESS;
178 }
179
OpenSoftbusSession(const std::string & mySessionName,const std::string & peerSessionName,const std::string & peerDevId)180 int32_t SoftbusAdapter::OpenSoftbusSession(const std::string &mySessionName, const std::string &peerSessionName,
181 const std::string &peerDevId)
182 {
183 DHLOGI("%{public}s: OpenSoftbusSession mysess:%{public}s peersess:%{public}s id:%{public}s.", DSCREEN_LOG_TAG,
184 mySessionName.c_str(), peerSessionName.c_str(), GetAnonyString(peerDevId).c_str());
185
186 QosTV qos[] = {
187 {.qos = QOS_TYPE_MIN_BW, .value = 40 * 1024 * 1024},
188 {.qos = QOS_TYPE_MAX_LATENCY, .value = 8000},
189 {.qos = QOS_TYPE_MIN_LATENCY, .value = 2000},
190 };
191 std::string localSesionName = mySessionName + "_" + std::to_string(GetCurrentTimeUs());
192 SocketInfo clientInfo = {
193 .name = const_cast<char*>((localSesionName.c_str())),
194 .peerName = const_cast<char*>(peerSessionName.c_str()),
195 .peerNetworkId = const_cast<char*>(peerDevId.c_str()),
196 .pkgName = const_cast<char*>(PKG_NAME.c_str()),
197 .dataType = DATA_TYPE_VIDEO_STREAM,
198 };
199 int32_t socketId = Socket(clientInfo);
200 if (socketId < 0) {
201 DHLOGE("Create OpenSoftbusChannel Socket error");
202 return ERR_DH_SCREEN_ADAPTER_PARA_ERROR;
203 }
204 int32_t ret = Bind(socketId, qos, sizeof(qos) / sizeof(qos[0]), &sessListener_);
205 if (ret != DH_SUCCESS) {
206 DHLOGE("Bind SocketClient error");
207 return ERR_DH_SCREEN_ADAPTER_PARA_ERROR;
208 }
209 {
210 std::lock_guard<std::mutex> lock(idMapMutex_);
211 devId2SessIdMap_.insert(std::make_pair(socketId, mySessionName + "_" + peerDevId));
212 }
213 std::shared_ptr<ISoftbusListener> &listener = GetSoftbusListenerByName(socketId);
214 if (listener == nullptr) {
215 DHLOGE("Get softbus listener failed.");
216 return ERR_DH_SCREEN_TRANS_ERROR;
217 }
218 PeerSocketInfo info;
219 ret = OnSoftbusSessionOpened(socketId, info);
220 if (ret != DH_SUCCESS) {
221 return ret;
222 }
223 DHLOGI("%{public}s: OpenSoftbusSession success sessionId: %{public}" PRId32, DSCREEN_LOG_TAG, socketId);
224 return socketId;
225 }
226
CloseSoftbusSession(const int32_t sessionId)227 int32_t SoftbusAdapter::CloseSoftbusSession(const int32_t sessionId)
228 {
229 DHLOGI("%{public}s: CloseSoftbusSession, sessid:%{public}" PRId32, DSCREEN_LOG_TAG, sessionId);
230 Shutdown(sessionId);
231 {
232 std::lock_guard<std::mutex> lock(idMapMutex_);
233 devId2SessIdMap_.erase(sessionId);
234 }
235 std::lock_guard<std::mutex> lisLock(listenerMtx_);
236 mapSessListeners_.erase(sessionId);
237
238 DHLOGI("%{public}s: CloseSoftbusSession success.", DSCREEN_LOG_TAG);
239 return DH_SUCCESS;
240 }
241
SendSoftbusBytes(int32_t sessionId,const void * data,int32_t dataLen) const242 int32_t SoftbusAdapter::SendSoftbusBytes(int32_t sessionId, const void *data, int32_t dataLen) const
243 {
244 DHLOGD("%{public}s: SendSoftbusBytes, sessid:%{public}" PRId32, DSCREEN_LOG_TAG, sessionId);
245 int32_t ret = SendBytes(sessionId, data, dataLen);
246 if (ret != DH_SUCCESS) {
247 DHLOGE("%{public}s: SendBytes failed ret:%{public}" PRId32, DSCREEN_LOG_TAG, ret);
248 return ERR_DH_SCREEN_TRANS_ERROR;
249 }
250
251 return DH_SUCCESS;
252 }
253
SendSoftbusStream(int32_t sessionId,const StreamData * data,const StreamData * ext,const StreamFrameInfo * param) const254 int32_t SoftbusAdapter::SendSoftbusStream(int32_t sessionId, const StreamData *data, const StreamData *ext,
255 const StreamFrameInfo *param) const
256 {
257 DHLOGD("%{public}s: SendSoftbusStream, sessid:%{public}" PRId32, DSCREEN_LOG_TAG, sessionId);
258 int32_t ret = SendStream(sessionId, data, ext, param);
259 if (ret != DH_SUCCESS) {
260 DHLOGE("%{public}s: SendStream failed ret:%{public}" PRId32, DSCREEN_LOG_TAG, ret);
261 return ERR_DH_SCREEN_TRANS_ERROR;
262 }
263
264 return DH_SUCCESS;
265 }
266
GetSoftbusListenerByName(int32_t sessionId)267 std::shared_ptr<ISoftbusListener> &SoftbusAdapter::GetSoftbusListenerByName(int32_t sessionId)
268 {
269 DHLOGD("%{public}s: GetSoftbusListenerByName, sessionId:%{public}" PRId32, DSCREEN_LOG_TAG, sessionId);
270 std::string strListenerKey = "";
271 {
272 std::lock_guard<std::mutex> lock(idMapMutex_);
273 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end(); it++) {
274 if (it->first == sessionId) {
275 strListenerKey = it->second;
276 break;
277 }
278 }
279 }
280 std::lock_guard<std::mutex> lisLock(listenerMtx_);
281 if (mapListeners_.find(strListenerKey) == mapListeners_.end()) {
282 DHLOGE("%{public}s: Find listener failed.", DSCREEN_LOG_TAG);
283 return nullListener_;
284 }
285 return mapListeners_[strListenerKey];
286 }
287
GetSoftbusListenerById(int32_t sessionId)288 std::shared_ptr<ISoftbusListener> &SoftbusAdapter::GetSoftbusListenerById(int32_t sessionId)
289 {
290 std::lock_guard<std::mutex> lisLock(listenerMtx_);
291 if (mapSessListeners_.find(sessionId) == mapSessListeners_.end()) {
292 DHLOGE("%{public}s: Find listener failed.", DSCREEN_LOG_TAG);
293 return nullListener_;
294 }
295
296 return mapSessListeners_[sessionId];
297 }
298
OnSoftbusSessionOpened(int32_t sessionId,PeerSocketInfo info)299 int32_t SoftbusAdapter::OnSoftbusSessionOpened(int32_t sessionId, PeerSocketInfo info)
300 {
301 DHLOGI("%{public}s: OnSoftbusSessionOpened session:%{public}" PRId32, DSCREEN_LOG_TAG, sessionId);
302 {
303 std::lock_guard<std::mutex> lock(serverIdMapMutex_);
304 for (auto it = serverIdMap_.begin(); it != serverIdMap_.end(); it++) {
305 if (info.networkId == nullptr) {
306 break;
307 }
308 std::string peerDevId(info.networkId);
309 if ((it->second).find(peerDevId) != std::string::npos) {
310 std::lock_guard<std::mutex> sessionLock(idMapMutex_);
311 devId2SessIdMap_.insert(std::make_pair(sessionId, it->second));
312 break;
313 }
314 }
315 }
316
317 std::shared_ptr<ISoftbusListener> &listener = GetSoftbusListenerByName(sessionId);
318 if (listener == nullptr) {
319 DHLOGE("Get softbus listener failed.");
320 return ERR_DH_SCREEN_TRANS_ERROR;
321 }
322 listener->OnSessionOpened(sessionId, info);
323
324 std::lock_guard<std::mutex> lisLock(listenerMtx_);
325 mapSessListeners_.insert(std::make_pair(sessionId, listener));
326
327 return DH_SUCCESS;
328 }
329
OnSoftbusSessionClosed(int32_t sessionId,ShutdownReason reason)330 void SoftbusAdapter::OnSoftbusSessionClosed(int32_t sessionId, ShutdownReason reason)
331 {
332 DHLOGI("%{public}s: OnSessionClosed sessionId:%{public}" PRId32, DSCREEN_LOG_TAG, sessionId);
333 std::shared_ptr<ISoftbusListener> &listener = GetSoftbusListenerById(sessionId);
334 if (listener == nullptr) {
335 DHLOGE("Get softbus listener failed.");
336 return;
337 }
338 listener->OnSessionClosed(sessionId, reason);
339 {
340 std::lock_guard<std::mutex> lock(idMapMutex_);
341 devId2SessIdMap_.erase(sessionId);
342 }
343 std::lock_guard<std::mutex> lisLock(listenerMtx_);
344 mapSessListeners_.erase(sessionId);
345 }
346
OnBytesReceived(int32_t sessionId,const void * data,uint32_t dataLen)347 void SoftbusAdapter::OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen)
348 {
349 DHLOGD("%{public}s: OnBytesReceived, sessionId:%{public}" PRId32, DSCREEN_LOG_TAG, sessionId);
350 if (data == nullptr) {
351 DHLOGE("BytesData is null.");
352 return;
353 }
354 if (dataLen == 0 || dataLen > DSCREEN_MAX_RECV_DATA_LEN) {
355 DHLOGE("BytesData length is too large, dataLen:%{public}" PRIu32, dataLen);
356 return;
357 }
358
359 std::shared_ptr<ISoftbusListener> &listener = GetSoftbusListenerByName(sessionId);
360 if (listener == nullptr) {
361 DHLOGE("Get softbus listener failed.");
362 return;
363 }
364 listener->OnBytesReceived(sessionId, data, dataLen);
365 }
366
OnStreamReceived(int32_t sessionId,const StreamData * data,const StreamData * ext,const StreamFrameInfo * frameInfo)367 void SoftbusAdapter::OnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext,
368 const StreamFrameInfo *frameInfo)
369 {
370 DHLOGD("%{public}s OnStreamReceived, sessionId:%{public}" PRId32, DSCREEN_LOG_TAG, sessionId);
371 if (data == nullptr) {
372 DHLOGE("StreamData is null.");
373 return;
374 }
375 if (data->bufLen <= 0 || data->bufLen > static_cast<int32_t>(DSCREEN_MAX_RECV_DATA_LEN)) {
376 DHLOGE("StreamData length is too large, dataLen:%{public}" PRId32, data->bufLen);
377 return;
378 }
379
380 std::shared_ptr<ISoftbusListener> &listener = GetSoftbusListenerByName(sessionId);
381 if (listener == nullptr) {
382 DHLOGE("Get softbus listener failed.");
383 return;
384 }
385 listener->OnStreamReceived(sessionId, data, ext, frameInfo);
386 }
387
OnMessageReceived(int sessionId,const void * data,unsigned int dataLen) const388 void SoftbusAdapter::OnMessageReceived(int sessionId, const void *data, unsigned int dataLen) const
389 {
390 (void)data;
391 (void)dataLen;
392 DHLOGD("%{public}s OnMessageReceived, sessionId:%{public}" PRId32, DSCREEN_LOG_TAG, sessionId);
393 }
394 } // namespace DistributedHardware
395 } // namespace OHOS