1 /*
2 * Copyright (C) 2021 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 "dbinder_remote_listener.h"
17
18 #include <cinttypes>
19 #include "securec.h"
20
21 #include "dbinder_error_code.h"
22 #include "dbinder_log.h"
23 #include "ipc_types.h"
24 #include "softbus_error_code.h"
25
26 namespace OHOS {
27 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC_REMOTE_LISTENER,
28 "DbinderRemoteListener" };
29
DBinderRemoteListener()30 DBinderRemoteListener::DBinderRemoteListener()
31 {
32 DBINDER_LOGI(LOG_LABEL, "create dbinder remote listener");
33
34 clientListener_.OnBind = DBinderRemoteListener::ClientOnBind;
35 clientListener_.OnShutdown = DBinderRemoteListener::ClientOnShutdown;
36 clientListener_.OnBytes = DBinderRemoteListener::OnBytesReceived;
37 clientListener_.OnMessage = DBinderRemoteListener::OnBytesReceived;
38
39 serverListener_.OnBind = DBinderRemoteListener::ServerOnBind;
40 serverListener_.OnShutdown = DBinderRemoteListener::ServerOnShutdown;
41 serverListener_.OnBytes = DBinderRemoteListener::OnBytesReceived;
42 serverListener_.OnMessage = DBinderRemoteListener::OnBytesReceived;
43 }
44
~DBinderRemoteListener()45 DBinderRemoteListener::~DBinderRemoteListener()
46 {
47 DBINDER_LOGI(LOG_LABEL, "delete dbinder remote listener");
48 }
49
ServerOnBind(int32_t socket,PeerSocketInfo info)50 void DBinderRemoteListener::ServerOnBind(int32_t socket, PeerSocketInfo info)
51 {
52 DBINDER_LOGI(LOG_LABEL, "socketId:%{public}d, peerNetworkId:%{public}s, peerName:%{public}s",
53 socket, DBinderService::ConvertToSecureDeviceID(info.networkId).c_str(), info.name);
54 std::lock_guard<std::mutex> lockGuard(serverSocketMutex_);
55 serverSocketInfos_[info.networkId] = socket;
56 return;
57 }
58
ServerOnShutdown(int32_t socket,ShutdownReason reason)59 void DBinderRemoteListener::ServerOnShutdown(int32_t socket, ShutdownReason reason)
60 {
61 DBINDER_LOGI(LOG_LABEL, "socketId:%{public}d, ShutdownReason:%{public}d", socket, reason);
62 std::lock_guard<std::mutex> lockGuard(serverSocketMutex_);
63 for (auto it = serverSocketInfos_.begin(); it != serverSocketInfos_.end(); it++) {
64 if (it->second == socket) {
65 serverSocketInfos_.erase(it);
66 DBINDER_LOGI(LOG_LABEL, "Shutdown end");
67 return;
68 }
69 }
70 }
71
ClientOnBind(int32_t socket,PeerSocketInfo info)72 void DBinderRemoteListener::ClientOnBind(int32_t socket, PeerSocketInfo info)
73 {
74 return;
75 }
76
ClientOnShutdown(int32_t socket,ShutdownReason reason)77 void DBinderRemoteListener::ClientOnShutdown(int32_t socket, ShutdownReason reason)
78 {
79 DBINDER_LOGI(LOG_LABEL, "socketId:%{public}d, ShutdownReason:%{public}d", socket, reason);
80 std::string networkId;
81 {
82 std::lock_guard<std::mutex> lockGuard(clientSocketMutex_);
83 for (auto it = clientSocketInfos_.begin(); it != clientSocketInfos_.end(); it++) {
84 if (it->second == socket) {
85 networkId = it->first;
86 DBINDER_LOGI(LOG_LABEL, "erase socket:%{public}d", socket);
87 clientSocketInfos_.erase(it);
88 break;
89 }
90 }
91 }
92 if (!networkId.empty()) {
93 EraseDeviceLock(networkId);
94 DBinderService::GetInstance()->ProcessOnSessionClosed(networkId);
95 }
96 DBINDER_LOGI(LOG_LABEL, "Shutdown end");
97 }
98
OnBytesReceived(int32_t socket,const void * data,uint32_t dataLen)99 void DBinderRemoteListener::OnBytesReceived(int32_t socket, const void *data, uint32_t dataLen)
100 {
101 DBINDER_LOGI(LOG_LABEL, "socketId:%{public}d len:%{public}u", socket, dataLen);
102 if (data == nullptr || dataLen != static_cast<uint32_t>(sizeof(DHandleEntryTxRx))) {
103 DBINDER_LOGE(LOG_LABEL, "wrong input, data length:%{public}u "
104 "socketId:%{public}d", dataLen, socket);
105 // ignore the package
106 return;
107 }
108
109 std::shared_ptr<DHandleEntryTxRx> message = std::make_shared<DHandleEntryTxRx>();
110 if (message == nullptr) {
111 DBINDER_LOGE(LOG_LABEL, "fail to create buffer with length:%{public}zu", sizeof(DHandleEntryTxRx));
112 return;
113 }
114 auto res = memcpy_s(message.get(), sizeof(DHandleEntryTxRx), data, sizeof(DHandleEntryTxRx));
115 if (res != 0) {
116 DBINDER_LOGE(LOG_LABEL, "memcpy copy failed");
117 return;
118 }
119 if (message->head.len != sizeof(DHandleEntryTxRx)) {
120 DBINDER_LOGE(LOG_LABEL, "msg head len error, len:%{public}u", message->head.len);
121 return;
122 }
123 DBINDER_LOGI(LOG_LABEL, "service:%{public}llu seq:%{public}u,"
124 " stubIndex:%{public}" PRIu64 " code:%{public}u", message->binderObject,
125 message->seqNumber, message->stubIndex, message->dBinderCode);
126
127 DBinderService::GetInstance()->AddAsynMessageTask(message);
128 return;
129 }
130
CreateClientSocket(const std::string & peerNetworkId)131 int32_t DBinderRemoteListener::CreateClientSocket(const std::string &peerNetworkId)
132 {
133 std::shared_ptr<DeviceLock> lockInfo = QueryOrNewDeviceLock(peerNetworkId);
134 if (lockInfo == nullptr) {
135 return SOCKET_ID_INVALID;
136 }
137 std::lock_guard<std::mutex> lockUnique(lockInfo->mutex);
138
139 {
140 std::lock_guard<std::mutex> lockGuard(clientSocketMutex_);
141 auto it = clientSocketInfos_.find(peerNetworkId);
142 if (it != clientSocketInfos_.end()) {
143 return it->second;
144 }
145 }
146
147 SocketInfo socketInfo = {
148 .name = const_cast<char*>(OWN_SESSION_NAME.c_str()),
149 .peerName = const_cast<char*>(PEER_SESSION_NAME.c_str()),
150 .peerNetworkId = const_cast<char*>(peerNetworkId.c_str()),
151 .pkgName = const_cast<char*>(DBINDER_SERVER_PKG_NAME.c_str()),
152 .dataType = TransDataType::DATA_TYPE_BYTES,
153 };
154 int32_t socketId = DBinderSoftbusClient::GetInstance().Socket(socketInfo);
155 if (socketId <= 0) {
156 DBINDER_LOGE(LOG_LABEL, "create socket error, socket is invalid");
157 return SOCKET_ID_INVALID;
158 }
159
160 int32_t ret = DBinderSoftbusClient::GetInstance().Bind(socketId, QOS_TV, QOS_COUNT, &clientListener_);
161 if (ret != SOFTBUS_OK && ret != SOFTBUS_TRANS_SOCKET_IN_USE) {
162 DBINDER_LOGE(LOG_LABEL, "Bind failed, ret:%{public}d, socketId:%{public}d, peerNetworkId:%{public}s",
163 ret, socketId, DBinderService::ConvertToSecureDeviceID(peerNetworkId).c_str());
164 DBinderSoftbusClient::GetInstance().Shutdown(socketId);
165 EraseDeviceLock(peerNetworkId);
166 return SOCKET_ID_INVALID;
167 }
168
169 DBINDER_LOGI(LOG_LABEL, "Bind succ socketId:%{public}d, peerNetworkId:%{public}s",
170 socketId, DBinderService::ConvertToSecureDeviceID(peerNetworkId).c_str());
171 {
172 std::lock_guard<std::mutex> lockGuard(clientSocketMutex_);
173
174 clientSocketInfos_[peerNetworkId] = socketId;
175 }
176
177 return socketId;
178 }
179
GetPeerSocketId(const std::string & peerNetworkId)180 int32_t DBinderRemoteListener::GetPeerSocketId(const std::string &peerNetworkId)
181 {
182 std::lock_guard<std::mutex> lockGuard(serverSocketMutex_);
183 auto it = serverSocketInfos_.find(peerNetworkId);
184 if (it != serverSocketInfos_.end()) {
185 return it->second;
186 }
187 return SOCKET_ID_INVALID;
188 }
189
StartListener()190 bool DBinderRemoteListener::StartListener()
191 {
192 DBINDER_LOGI(LOG_LABEL, "create socket server");
193 int pid = static_cast<int>(getpid());
194 int uid = static_cast<int>(getuid());
195
196 int32_t ret = DBinderSoftbusClient::GetInstance().DBinderGrantPermission(uid, pid, OWN_SESSION_NAME);
197 if (ret != ERR_NONE) {
198 DBINDER_LOGE(LOG_LABEL, "GrantPermission failed softbus name:%{public}s", OWN_SESSION_NAME.c_str());
199 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GRANT_PERMISSION_FAIL, __FUNCTION__);
200 return false;
201 }
202 SocketInfo serverSocketInfo = {
203 .name = const_cast<char*>(OWN_SESSION_NAME.c_str()),
204 .pkgName = const_cast<char*>(DBINDER_SERVER_PKG_NAME.c_str()),
205 .dataType = TransDataType::DATA_TYPE_BYTES,
206 };
207 int32_t socketId = DBinderSoftbusClient::GetInstance().Socket(serverSocketInfo);
208 if (socketId <= 0) {
209 DBINDER_LOGE(LOG_LABEL, "create socket server error, socket is invalid");
210 return false;
211 }
212 ret = DBinderSoftbusClient::GetInstance().Listen(socketId, QOS_TV, QOS_COUNT, &serverListener_);
213 if (ret != SOFTBUS_OK && ret != SOFTBUS_TRANS_SOCKET_IN_USE) {
214 DBINDER_LOGE(LOG_LABEL, "Listen failed, ret:%{public}d", ret);
215 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_CREATE_SOFTBUS_SERVER_FAIL, __FUNCTION__);
216 DBinderSoftbusClient::GetInstance().Shutdown(socketId);
217 return false;
218 }
219 DBINDER_LOGI(LOG_LABEL, "Listen ok, socketId:%{public}d", socketId);
220 listenSocketId_ = socketId;
221
222 return true;
223 }
224
StopListener()225 bool DBinderRemoteListener::StopListener()
226 {
227 ClearDeviceLock();
228 {
229 std::lock_guard<std::mutex> lockGuard(clientSocketMutex_);
230 for (auto it = clientSocketInfos_.begin(); it != clientSocketInfos_.end(); it++) {
231 DBinderSoftbusClient::GetInstance().Shutdown(it->second);
232 }
233 clientSocketInfos_.clear();
234 }
235 DBinderSoftbusClient::GetInstance().Shutdown(listenSocketId_);
236 return true;
237 }
238
QueryOrNewDeviceLock(const std::string & networkId)239 std::shared_ptr<DeviceLock> DBinderRemoteListener::QueryOrNewDeviceLock(const std::string &networkId)
240 {
241 std::lock_guard<std::mutex> lockGuard(deviceMutex_);
242 auto it = deviceLockMap_.find(networkId);
243 if (it != deviceLockMap_.end()) {
244 return it->second;
245 }
246 std::shared_ptr<DeviceLock> lockInfo = std::make_shared<struct DeviceLock>();
247 if (lockInfo == nullptr) {
248 DBINDER_LOGE(LOG_LABEL, "failed to create mutex of device:%{public}s",
249 DBinderService::ConvertToSecureDeviceID(networkId).c_str());
250 return nullptr;
251 }
252 deviceLockMap_.insert(std::pair<std::string, std::shared_ptr<DeviceLock>>(networkId, lockInfo));
253 return lockInfo;
254 }
255
ClearDeviceLock()256 void DBinderRemoteListener::ClearDeviceLock()
257 {
258 std::lock_guard<std::mutex> lockGuard(deviceMutex_);
259 deviceLockMap_.clear();
260 }
261
EraseDeviceLock(const std::string & networkId)262 void DBinderRemoteListener::EraseDeviceLock(const std::string &networkId)
263 {
264 std::lock_guard<std::mutex> lockGuard(deviceMutex_);
265 deviceLockMap_.erase(networkId);
266 }
267
SendDataToRemote(const std::string & networkId,const struct DHandleEntryTxRx * msg)268 bool DBinderRemoteListener::SendDataToRemote(const std::string &networkId, const struct DHandleEntryTxRx *msg)
269 {
270 DBINDER_LOGI(LOG_LABEL, "device:%{public}s",
271 DBinderService::ConvertToSecureDeviceID(networkId).c_str());
272 if (msg == nullptr) {
273 DBINDER_LOGE(LOG_LABEL, "msg is null");
274 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
275 return false;
276 }
277
278 int32_t socketId = CreateClientSocket(networkId);
279 if (socketId <= 0) {
280 DBINDER_LOGE(LOG_LABEL, "fail to creat client Socket");
281 return false;
282 }
283
284 int32_t ret = DBinderSoftbusClient::GetInstance().SendBytes(socketId, msg, msg->head.len);
285 if (ret != 0) {
286 DBINDER_LOGE(LOG_LABEL, "fail to send bytes, ret:%{public}d socketId:%{public}d, networkId:%{public}s",
287 ret, socketId, DBinderService::ConvertToSecureDeviceID(networkId).c_str());
288 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_SEND_BYTES_FAIL, __FUNCTION__);
289 return false;
290 }
291 DBINDER_LOGI(LOG_LABEL, "socketId:%{public}d device:%{public}s succ",
292 socketId, DBinderService::ConvertToSecureDeviceID(networkId).c_str());
293 return true;
294 }
295
SendDataReply(const std::string & networkId,const struct DHandleEntryTxRx * msg)296 bool DBinderRemoteListener::SendDataReply(const std::string &networkId, const struct DHandleEntryTxRx *msg)
297 {
298 if (msg == nullptr) {
299 DBINDER_LOGE(LOG_LABEL, "msg is null");
300 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
301 return false;
302 }
303
304 int32_t socketId = GetPeerSocketId(networkId);
305 if (socketId == SOCKET_ID_INVALID) {
306 DBINDER_LOGE(LOG_LABEL, "failed to get peer SocketId, device:%{public}s",
307 DBinderService::ConvertToSecureDeviceID(networkId).c_str());
308 DfxReportFailDeviceEvent(DbinderErrorCode::RPC_DRIVER,
309 DBinderService::ConvertToSecureDeviceID(networkId).c_str(), RADAR_GET_PEER_SESSION_FAIL, __FUNCTION__);
310 return false;
311 }
312
313 int32_t result = DBinderSoftbusClient::GetInstance().SendBytes(socketId, msg, msg->head.len);
314 if (result != 0) {
315 DBINDER_LOGE(LOG_LABEL, "fail to send bytes of reply, result:%{public}d device:%{public}s"
316 " socketId:%{public}d", result, DBinderService::ConvertToSecureDeviceID(networkId).c_str(), socketId);
317 DfxReportFailDeviceEvent(DbinderErrorCode::RPC_DRIVER,
318 DBinderService::ConvertToSecureDeviceID(networkId).c_str(), RADAR_SEND_BYTES_FAIL, __FUNCTION__);
319 return false;
320 }
321 DBINDER_LOGI(LOG_LABEL, "socketId:%{public}d, networkId:%{public}s",
322 socketId, DBinderService::ConvertToSecureDeviceID(networkId).c_str());
323 return true;
324 }
325
ShutdownSocket(const std::string & networkId)326 bool DBinderRemoteListener::ShutdownSocket(const std::string &networkId)
327 {
328 EraseDeviceLock(networkId);
329 std::lock_guard<std::mutex> lockGuard(clientSocketMutex_);
330 auto it = clientSocketInfos_.find(networkId);
331 if (it != clientSocketInfos_.end()) {
332 DBINDER_LOGI(LOG_LABEL, "networkId:%{public}s offline, Shutdown socketId:%{public}d ",
333 DBinderService::ConvertToSecureDeviceID(networkId).c_str(), it->second);
334 DBinderSoftbusClient::GetInstance().Shutdown(it->second);
335 clientSocketInfos_.erase(it);
336 return true;
337 }
338 DBINDER_LOGI(LOG_LABEL, "no socketId of networkId:%{public}s",
339 DBinderService::ConvertToSecureDeviceID(networkId).c_str());
340 return false;
341 }
342 } // namespace OHOS
343