/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "session_service_impl.h" #include "session_impl.h" #include "session_mock.h" #include "softbus_bus_center.h" #include "softbus_def.h" #include "softbus_errcode.h" #include "softbus_log.h" namespace Communication { namespace SoftBus { std::shared_mutex ISessionService::instanceMutex_; std::shared_ptr<ISessionService> ISessionService::instance_ = nullptr; std::mutex SessionServiceImpl::listenerMutex_; std::map<std::string, std::shared_ptr<ISessionListener>> SessionServiceImpl::listenerMap_; std::mutex SessionServiceImpl::sessionMutex_; std::map<int, std::shared_ptr<Session>> SessionServiceImpl::sessionMap_; std::shared_ptr<ISessionService> ISessionService::GetInstance() { std::shared_ptr<ISessionService> tmp = instance_; if (tmp == nullptr) { std::unique_lock<std::shared_mutex> instanceLock(instanceMutex_); tmp = instance_; if (tmp == nullptr) { tmp = std::make_shared<SessionServiceImpl>(); instance_ = tmp; } } return instance_; } int SessionServiceImpl::CreateSessionServer(const std::string &pkgName, const std::string &sessionName, std::shared_ptr<ISessionListener> listener) { if (pkgName.empty() || sessionName.empty() || listener == nullptr) { SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "SessionServiceImpl:CreateSessionServer, invalid parameter"); return SOFTBUS_ERR; } std::lock_guard<std::mutex> autoLock(listenerMutex_); int ret = CreateSessionServerInner(pkgName.c_str(), sessionName.c_str()); if (ret == SOFTBUS_OK) { listenerMap_.insert(std::pair<std::string, std::shared_ptr<ISessionListener>>(sessionName, listener)); } return ret; } int SessionServiceImpl::RemoveSessionServer(const std::string &pkgName, const std::string &sessionName) { if (pkgName.empty() || sessionName.empty()) { SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "SessionServiceImpl:RemoveSessionServer, invalid parameter"); return SOFTBUS_ERR; } std::lock_guard<std::mutex> autoLock(listenerMutex_); auto iter = listenerMap_.find(sessionName); if (iter != listenerMap_.end()) { listenerMap_.erase(iter); return RemoveSessionServerInner(pkgName.c_str(), sessionName.c_str()); } SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "SessionServiceImpl:RemoveSessionServer, not find session server"); return SOFTBUS_ERR; } std::shared_ptr<Session> SessionServiceImpl::OpenSession(const std::string &mySessionName, const std::string &peerSessionName, const std::string &peerDeviceId, const std::string &groupId, int flags) { SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "SessionServiceImpl::OpenSession"); if (mySessionName.empty() || peerSessionName.empty() || peerDeviceId.empty()) { return nullptr; } int sessionId = OpenSessionInner(mySessionName.c_str(), peerSessionName.c_str(), peerDeviceId.c_str(), groupId.c_str(), flags); if (sessionId <= 0) { SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "SessionServiceImpl:OpenSession, invalid sessionId."); return nullptr; } std::shared_ptr<Session> session; std::lock_guard<std::mutex> autoLock(sessionMutex_); auto iter = sessionMap_.find(sessionId); if (iter != sessionMap_.end()) { session = iter->second; SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "SessionServiceImpl::Session Find"); } SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "SessionServiceImpl::OpenSession ok"); return session; } int SessionServiceImpl::CloseSession(std::shared_ptr<Session> session) { if (session == nullptr) { SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "SessionServiceImpl:CloseSession, invalid parameter"); return SOFTBUS_ERR; } int sessionId = session->GetSessionId(); if (sessionId <= 0) { SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "SessionServiceImpl:OpenSession, invalid sessionId."); return SOFTBUS_ERR; } CloseSessionInner(sessionId); std::lock_guard<std::mutex> autoLock(sessionMutex_); auto iter = sessionMap_.find(sessionId); if (iter != sessionMap_.end()) { sessionMap_.erase(sessionId); } return SOFTBUS_OK; } int SessionServiceImpl::GrantPermission(int uid, int pid, const std::string &busName) { if (uid < 0 || pid < 0 || busName.empty()) { SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "SessionServiceImpl:GrantPermission, invalid parameter"); return SOFTBUS_ERR; } return SOFTBUS_OK; } int SessionServiceImpl::CreatNewSession(int sessionId) { std::shared_ptr<Session> session = std::make_shared<SessionImpl>(); session->SetSessionId(sessionId); char str[SESSION_NAME_SIZE_MAX]; int ret = GetMySessionNameInner(sessionId, str, SESSION_NAME_SIZE_MAX); if (ret != SOFTBUS_OK) { return ret; } std::string mySessionName(str); session->SetMySessionName(mySessionName); ret = GetPeerSessionNameInner(sessionId, str, SESSION_NAME_SIZE_MAX); if (ret != SOFTBUS_OK) { return ret; } std::string peerSessionName(str); session->SetPeerSessionName(peerSessionName); ret = GetPeerDeviceIdInner(sessionId, str, SESSION_NAME_SIZE_MAX); if (ret != SOFTBUS_OK) { return ret; } std::string peerDevId(str); session->SetPeerDeviceId(peerDevId); session->SetIsServer(true); std::lock_guard<std::mutex> autoLock(sessionMutex_); sessionMap_.insert(std::pair<int, std::shared_ptr<Session>>(sessionId, session)); return SOFTBUS_OK; } int SessionServiceImpl::OpenSessionCallback(int sessionId) { SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "SessionServiceImpl::OpenSessionCallback"); int isServer; if (IsServerSideInner(sessionId, &isServer) != SOFTBUS_OK) { return SOFTBUS_ERR; } std::shared_ptr<Session> session = std::make_shared<SessionImpl>(); session->SetSessionId(sessionId); char str[SESSION_NAME_SIZE_MAX]; if (GetMySessionNameInner(sessionId, str, SESSION_NAME_SIZE_MAX) != SOFTBUS_OK) { return SOFTBUS_ERR; } std::string mySessionName(str); session->SetMySessionName(mySessionName); if (GetPeerSessionNameInner(sessionId, str, SESSION_NAME_SIZE_MAX) != SOFTBUS_OK) { return SOFTBUS_ERR; } std::string peerSessionName(str); session->SetPeerSessionName(peerSessionName); char deviceId[DEVICE_ID_SIZE_MAX]; if (GetPeerDeviceIdInner(sessionId, deviceId, DEVICE_ID_SIZE_MAX) != SOFTBUS_OK) { return SOFTBUS_ERR; } std::string peerDeviceId(deviceId); session->SetPeerDeviceId(peerDeviceId); session->SetIsServer(isServer); std::lock_guard<std::mutex> autoLock(sessionMutex_); sessionMap_.insert(std::pair<int, std::shared_ptr<Session>>(sessionId, session)); std::shared_ptr<ISessionListener> listener; if (GetSessionListenerOnSessionOpened(sessionId, listener, session) != SOFTBUS_OK) { SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "OpenSessionCallback get session listener failed"); return SOFTBUS_ERR; } NodeBasicInfo info; char pkgName[PKG_NAME_SIZE_MAX]; if (GetPkgNameInner(sessionId, pkgName, PKG_NAME_SIZE_MAX) != SOFTBUS_OK) { return SOFTBUS_ERR; } if (GetLocalNodeDeviceInfo(pkgName, &info) != SOFTBUS_OK) { return SOFTBUS_ERR; } session->SetDeviceId(info.networkId); int tmp; if (GetPeerUidInner(sessionId, &tmp) != SOFTBUS_OK) { return SOFTBUS_ERR; } session->SetPeerUid(static_cast<uid_t>(tmp)); if (GetPeerPidInner(sessionId, &tmp) != SOFTBUS_OK) { return SOFTBUS_ERR; } session->SetPeerPid(static_cast<pid_t>(tmp)); SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "SessionServiceImpl::OpenSessionCallback Ok"); return listener->OnSessionOpened(session); } void SessionServiceImpl::CloseSessionCallback(int sessionId) { std::shared_ptr<ISessionListener> listener; std::shared_ptr<Session> session; if (GetSessionListener(sessionId, listener, session) != SOFTBUS_OK) { return; } listener->OnSessionClosed(session); } void SessionServiceImpl::BytesReceivedCallback(int sessionId, const void *data, unsigned int len) { std::shared_ptr<ISessionListener> listener; std::shared_ptr<Session> session; if (GetSessionListener(sessionId, listener, session) != SOFTBUS_OK) { return; } const char *msg = static_cast<const char *>(data); ssize_t lenMsg = static_cast<ssize_t>(len); listener->OnBytesReceived(session, msg, lenMsg); } void SessionServiceImpl::MessageReceivedCallback(int sessionId, const void *data, unsigned int len) { std::shared_ptr<ISessionListener> listener; std::shared_ptr<Session> session; if (GetSessionListener(sessionId, listener, session) != SOFTBUS_OK) { return; } const char *msg = static_cast<const char *>(data); ssize_t lenMsg = static_cast<ssize_t>(len); listener->OnMessageReceived(session, msg, lenMsg); } int SessionServiceImpl::GetSessionListener(int sessionId, std::shared_ptr<ISessionListener> &listener, std::shared_ptr<Session> &session) { std::lock_guard<std::mutex> autoLock(sessionMutex_); auto iter = sessionMap_.find(sessionId); if (iter != sessionMap_.end()) { session = iter->second; std::lock_guard<std::mutex> autoLock(listenerMutex_); auto iterListener = listenerMap_.find(session->GetMySessionName()); if (iterListener != listenerMap_.end()) { listener = iterListener->second; return SOFTBUS_OK; } } return SOFTBUS_ERR; } int SessionServiceImpl::GetSessionListenerOnSessionOpened(int sessionId, std::shared_ptr<ISessionListener> &listener, std::shared_ptr<Session> &session) { (void)session; char str[SESSION_NAME_SIZE_MAX]; if (GetMySessionNameInner(sessionId, str, SESSION_NAME_SIZE_MAX) != SOFTBUS_OK) { return SOFTBUS_ERR; } std::string mySessionName(str); std::lock_guard<std::mutex> autoLock(listenerMutex_); auto iterListener = listenerMap_.find(mySessionName); if (iterListener != listenerMap_.end()) { listener = iterListener->second; return SOFTBUS_OK; } return SOFTBUS_ERR; } } // namespace SoftBus } // namespace Communication