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