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