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