1 /* 2 * Copyright (C) 2021-2023 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 #ifndef OHOS_IPC_SERVICES_DBINDER_DBINDER_SERVICE_H 17 #define OHOS_IPC_SERVICES_DBINDER_DBINDER_SERVICE_H 18 19 #include <string> 20 #include <map> 21 #include <mutex> 22 #include <shared_mutex> 23 #include <memory> 24 #include <list> 25 #include <thread> 26 27 #include "dbinder_service_stub.h" 28 #include "ipc_object_proxy.h" 29 #include "ipc_object_stub.h" 30 #include "rpc_system_ability_callback.h" 31 #include "Session.h" 32 #include "thread_pool.h" 33 34 using Communication::SoftBus::Session; 35 36 namespace OHOS { 37 class DBinderRemoteListener; 38 39 constexpr int DEVICEID_LENGTH = 64; 40 constexpr int SERVICENAME_LENGTH = 200; 41 42 /* version change history 43 * a) 1 --> 2, support transfer tokenid to peer device 44 */ 45 constexpr int RPC_TOKENID_SUPPORT_VERSION = 2; 46 constexpr int ENCRYPT_HEAD_LEN = 28; 47 constexpr int ENCRYPT_LENGTH = 4; 48 49 // Description of the device identification information parameter. 50 struct DeviceIdInfo { 51 uint32_t tokenId; 52 char fromDeviceId[DEVICEID_LENGTH + 1]; 53 char toDeviceId[DEVICEID_LENGTH + 1]; 54 }; 55 56 // Description of the DHandle entry head parameter. 57 struct DHandleEntryHead { 58 uint32_t len; 59 uint32_t version; 60 }; 61 62 // Description of the DHandle entry TxRx parameter. 63 struct DHandleEntryTxRx { 64 struct DHandleEntryHead head; 65 uint32_t transType; 66 uint32_t dBinderCode; 67 uint16_t fromPort; 68 uint16_t toPort; 69 uint64_t stubIndex; 70 uint32_t seqNumber; 71 binder_uintptr_t binderObject; 72 struct DeviceIdInfo deviceIdInfo; 73 binder_uintptr_t stub; 74 uint16_t serviceNameLength; 75 char serviceName[SERVICENAME_LENGTH + 1]; 76 uint32_t pid; 77 uint32_t uid; 78 }; 79 80 // SessionInfo parameter description. 81 struct SessionInfo { 82 uint32_t seqNumber; 83 uint32_t type; 84 uint16_t toPort; 85 uint16_t fromPort; 86 uint64_t stubIndex; 87 uint32_t socketFd; 88 std::string serviceName; 89 struct DeviceIdInfo deviceIdInfo; 90 }; 91 92 // Enumerate DBinder message codes. 93 enum DBinderCode { 94 MESSAGE_AS_INVOKER = 1, 95 MESSAGE_AS_REPLY = 2, 96 MESSAGE_AS_OBITUARY = 3, 97 MESSAGE_AS_REMOTE_ERROR = 4, 98 MESSAGE_AS_REPLY_TOKENID = 5, 99 }; 100 101 // Enumerate the returned DBinder error codes. 102 enum DBinderErrorCode { 103 DBINDER_OK = 100, 104 STUB_INVALID = 101, 105 SEND_MESSAGE_FAILED = 102, 106 MAKE_THREADLOCK_FAILED = 103, 107 WAIT_REPLY_TIMEOUT = 104, 108 QUERY_REPLY_SESSION_FAILED = 105, 109 SA_NOT_FOUND = 106, 110 SA_INVOKE_FAILED = 107, 111 DEVICEID_INVALID = 108, 112 SESSION_NAME_NOT_FOUND = 109, 113 WRITE_PARCEL_FAILED = 110, 114 INVOKE_STUB_THREAD_FAILED = 111, 115 SESSION_NAME_INVALID = 112, 116 }; 117 118 // Description of thread locking information parameters. 119 struct ThreadLockInfo { 120 std::mutex mutex; 121 std::string networkId; 122 std::condition_variable condition; 123 bool ready = false; 124 }; 125 126 class DBinderService : public virtual RefBase { 127 public: 128 DBinderService(); 129 virtual ~DBinderService(); 130 public: 131 132 /** 133 * @brief Obtains an instance. 134 * @return Returns a DBinderService type pointer object. 135 * @since 9 136 */ 137 static sptr<DBinderService> GetInstance(); 138 139 /** 140 * @brief Convert device ID to security string for printing. 141 * @param deviceID Indicates the device ID to be converted. 142 * @return Returns the converted security device ID. 143 * @since 9 144 */ 145 static std::string ConvertToSecureDeviceID(const std::string &deviceID); 146 147 /** 148 * @brief Start the DBinder service. 149 * @param callbackImpl Indicates a callback of type RpcSystemAbilityCallback. 150 * @return Returns <b>true</b> if the service started successfully; returns <b>false</b> otherwise. 151 * @since 9 152 */ 153 bool StartDBinderService(std::shared_ptr<RpcSystemAbilityCallback> &callbackImpl); 154 155 /** 156 * @brief Make a remote binding. 157 * @param serviceName Indicates the service name. 158 * @param deviceID Indicates the device ID. 159 * @param binderObject Indicates the object to be binder. 160 * @param pid Indicates the value of pid. 161 * @param uid Indicates the value of uid. 162 * @return Returns the DBinderServiceStuble pointer object. 163 * @since 9 164 */ 165 sptr<DBinderServiceStub> MakeRemoteBinder(const std::u16string &serviceName, 166 const std::string &deviceID, int32_t binderObject, uint32_t pid = 0, uint32_t uid = 0); 167 168 /** 169 * @brief Register the remote agent. 170 * @param serviceName Indicates the service name. 171 * @param binderObject Indicates the IRemoteObject pointer object to be binder. 172 * @return Returns <b>true</b> if the registration successful; returns <b>false</b> otherwise. 173 * @since 9 174 */ 175 bool RegisterRemoteProxy(std::u16string serviceName, sptr<IRemoteObject> binderObject); 176 177 /** 178 * @brief Register the remote agent. 179 * @param serviceName Indicates the service name. 180 * @param systemAbilityId Indicatesthe system ability ID. 181 * @return Returns <b>true</b> if the registration successful; returns <b>false</b> otherwise. 182 * @since 9 183 */ 184 bool RegisterRemoteProxy(std::u16string serviceName, int32_t systemAbilityId); 185 186 /** 187 * @brief Processing remote messaging tasks. 188 * @param message Indicates the delivered message belongs to the DHandleEntryTxR structure. 189 * @return Returns <b>true</b> if the processing is successful; returns <b>false</b> otherwise. 190 * @since 9 191 */ 192 bool OnRemoteMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message); 193 194 /** 195 * @brief Register an asynchronous message task. 196 * @param message Indicates the delivered message belongs to the DHandleEntryTxR structure. 197 * @return void 198 * @since 9 199 */ 200 void AddAsynMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message); 201 202 /** 203 * @brief Query the session object. 204 * @param stub Indicates a stub that can be used to query a session object. 205 * @return The returned result belongs to the SessionInfo structure. 206 * @since 9 207 */ 208 std::shared_ptr<struct SessionInfo> QuerySessionObject(binder_uintptr_t stub); 209 210 /** 211 * @brief Detach the remote object death notification. 212 * @param object Indicates the IRemoteObject pointer object. 213 * @return Returns <b>true</b> if the registration successful; returns <b>false</b> otherwise. 214 * @since 9 215 */ 216 bool DetachDeathRecipient(sptr<IRemoteObject> object); 217 218 /** 219 * @brief Attach the remote object death notification. 220 * @param object Indicates the IRemoteObject pointer object. 221 * @param deathRecipient Indicates the the callback to attach. 222 * @return Returns <b>true</b> if the operation succeeds; returns <b>false</b> otherwise. 223 * @since 9 224 */ 225 bool AttachDeathRecipient(sptr<IRemoteObject> object, sptr<IRemoteObject::DeathRecipient> deathRecipient); 226 227 /** 228 * @brief Query the remote object death notification. 229 * @param object Indicates the IRemoteObject pointer object. 230 * @return Returns the results of the found death notice. 231 * @since 9 232 */ 233 sptr<IRemoteObject::DeathRecipient> QueryDeathRecipient(sptr<IRemoteObject> object); 234 235 /** 236 * @brief Detach the callback proxy object. 237 * @param object Indicates the IRemoteObject pointer object. 238 * @return Returns <b>true</b> if the operation succeeds; returns <b>false</b> otherwise. 239 * @since 9 240 */ 241 bool DetachCallbackProxy(sptr<IRemoteObject> object); 242 243 /** 244 * @brief Attach the callback proxy object. 245 * @param object Indicates the IRemoteObject pointer object. 246 * @param dbStub Indicates a service communication stub across devices. 247 * @return Returns <b>true</b> if the operation succeeds; returns <b>false</b> otherwise. 248 * @since 9 249 */ 250 bool AttachCallbackProxy(sptr<IRemoteObject> object, DBinderServiceStub *dbStub); 251 252 /** 253 * @brief Notification service death. 254 * @param serviceName Indicates the service name. 255 * @param deviceID Indicates the device ID. 256 * @return Returns {@code ERR_NONE} if valid notifications; returns an error code if the operation fails. 257 * @since 9 258 */ 259 int32_t NoticeServiceDie(const std::u16string &serviceName, const std::string &deviceID); 260 261 /** 262 * @brief Notification device death. 263 * @param deviceID Indicates the device ID. 264 * @return Returns {@code ERR_NONE} if valid notifications; returns an error code if the operation fails. 265 * @since 9 266 */ 267 int32_t NoticeDeviceDie(const std::string &deviceID); 268 269 /** 270 * @brief Create a databus(Dbinder) name. 271 * @param uid Indicates the UID of databus(Dbinder). 272 * @param pid Indicates the PID of databus(Dbinder). 273 * @return Returns the corresponding sessionName. 274 * @since 9 275 */ 276 std::string CreateDatabusName(int uid, int pid); 277 278 /** 279 * @brief Detach the proxy object. 280 * @param binderObject Indicates the object to which it is bound. 281 * @return Returns <b>true</b> if the operation succeeds; returns <b>false</b> otherwise. 282 * @since 9 283 */ 284 bool DetachProxyObject(binder_uintptr_t binderObject); 285 286 /** 287 * @brief A callback when a system ability is loaded completely. 288 * @param srcNetworkId Indicates The network ID of the path. 289 * @param systemAbilityId Indicates system capability ID. 290 * @param remoteObject Indicates a remote object. 291 * @return void 292 * @since 9 293 */ 294 void LoadSystemAbilityComplete(const std::string& srcNetworkId, int32_t systemAbilityId, 295 const sptr<IRemoteObject>& remoteObject); 296 297 /** 298 * @brief Close the process session. 299 * @param session Indicates the session to close. 300 * @return Returns <b>true</b> if the shutdown is successful; returns <b>false</b> otherwise. 301 * @since 9 302 */ 303 bool ProcessOnSessionClosed(std::shared_ptr<Session> session); 304 305 private: 306 static std::shared_ptr<DBinderRemoteListener> GetRemoteListener(); 307 static bool StartRemoteListener(); 308 static void StopRemoteListener(); 309 std::u16string GetRegisterService(binder_uintptr_t binderObject); 310 int32_t InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub, uint32_t seqNumber, uint32_t pid, uint32_t uid); 311 bool OnRemoteReplyMessage(const struct DHandleEntryTxRx *replyMessage); 312 bool OnRemoteErrorMessage(const struct DHandleEntryTxRx *replyMessage); 313 void MakeSessionByReplyMessage(const struct DHandleEntryTxRx *replyMessage); 314 bool OnRemoteInvokerMessage(const struct DHandleEntryTxRx *message); 315 void WakeupThreadByStub(uint32_t seqNumber); 316 void DetachThreadLockInfo(uint32_t seqNumber); 317 bool AttachThreadLockInfo(uint32_t seqNumber, const std::string &networkId, 318 std::shared_ptr<struct ThreadLockInfo> object); 319 std::shared_ptr<struct ThreadLockInfo> QueryThreadLockInfo(uint32_t seqNumber); 320 bool AttachProxyObject(sptr<IRemoteObject> object, binder_uintptr_t binderObject); 321 sptr<IRemoteObject> QueryProxyObject(binder_uintptr_t binderObject); 322 bool DetachSessionObject(binder_uintptr_t stub); 323 bool AttachSessionObject(std::shared_ptr<struct SessionInfo> object, binder_uintptr_t stub); 324 sptr<IRemoteObject> FindOrNewProxy(binder_uintptr_t binderObject, int32_t systemAbilityId); 325 bool SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint32_t seqNumber, uint32_t pid, uint32_t uid); 326 uint16_t AllocFreeSocketPort(); 327 std::string GetLocalDeviceID(); 328 binder_uintptr_t AddStubByTag(binder_uintptr_t stub); 329 binder_uintptr_t QueryStubPtr(binder_uintptr_t stub); 330 bool CheckBinderObject(const sptr<DBinderServiceStub> &stub, binder_uintptr_t binderObject); 331 bool HasDBinderStub(binder_uintptr_t binderObject); 332 bool IsSameStubObject(const sptr<DBinderServiceStub> &stub, const std::u16string &service, 333 const std::string &device); 334 sptr<DBinderServiceStub> FindDBinderStub(const std::u16string &service, const std::string &device); 335 bool DeleteDBinderStub(const std::u16string &service, const std::string &device); 336 sptr<DBinderServiceStub> FindOrNewDBinderStub(const std::u16string &service, 337 const std::string &device, binder_uintptr_t binderObject); 338 void ProcessCallbackProxy(sptr<DBinderServiceStub> dbStub); 339 bool NoticeCallbackProxy(sptr<DBinderServiceStub> dbStub); 340 std::list<std::u16string> FindServicesByDeviceID(const std::string &deviceID); 341 int32_t NoticeServiceDieInner(const std::u16string &serviceName, const std::string &deviceID); 342 uint32_t GetRemoteTransType(); 343 uint32_t OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy, struct DHandleEntryTxRx *replyMessage, 344 std::string &remoteDeviceId, int pid, int uid, uint32_t tokenId); 345 bool IsDeviceIdIllegal(const std::string &deviceID); 346 std::string GetDatabusNameByProxy(IPCObjectProxy *proxy); 347 uint32_t GetSeqNumber(); 348 bool StartThreadPool(); 349 bool StopThreadPool(); 350 bool AddAsynTask(const ThreadPool::Task &f); 351 bool IsSameSession(std::shared_ptr<struct SessionInfo> oldSession, std::shared_ptr<struct SessionInfo> newSession); 352 bool RegisterRemoteProxyInner(std::u16string serviceName, binder_uintptr_t binder); 353 bool CheckSystemAbilityId(int32_t systemAbilityId); 354 bool HandleInvokeListenThread(IPCObjectProxy *proxy, uint64_t stubIndex, std::string serverSessionName, 355 struct DHandleEntryTxRx *replyMessage); 356 bool ReStartRemoteListener(); 357 bool IsSameLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId, 358 std::shared_ptr<DHandleEntryTxRx> loadSaItem); 359 std::shared_ptr<struct DHandleEntryTxRx> PopLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId); 360 void SendMessageToRemote(uint32_t dBinderCode, uint32_t reason, 361 std::shared_ptr<struct DHandleEntryTxRx> replyMessage); 362 363 private: 364 DISALLOW_COPY_AND_MOVE(DBinderService); 365 static std::mutex instanceMutex_; 366 static constexpr int WAIT_FOR_REPLY_MAX_SEC = 8; 367 static constexpr int RETRY_TIMES = 2; 368 static std::shared_ptr<DBinderRemoteListener> remoteListener_; 369 static bool mainThreadCreated_; 370 static sptr<DBinderService> instance_; 371 372 std::shared_mutex remoteBinderMutex_; 373 std::shared_mutex proxyMutex_; 374 std::shared_mutex deathRecipientMutex_; 375 std::shared_mutex sessionMutex_; 376 std::shared_mutex loadSaMutex_; 377 378 std::mutex handleEntryMutex_; 379 std::mutex threadLockMutex_; 380 std::mutex callbackProxyMutex_; 381 std::mutex deathNotificationMutex_; 382 std::mutex threadPoolMutex_; 383 384 uint32_t seqNumber_ = 0; /* indicate make remote binder message sequence number, and can be overflow */ 385 386 /* indicate the stub flag used for negotiation with the peer end, and can be overflow */ 387 binder_uintptr_t stubTagNum_ = 1; 388 std::map<binder_uintptr_t, binder_uintptr_t> mapDBinderStubRegisters_; 389 std::list<sptr<DBinderServiceStub>> DBinderStubRegisted_; 390 std::map<std::u16string, binder_uintptr_t> mapRemoteBinderObjects_; 391 std::map<uint32_t, std::shared_ptr<struct ThreadLockInfo>> threadLockInfo_; 392 std::map<int, sptr<IRemoteObject>> proxyObject_; 393 std::map<binder_uintptr_t, std::shared_ptr<struct SessionInfo>> sessionObject_; 394 std::map<sptr<IRemoteObject>, DBinderServiceStub *> noticeProxy_; 395 std::map<sptr<IRemoteObject>, sptr<IRemoteObject::DeathRecipient>> deathRecipients_; 396 bool threadPoolStarted_ = false; 397 int32_t threadPoolNumber_ = 4; 398 std::unique_ptr<ThreadPool> threadPool_ = nullptr; 399 std::list<std::shared_ptr<struct DHandleEntryTxRx>> loadSaReply_; 400 static constexpr int32_t FIRST_SYS_ABILITY_ID = 0x00000001; 401 static constexpr int32_t LAST_SYS_ABILITY_ID = 0x00ffffff; 402 403 std::shared_ptr<RpcSystemAbilityCallback> dbinderCallback_; 404 }; 405 } // namespace OHOS 406 #endif // OHOS_IPC_SERVICES_DBINDER_DBINDER_SERVICE_H 407