• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 "databus_socket_listener.h"
17 
18 #include "dbinder_databus_invoker.h"
19 #include "dsoftbus_interface.h"
20 #include "ipc_debug.h"
21 #include "ipc_process_skeleton.h"
22 #include "ipc_thread_skeleton.h"
23 #include "log_tags.h"
24 
25 namespace OHOS {
26 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_RPC_REMOTE_LISTENER, "DatabusSocketListener" };
27 
DBinderSocketInfo(const std::string & ownName,const std::string & peerName,const std::string & networkId)28 DBinderSocketInfo::DBinderSocketInfo(const std::string &ownName, const std::string &peerName,
29     const std::string &networkId)
30     : ownName_(ownName), peerName_(peerName), networkId_(networkId)
31 {
32 }
33 
GetOwnName() const34 std::string DBinderSocketInfo::GetOwnName() const
35 {
36     return ownName_;
37 }
38 
GetPeerName() const39 std::string DBinderSocketInfo::GetPeerName() const
40 {
41     return peerName_;
42 }
43 
GetNetworkId() const44 std::string DBinderSocketInfo::GetNetworkId() const
45 {
46     return networkId_;
47 }
48 
DatabusSocketListener()49 DatabusSocketListener::DatabusSocketListener()
50 {
51     serverListener_.OnBind = DatabusSocketListener::ServerOnBind;
52     serverListener_.OnShutdown = DatabusSocketListener::ServerOnShutdown;
53     serverListener_.OnBytes = DatabusSocketListener::OnBytesReceived;
54     serverListener_.OnMessage = DatabusSocketListener::OnBytesReceived;
55 
56     clientListener_.OnBind = DatabusSocketListener::ClientOnBind;
57     clientListener_.OnShutdown = DatabusSocketListener::ClientOnShutdown;
58     clientListener_.OnBytes = DatabusSocketListener::OnBytesReceived;
59     clientListener_.OnMessage = DatabusSocketListener::OnBytesReceived;
60 }
61 
~DatabusSocketListener()62 DatabusSocketListener::~DatabusSocketListener() {}
63 
ServerOnBind(int32_t socket,PeerSocketInfo info)64 void DatabusSocketListener::ServerOnBind(int32_t socket, PeerSocketInfo info)
65 {
66     ZLOGI(LABEL, "socketId:%{public}d, deviceId:%{public}s, peerName:%{public}s", socket,
67         IPCProcessSkeleton::ConvertToSecureString(info.networkId).c_str(), info.name);
68 
69     std::string networkId = info.networkId;
70     std::string peerName = info.name;
71     std::string str = peerName.substr(DBINDER_SOCKET_NAME_PREFIX.length());
72     std::string::size_type pos = str.find("_");
73     std::string peerUid = str.substr(0, pos);
74     std::string peerPid = str.substr(pos + 1);
75     if ((peerUid.length() > INT_STRING_MAX_LEN) || (peerPid.length() > INT_STRING_MAX_LEN) ||
76         !ProcessSkeleton::IsNumStr(peerUid) || !ProcessSkeleton::IsNumStr(peerPid)) {
77         ZLOGE(LOG_LABEL, "peerUid:%{public}s or peerPid:%{public}s is invalid", peerUid.c_str(), peerPid.c_str());
78         return;
79     }
80     DBinderDatabusInvoker *invoker =
81         reinterpret_cast<DBinderDatabusInvoker *>(IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS));
82     if (invoker == nullptr) {
83         ZLOGE(LABEL, "fail to get invoker");
84         return;
85     }
86 
87     invoker->OnReceiveNewConnection(socket, std::stoi(peerPid), std::stoi(peerUid), peerName, networkId);
88 }
89 
ServerOnShutdown(int32_t socket,ShutdownReason reason)90 void DatabusSocketListener::ServerOnShutdown(int32_t socket, ShutdownReason reason)
91 {
92     ZLOGI(LABEL, "socketId:%{public}d, ShutdownReason:%{public}d", socket, reason);
93     DBinderDatabusInvoker *invoker =
94         reinterpret_cast<DBinderDatabusInvoker *>(IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS));
95     if (invoker == nullptr) {
96         ZLOGE(LABEL, "fail to get invoker");
97         return;
98     }
99     invoker->OnDatabusSessionServerSideClosed(socket);
100 }
101 
ClientOnBind(int32_t socket,PeerSocketInfo info)102 void DatabusSocketListener::ClientOnBind(int32_t socket, PeerSocketInfo info)
103 {
104     return;
105 }
106 
ClientOnShutdown(int32_t socket,ShutdownReason reason)107 void DatabusSocketListener::ClientOnShutdown(int32_t socket, ShutdownReason reason)
108 {
109     ZLOGI(LABEL, "socketId:%{public}d, ShutdownReason:%{public}d", socket, reason);
110     DBinderDatabusInvoker *invoker =
111         reinterpret_cast<DBinderDatabusInvoker *>(IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS));
112     if (invoker == nullptr) {
113         ZLOGE(LABEL, "fail to get invoker");
114         return;
115     }
116 
117     DBinderSocketInfo socketInfo;
118     {
119         std::lock_guard<std::mutex> lockGuard(socketInfoMutex_);
120         for (auto it = socketInfoMap_.begin(); it != socketInfoMap_.end(); it++) {
121             if (it->second == socket) {
122                 socketInfo = it->first;
123                 ZLOGI(LOG_LABEL, "erase socketId:%{public}d ", it->second);
124                 socketInfoMap_.erase(it);
125                 break;
126             }
127         }
128     }
129     EraseDeviceLock(socketInfo);
130     invoker->OnDatabusSessionClientSideClosed(socket);
131 }
132 
OnBytesReceived(int32_t socket,const void * data,uint32_t dataLen)133 void DatabusSocketListener::OnBytesReceived(int32_t socket, const void *data, uint32_t dataLen)
134 {
135     ZLOGI(LABEL, "socketId:%{public}d len:%{public}u", socket, dataLen);
136     DBinderDatabusInvoker *invoker =
137         reinterpret_cast<DBinderDatabusInvoker *>(IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS));
138     if (invoker == nullptr) {
139         ZLOGE(LABEL, "fail to get invoker");
140         return;
141     }
142 
143     invoker->OnMessageAvailable(socket, static_cast<const char*>(data), dataLen);
144 }
145 
StartServerListener(const std::string & ownName)146 int32_t DatabusSocketListener::StartServerListener(const std::string &ownName)
147 {
148     std::string pkgName = DBINDER_PKG_NAME + "_" + std::to_string(getpid());
149 
150     SocketInfo serverSocketInfo = {
151         .name = const_cast<char*>(ownName.c_str()),
152         .pkgName = const_cast<char*>(pkgName.c_str()),
153         .dataType = TransDataType::DATA_TYPE_BYTES,
154     };
155     int32_t socketId = DBinderSoftbusClient::GetInstance().Socket(serverSocketInfo);
156     if (socketId <= 0) {
157         ZLOGE(LABEL, "create socket server error, socket is invalid");
158         return SOCKET_ID_INVALID;
159     }
160     int32_t ret = DBinderSoftbusClient::GetInstance().Listen(socketId, QOS_TV, QOS_COUNT, &serverListener_);
161     if (ret != SOFTBUS_OK && ret != SOFTBUS_TRANS_SOCKET_IN_USE) {
162         ZLOGE(LABEL, "Listen failed, ret:%{public}d", ret);
163         DBinderSoftbusClient::GetInstance().Shutdown(socketId);
164         return SOCKET_ID_INVALID;
165     }
166     ZLOGI(LABEL, "Listen ok, socketId:%{public}d, ownName:%{public}s", socketId, ownName.c_str());
167     return socketId;
168 }
169 
QueryOrNewInfoMutex(DBinderSocketInfo socketInfo)170 std::shared_ptr<std::mutex> DatabusSocketListener::QueryOrNewInfoMutex(DBinderSocketInfo socketInfo)
171 {
172     std::lock_guard<std::mutex> lockGuard(deviceMutex_);
173     auto it = infoMutexMap_.find(socketInfo);
174     if (it != infoMutexMap_.end()) {
175         return it->second;
176     }
177     std::shared_ptr<std::mutex> infoMutex = std::make_shared<std::mutex>();
178     if (infoMutex == nullptr) {
179         ZLOGE(LOG_LABEL, "failed to create mutex, ownName:%{public}s, peerName:%{public}s, networkId:%{public}s",
180             socketInfo.GetOwnName().c_str(), socketInfo.GetPeerName().c_str(),
181             IPCProcessSkeleton::ConvertToSecureString(socketInfo.GetNetworkId()).c_str());
182         return nullptr;
183     }
184     infoMutexMap_[socketInfo] = infoMutex;
185     return infoMutex;
186 }
187 
CreateClientSocket(const std::string & ownName,const std::string & peerName,const std::string & networkId)188 int32_t DatabusSocketListener::CreateClientSocket(const std::string &ownName, const std::string &peerName,
189     const std::string &networkId)
190 {
191     DBinderSocketInfo info(ownName, peerName, networkId);
192     std::shared_ptr<std::mutex> infoMutex = QueryOrNewInfoMutex(info);
193     if (infoMutex == nullptr) {
194         return SOCKET_ID_INVALID;
195     }
196     std::lock_guard<std::mutex> lockUnique(*infoMutex);
197 
198     {
199         std::lock_guard<std::mutex> lockGuard(socketInfoMutex_);
200         auto it = socketInfoMap_.find(info);
201         if (it != socketInfoMap_.end()) {
202             return it->second;
203         }
204     }
205 
206     std::string pkgName = std::string(DBINDER_PKG_NAME) + "_" + std::to_string(getpid());
207     SocketInfo socketInfo = {
208         .name = const_cast<char*>(ownName.c_str()),
209         .peerName = const_cast<char*>(peerName.c_str()),
210         .peerNetworkId = const_cast<char*>(networkId.c_str()),
211         .pkgName = const_cast<char*>(pkgName.c_str()),
212         .dataType = TransDataType::DATA_TYPE_BYTES,
213     };
214     int32_t socketId = DBinderSoftbusClient::GetInstance().Socket(socketInfo);
215     if (socketId <= 0) {
216         ZLOGE(LABEL, "create socket error, socket is invalid");
217         return SOCKET_ID_INVALID;
218     }
219     int32_t ret = DBinderSoftbusClient::GetInstance().Bind(socketId, QOS_TV, QOS_COUNT, &clientListener_);
220     if (ret != SOFTBUS_OK && ret != SOFTBUS_TRANS_SOCKET_IN_USE) {
221         ZLOGE(LABEL, "Bind failed, ret:%{public}d, socketId:%{public}d,"
222             "ownName:%{public}s, peerName:%{public}s, peerNetworkId:%{public}s",
223             ret, socketId, ownName.c_str(), peerName.c_str(),
224             IPCProcessSkeleton::ConvertToSecureString(networkId).c_str());
225         DBinderSoftbusClient::GetInstance().Shutdown(socketId);
226         EraseDeviceLock(info);
227         return SOCKET_ID_INVALID;
228     }
229     ZLOGI(LABEL, "Bind succ, ownName:%{public}s peer:%{public}s deviceId:%{public}s socketId:%{public}d",
230         ownName.c_str(), peerName.c_str(), IPCProcessSkeleton::ConvertToSecureString(networkId).c_str(), socketId);
231     {
232         std::lock_guard<std::mutex> lockGuard(socketInfoMutex_);
233         socketInfoMap_[info] = socketId;
234     }
235     return socketId;
236 }
237 
ShutdownSocket(int32_t socketId)238 void DatabusSocketListener::ShutdownSocket(int32_t socketId)
239 {
240     DBinderSocketInfo socketInfo;
241     {
242         std::lock_guard<std::mutex> lockGuard(socketInfoMutex_);
243         for (auto it = socketInfoMap_.begin(); it != socketInfoMap_.end(); it++) {
244             if (it->second == socketId) {
245                 ZLOGI(LOG_LABEL, "Shutdown socketId:%{public}d ", it->second);
246                 DBinderSoftbusClient::GetInstance().Shutdown(it->second);
247                 socketInfo = it->first;
248                 it = socketInfoMap_.erase(it);
249                 break;
250             }
251         }
252     }
253     EraseDeviceLock(socketInfo);
254 }
255 
EraseDeviceLock(DBinderSocketInfo info)256 void DatabusSocketListener::EraseDeviceLock(DBinderSocketInfo info)
257 {
258     std::lock_guard<std::mutex> lockGuard(deviceMutex_);
259     auto it = infoMutexMap_.find(info);
260     if (it != infoMutexMap_.end()) {
261         infoMutexMap_.erase(it);
262     }
263 }
264 
RemoveSessionName(void)265 void DatabusSocketListener::RemoveSessionName(void)
266 {
267     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
268     if (current == nullptr) {
269         ZLOGE(LABEL, "get current is null");
270         return;
271     }
272     sptr<IRemoteObject> object = current->GetSAMgrObject();
273     if (object == nullptr) {
274         ZLOGE(LABEL, "get object is null");
275         return;
276     }
277 
278     IPCObjectProxy *samgr = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
279     const std::string sessionName = current->GetDatabusName();
280     samgr->RemoveSessionName(sessionName);
281     ZLOGI(LABEL, "%{public}s", sessionName.c_str());
282 }
283 } // namespace OHOS
284