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 28namespace OHOS { 29namespace DistributedHardware { 30IMPLEMENT_SINGLE_INSTANCE(SoftbusAdapter); 31static void ScreenOnSoftbusSessionOpened(int32_t sessionId, PeerSocketInfo info) 32{ 33 SoftbusAdapter::GetInstance().OnSoftbusSessionOpened(sessionId, info); 34} 35 36static void ScreenOnSoftbusSessionClosed(int32_t sessionId, ShutdownReason reason) 37{ 38 SoftbusAdapter::GetInstance().OnSoftbusSessionClosed(sessionId, reason); 39} 40 41static void ScreenOnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) 42{ 43 SoftbusAdapter::GetInstance().OnBytesReceived(sessionId, data, dataLen); 44} 45 46static 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 52static void ScreenOnMessageReceived(int sessionId, const void *data, unsigned int dataLen) 53{ 54 SoftbusAdapter::GetInstance().OnMessageReceived(sessionId, data, dataLen); 55} 56 57SoftbusAdapter::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 71SoftbusAdapter::~SoftbusAdapter() 72{ 73 DHLOGI("~SoftbusAdapter"); 74} 75 76int32_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 96int32_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 108int32_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 153int32_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 180int32_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 227int32_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 242int32_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 254int32_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 267std::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 288std::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 299int32_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 330void 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 347void 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 367void 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 388void 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