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