From f4d0cef22026465efde3501b76fbee5923980505 Mon Sep 17 00:00:00 2001 From: zhengliming Date: Thu, 15 Sep 2022 20:29:31 +0800 Subject: [PATCH 1/2] Support to multi-clients Now, IPC support multi-clients. Each client has two component, proxy as a sender and stub as a receiver. Client can transfer its stub into the correspoding proxy and transmit it to the server. Signed-off-by: zhengliming --- include/ipc_base.h | 29 ++++++++-- include/ipc_center.h | 12 ++-- include/ipc_object_proxy.h | 25 ++++++++ include/ipc_object_stub.h | 7 +++ include/ipc_proxy_manager.h | 20 +++++++ include/ipc_skeleton.h | 8 +-- include/ipc_socket_manager.h | 20 +++++++ include/ipc_stub_manager.h | 20 +++++++ include/iremote_object.h | 4 ++ include/message_parcel.h | 3 + ipc_center.cpp | 109 +++++++++++++++++++++++++---------- ipc_object_proxy.cpp | 100 ++++++++++++++++++++++++++++++++ ipc_object_stub.cpp | 57 +++++++++++++++++- ipc_proxy_manager.cpp | 31 ++++++++++ ipc_skeleton.cpp | 47 ++++++--------- ipc_socket_manager.cpp | 24 ++++++++ ipc_stub_manager.cpp | 20 +++++++ iremote_object.cpp | 48 ++++++++++++--- message_parcel.cpp | 20 ++++++- 19 files changed, 517 insertions(+), 87 deletions(-) create mode 100644 include/ipc_object_proxy.h create mode 100644 include/ipc_proxy_manager.h create mode 100644 include/ipc_socket_manager.h create mode 100644 include/ipc_stub_manager.h create mode 100644 ipc_object_proxy.cpp create mode 100644 ipc_proxy_manager.cpp create mode 100644 ipc_socket_manager.cpp create mode 100644 ipc_stub_manager.cpp diff --git a/include/ipc_base.h b/include/ipc_base.h index d289e51..131bc06 100644 --- a/include/ipc_base.h +++ b/include/ipc_base.h @@ -5,19 +5,22 @@ #include #include #include -#include -#include +#include +#include #define IPC_LOG(fmt, args...) \ printf("[IPC LOG %s:%u]" fmt, __FILE__, __LINE__, ##args); -extern key_t g_send_shm_key; -extern key_t g_receive_shm_key; +extern key_t g_client_server_shmKey; const int IPC_SHM_FLAG = IPC_CREAT | 0666; const size_t DATA_SIZE = 0x20000; +const int32_t GET_SA_REQUEST_CODE = 2; +const int32_t WIFI_DEVICE_ABILITY_ID = 1125; +const int32_t WIFI_P2P_ABILITY_ID = 1128; + struct IpcShmData { size_t inputSz; size_t outputSz; @@ -26,13 +29,17 @@ struct IpcShmData { volatile bool needReply; uint32_t requestCode; volatile bool containFd; + volatile bool containHandle; + unsigned long long handle; + std::atomic< bool > isProcessing; + bool deadNotice; }; static inline IpcShmData *OpenShmCommon(key_t shmKey, int flag) { int shmFd = shmget(shmKey, sizeof(IpcShmData), flag); if (shmFd < 0) { - IPC_LOG("Get shm failed\n"); + IPC_LOG("Get shm failed, errno=%d\n", errno); return nullptr; } void *shmPtr = shmat(shmFd, 0, 0); @@ -53,4 +60,16 @@ static inline IpcShmData *OpenShmExcl(key_t shmKey) return OpenShmCommon(shmKey, IPC_SHM_FLAG | IPC_EXCL); } +static inline key_t HandleToKey(unsigned long long handle) +{ + key_t key = handle >> 32; + key ^= handle & 0xFFFFFFFF; + return key; +} + +static inline void HandleToAddr(char *addr, unsigned long long handle) +{ + sprintf(addr, "/tmp/%llx.ipc.socket", handle); +} + #endif // _IPC_BASE_H_ diff --git a/include/ipc_center.h b/include/ipc_center.h index ebf9891..ae14fa7 100644 --- a/include/ipc_center.h +++ b/include/ipc_center.h @@ -9,14 +9,14 @@ namespace OHOS { class IpcCenter { public: IpcCenter(); + ~IpcCenter(); + static bool ShmInit(key_t ShmKey); bool Init(bool isServer, IPCObjectStub *stub); - bool ThreadCreate(); - void ProcessHandle(); + bool ThreadCreate(IPCObjectStub *stub); + static void ProcessHandle(key_t ShmKey, IPCObjectStub *ipcStub); + static size_t threadNum_; private: - bool ShmInit(key_t ShmKey); - size_t threadNum_; - IPCObjectStub *ipcStub_; - bool needStop_; + key_t receive_shm_key_; }; } // namespace OHOS diff --git a/include/ipc_object_proxy.h b/include/ipc_object_proxy.h new file mode 100644 index 0000000..a130e69 --- /dev/null +++ b/include/ipc_object_proxy.h @@ -0,0 +1,25 @@ +#ifndef _IPC_OBJECT_PROXY_H_ +#define _IPC_OBJECT_PROXY_H_ + +#include "ipc_base.h" +#include "iremote_object.h" + +namespace OHOS { + +class IPCObjectProxy : public IRemoteObject { +public: + IPCObjectProxy(unsigned long long handle); + ~IPCObjectProxy(); + int SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + bool AddDeathRecipient(const sptr< DeathRecipient > &recipient) override; + void SendObituary(); +private: + key_t sendShmKey_; + const char *socketAddr_; + int recvFd_; + sptr< DeathRecipient > deathRecipient_; +}; + +}; // namespace OHOS + +#endif // _IPC_OBJECT_PROXY_H_ \ No newline at end of file diff --git a/include/ipc_object_stub.h b/include/ipc_object_stub.h index ec93b6d..a1306ab 100644 --- a/include/ipc_object_stub.h +++ b/include/ipc_object_stub.h @@ -1,6 +1,8 @@ #ifndef _IPC_OBJECT_STUB_H_ #define _IPC_OBJECT_STUB_H_ +#include + #include "iremote_object.h" namespace OHOS { @@ -10,6 +12,11 @@ public: IPCObjectStub(); ~IPCObjectStub(); virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); + void CreateThread(key_t shmKey); + void SendDeadNotification(); + volatile bool needStop_; + const char *sendAddr_; + int recvFd_; }; } // namespace OHOS diff --git a/include/ipc_proxy_manager.h b/include/ipc_proxy_manager.h new file mode 100644 index 0000000..0dc0d67 --- /dev/null +++ b/include/ipc_proxy_manager.h @@ -0,0 +1,20 @@ +#ifndef _IPC_PROXY_MANAGER_H_ +#define _IPC_PROXY_MANAGER_H_ + +#include +#include +#include "ipc_object_proxy.h" + +namespace OHOS { +class IPCProxyManager { +public: + static sptr< IPCObjectProxy > FindOrNewProxy(unsigned long long handle); + static void CleanProxy(unsigned long long handle); +private: + static std::map< unsigned long long, sptr< IPCObjectProxy > > proxyMap_; + static std::mutex mutex_; +}; + +}; + +#endif // _IPC_PROXY_MANAGER_H_ \ No newline at end of file diff --git a/include/ipc_skeleton.h b/include/ipc_skeleton.h index 45260cb..d0157a8 100644 --- a/include/ipc_skeleton.h +++ b/include/ipc_skeleton.h @@ -19,14 +19,12 @@ public: static uid_t GetCallingUid(); static sptr< IRemoteObject > GetContextObject(); static bool SetContextObject(sptr< IRemoteObject > &object); - static bool SocketListening(bool isServer); - static int SocketReadFd(); - static bool SocketWriteFd(int fd); + static int SocketListening(const char *addr); + static int SocketReadFd(int socketFd); + static bool SocketWriteFd(const char *addr, int fd); private: static sptr< IRemoteObject > obj_; - static int socketFd_; - static bool isServer_; }; } // namespace OHOS diff --git a/include/ipc_socket_manager.h b/include/ipc_socket_manager.h new file mode 100644 index 0000000..b8f86ac --- /dev/null +++ b/include/ipc_socket_manager.h @@ -0,0 +1,20 @@ +#ifndef _IPC_SOCKET_MANAGER_H_ +#define _IPC_SOCKET_MANAGER_H_ + +#include +#include + +namespace OHOS { + +class IPCSocketManager { +public: + static void InsertSocketFd(unsigned long long handle, int socketFd); + static int FindSocketFd(unsigned long long handle); +private: + static std::map< unsigned long long, int > socketFdMap_; + static std::mutex mutex_; +}; + +} // namespace OHOS + +#endif // _IPC_SOCKET_MANAGER_H_ \ No newline at end of file diff --git a/include/ipc_stub_manager.h b/include/ipc_stub_manager.h new file mode 100644 index 0000000..a2533b5 --- /dev/null +++ b/include/ipc_stub_manager.h @@ -0,0 +1,20 @@ +#ifndef _IPC_STUB_MANAGER_H_ +#define _IPC_STUB_MANAGER_H_ + +#include +#include +#include "ipc_object_stub.h" + +namespace OHOS { +class IPCStubManager { +public: + static unsigned long long GetHandleNum(); + static void InsertStub(unsigned long long handle, sptr< IPCObjectStub > stub); +private: + static std::map< unsigned long long, sptr< IPCObjectStub > > stubMap_; + static std::mutex mutex_; +}; + +}; + +#endif // _IPC_STUB_MANAGER_H_ \ No newline at end of file diff --git a/include/iremote_object.h b/include/iremote_object.h index a955172..ef1e6e3 100644 --- a/include/iremote_object.h +++ b/include/iremote_object.h @@ -26,6 +26,8 @@ public: class IRemoteObject : public virtual Parcelable { public: + IRemoteObject(); + ~IRemoteObject(); class DeathRecipient : public RefBase { public: virtual void OnRemoteDied(const wptr< IRemoteObject > &object) {} @@ -35,6 +37,8 @@ public: virtual bool AddDeathRecipient(const sptr< DeathRecipient > &recipient); virtual bool RemoveDeathRecipient(const sptr< DeathRecipient > &recipient); virtual bool Marshalling(Parcel &parcel) const override; + unsigned long long GetHandle(); + unsigned long long handle_; }; } // namespace OHOS diff --git a/include/message_parcel.h b/include/message_parcel.h index 61534df..5390aea 100644 --- a/include/message_parcel.h +++ b/include/message_parcel.h @@ -18,6 +18,9 @@ public: bool ContainFileDescriptors() const; sptr< IRemoteObject > ReadRemoteObject(); bool WriteRemoteObject(const sptr< IRemoteObject > &object); + bool ContainRemoteObject(); + unsigned long long RemoteObjectHandle_; + bool isContainHandle_; private: static constexpr size_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // 128M int fd_; diff --git a/ipc_center.cpp b/ipc_center.cpp index b51f39d..e995935 100644 --- a/ipc_center.cpp +++ b/ipc_center.cpp @@ -4,10 +4,19 @@ #include "ipc_base.h" #include "ipc_center.h" #include "ipc_skeleton.h" +#include "ipc_socket_manager.h" +#include "ipc_proxy_manager.h" namespace OHOS { -IpcCenter::IpcCenter() : threadNum_(0), needStop_(false) {} +static const char *IPC_SERVER_SOCKET_ADDR = "/tmp/ipc.socket.server"; +static const char *IPC_CLIENT_SOCKET_ADDR = "/tmp/ipc.socket.client"; + +size_t IpcCenter::threadNum_ = 0; + +IpcCenter::IpcCenter() {} + +IpcCenter::~IpcCenter() {} bool IpcCenter::ShmInit(key_t shmKey) { @@ -18,82 +27,124 @@ bool IpcCenter::ShmInit(key_t shmKey) } shmPtr->needReply = false; shmPtr->containFd = false; + shmPtr->isProcessing = false; + shmPtr->deadNotice = false; shmdt((void *)shmPtr); return true; } bool IpcCenter::Init(bool isServer, IPCObjectStub *stub) { + if (!isServer) { + IPC_LOG("Only the server can call this interface\n"); + return false; + } + if (stub == nullptr) { IPC_LOG("Invalid stub\n"); return false; } - if (isServer && (!ShmInit(g_send_shm_key) || !ShmInit(g_receive_shm_key))) { - IPC_LOG("Shm inti failed\n"); + if (isServer && !ShmInit(g_client_server_shmKey)) { + IPC_LOG("Shm init failed\n"); return false; } - if (isServer) { - std::swap(g_send_shm_key, g_receive_shm_key); + if (stub->recvFd_ >= 0) { + close(stub->recvFd_); } - ipcStub_ = stub; - - if (!IPCSkeleton::SocketListening(isServer)) { + stub->recvFd_ = IPCSkeleton::SocketListening(IPC_SERVER_SOCKET_ADDR); + if (stub->recvFd_ < 0) { IPC_LOG("Starting socket listen failed\n"); return false; } - return ThreadCreate(); + IPCSocketManager::InsertSocketFd(0, stub->recvFd_); + stub->sendAddr_ = IPC_CLIENT_SOCKET_ADDR; + stub->handle_ = 0; + + return ThreadCreate(stub); } -void IpcCenter::ProcessHandle() +void IpcCenter::ProcessHandle(key_t shmKey, IPCObjectStub *ipcStub) { + IpcShmData *shmPtr = OpenShm(shmKey); + if (shmPtr == nullptr) { + IPC_LOG("Open shm failed"); + return; + } + IPC_LOG("STUB LISTENING with handle=%llx\n", ipcStub->handle_); do { - IpcShmData *shmPtr = OpenShm(g_receive_shm_key); - if (shmPtr == nullptr) { - return; - } while (!shmPtr->needReply) { usleep(10); + if (ipcStub->needStop_) { + IPC_LOG("STUB LISTENING END with handle=%llx\n", ipcStub->handle_); + shmdt((void*)shmPtr); + return; + } + } + + if (shmPtr->deadNotice) { + if (ipcStub->handle_) { + IPC_LOG("Client received a wrong notice\n"); + shmdt((void*)shmPtr); + return; + } + IPCProxyManager::CleanProxy(shmPtr->handle); + shmPtr->deadNotice = false; + shmPtr->needReply = false; + continue; } + + IPC_LOG("PROCESSING REMOTE REQUEST with handle=%llx\n", ipcStub->handle_); MessageParcel data, reply; MessageOption option; data.WriteUnpadBuffer(shmPtr->inputData, shmPtr->inputSz); if (shmPtr->containFd) { shmPtr->containFd = false; - if (!data.WriteFileDescriptor(IPCSkeleton::SocketReadFd())) { - IPC_LOG("Process file descriptor failed"); + if (!data.WriteFileDescriptor(IPCSkeleton::SocketReadFd(ipcStub->recvFd_))) { + IPC_LOG("Process file descriptor failed\n"); shmdt((void *)shmPtr); return; } } - ipcStub_->OnRemoteRequest(shmPtr->requestCode, data, reply, option); + if (shmPtr->containHandle) { + data.RemoteObjectHandle_ = shmPtr->handle; + data.isContainHandle_ = true; + shmPtr->containHandle = false; + } + ipcStub->OnRemoteRequest(shmPtr->requestCode, data, reply, option); shmPtr->outputSz = reply.GetDataSize(); + if (shmPtr->outputSz > DATA_SIZE) { + IPC_LOG("Callback data overflow!\n"); + } memcpy(shmPtr->outputData, (void*)reply.GetData(), shmPtr->outputSz); if (reply.ContainFileDescriptors()) { - if (!IPCSkeleton::SocketWriteFd(reply.ReadFileDescriptor())) { - IPC_LOG("Send file descriptor in reply failed\n") + if (!IPCSkeleton::SocketWriteFd(ipcStub->sendAddr_, reply.ReadFileDescriptor())) { + IPC_LOG("Send file descriptor in reply failed\n"); shmdt((void *)shmPtr); return; } shmPtr->containFd = true; } + if (reply.ContainRemoteObject()) { + shmPtr->handle = reply.RemoteObjectHandle_; + shmPtr->containHandle = true; + } shmPtr->needReply = false; - shmdt((void*)shmPtr); - } while (!needStop_); + IPC_LOG("IPC STUB PROCESS END with handle=%llx\n", ipcStub->handle_); + } while (!ipcStub->needStop_); + IPC_LOG("STUB LISTENING END with handle=%llx\n", ipcStub->handle_); + shmdt((void*)shmPtr); } -bool IpcCenter::ThreadCreate() +bool IpcCenter::ThreadCreate(IPCObjectStub *stub) { - if (!threadNum_) { - ++threadNum_; - std::thread new_thread(std::bind(&IpcCenter::ProcessHandle, this)); - new_thread.detach(); - return true; - } - return false; + ++threadNum_; + std::thread new_thread(std::bind(&IpcCenter::ProcessHandle, g_client_server_shmKey, stub)); + new_thread.detach(); + return true; } } // namespace OHOS diff --git a/ipc_object_proxy.cpp b/ipc_object_proxy.cpp new file mode 100644 index 0000000..2701e2d --- /dev/null +++ b/ipc_object_proxy.cpp @@ -0,0 +1,100 @@ +#include "ipc_skeleton.h" +#include "ipc_object_proxy.h" +#include "ipc_socket_manager.h" + +namespace OHOS { + +static const char *IPC_CLIENT_SOCKET_ADDR = "/tmp/ipc.socket.client"; + +IPCObjectProxy::IPCObjectProxy(unsigned long long handle) : + socketAddr_(IPC_CLIENT_SOCKET_ADDR), recvFd_(-1), deathRecipient_(nullptr) +{ + IPC_LOG("INSERT PROXY with handle=%llx\n", handle); + handle_ = handle; + sendShmKey_ = HandleToKey(handle); +} + +IPCObjectProxy::~IPCObjectProxy() {} + +int IPCObjectProxy::SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + IpcShmData *shmPtr = NULL; + + if (code == GET_SA_REQUEST_CODE || (code >= WIFI_DEVICE_ABILITY_ID && code <= WIFI_P2P_ABILITY_ID)) { + reply.isContainHandle_ = true; + reply.RemoteObjectHandle_ = 0; + return 0; + } + + shmPtr = OpenShm(sendShmKey_); + if (shmPtr == nullptr) { + return -1; + } + + IPC_LOG("WAITING FOR PREVIOUS IPC\n"); + + // waiting previous ipc + while (shmPtr->needReply); + + IPC_LOG("SENDING REQUEST with code=%u\n", code); + + shmPtr->requestCode = code; + shmPtr->inputSz = data.GetDataSize(); + if (shmPtr->inputSz > DATA_SIZE) { + IPC_LOG("Sending data overflow!"); + } + memcpy(shmPtr->inputData, (void *)data.GetData(), shmPtr->inputSz); + if (data.ContainFileDescriptors()) { + IPC_LOG("SENDING FD\n"); + shmPtr->containFd = true; + if (!IPCSkeleton::SocketWriteFd(socketAddr_, data.ReadFileDescriptor())) { + IPC_LOG("Send File Descriptor failed\n"); + shmdt((void*)shmPtr); + return -1; + } + } + if (data.ContainRemoteObject()) { + shmPtr->containHandle = true; + shmPtr->handle = data.RemoteObjectHandle_; + } + shmPtr->needReply = true; + + IPC_LOG("WAITING STUB REPLY with handle=%llx\n", handle_); + + // waiting receiver reply + while (shmPtr->needReply); + IPC_LOG("RECEIVED DATA FROM REMOTE with code=%u\n", code); + + reply.WriteUnpadBuffer(shmPtr->outputData, shmPtr->outputSz); + if (shmPtr->containFd) { + if (!reply.WriteFileDescriptor(IPCSkeleton::SocketReadFd(IPCSocketManager::FindSocketFd(1)))) { + IPC_LOG("Receive reply fd failed"); + shmdt((void *)shmPtr); + return -1; + } + shmPtr->containFd = false; + } + if (shmPtr->containHandle) { + reply.isContainHandle_ = true; + reply.RemoteObjectHandle_ = shmPtr->handle; + shmPtr->containHandle = false; + } + shmdt((void *)shmPtr); + return 0; +} + +bool IPCObjectProxy::AddDeathRecipient(const sptr< DeathRecipient > &recipient) +{ + deathRecipient_ = recipient; + return true; +} + +void IPCObjectProxy::SendObituary() +{ + if (deathRecipient_ != nullptr) { + deathRecipient_->OnRemoteDied(this); + deathRecipient_ = nullptr; + } +} + +}; // namespace OHOS \ No newline at end of file diff --git a/ipc_object_stub.cpp b/ipc_object_stub.cpp index 7cae93f..4f74983 100644 --- a/ipc_object_stub.cpp +++ b/ipc_object_stub.cpp @@ -1,11 +1,32 @@ +#include + #include "ipc_base.h" +#include "ipc_center.h" +#include "ipc_skeleton.h" +#include "ipc_stub_manager.h" #include "ipc_object_stub.h" +#include "ipc_socket_manager.h" namespace OHOS { -IPCObjectStub::IPCObjectStub() {} +static const char *IPC_SERVER_SOCKET_ADDR = "/tmp/ipc.socket.server"; +static const char *IPC_CLIENT_SOCKET_ADDR = "/tmp/ipc.socket.client"; + +IPCObjectStub::IPCObjectStub() : needStop_(false) +{ + handle_ = getpid(); + handle_ = (handle_ << 32) | IPCStubManager::GetHandleNum(); + IPCStubManager::InsertStub(handle_, this); + key_t shmKey = HandleToKey(handle_); + IpcCenter::ShmInit(shmKey); + sendAddr_ = IPC_SERVER_SOCKET_ADDR; + CreateThread(shmKey); +} -IPCObjectStub::~IPCObjectStub() {} +IPCObjectStub::~IPCObjectStub() +{ + SendDeadNotification(); +} int IPCObjectStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { @@ -13,4 +34,36 @@ int IPCObjectStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessagePa return -1; } +void IPCObjectStub::CreateThread(key_t shmKey) +{ + IpcCenter::threadNum_++; + std::thread new_thread(std::bind(IpcCenter::ProcessHandle, shmKey, this)); + new_thread.detach(); + recvFd_ = IPCSkeleton::SocketListening(IPC_CLIENT_SOCKET_ADDR); + IPCSocketManager::InsertSocketFd(1, recvFd_); + if (recvFd_ < 0) { + IPC_LOG("Stub socket listen failed\n"); + } +} + +void IPCObjectStub::SendDeadNotification() +{ + IpcShmData *shmPtr = OpenShm(g_client_server_shmKey); + if (shmPtr == nullptr) { + IPC_LOG("Open server shm failed\n"); + return; + } + + // waiting previous ipc + IPC_LOG("WAITING FOR PREVIOUS IPC\n"); + while (shmPtr->needReply); + + shmPtr->deadNotice = true; + shmPtr->handle = handle_; + + shmPtr->needReply = true; + + shmdt((void *)shmPtr); +} + } // namespace OHOS diff --git a/ipc_proxy_manager.cpp b/ipc_proxy_manager.cpp new file mode 100644 index 0000000..baf63e9 --- /dev/null +++ b/ipc_proxy_manager.cpp @@ -0,0 +1,31 @@ +#include "ipc_proxy_manager.h" + +namespace OHOS { + +std::map< unsigned long long, sptr< IPCObjectProxy > > IPCProxyManager::proxyMap_; +std::mutex IPCProxyManager::mutex_; + +sptr< IPCObjectProxy > IPCProxyManager::FindOrNewProxy(unsigned long long handle) +{ + std::lock_guard< std::mutex > lock(mutex_); + auto it = proxyMap_.find(handle); + if (it == proxyMap_.end()) { + sptr< IPCObjectProxy > proxy(new IPCObjectProxy(handle)); + proxyMap_.emplace(handle, proxy); + IPC_LOG("INSERT PROXY with handle=%llx\n", handle); + return proxy; + } + return it->second; +} + +void IPCProxyManager::CleanProxy(unsigned long long handle) +{ + std::lock_guard< std::mutex > lock(mutex_); + auto it = proxyMap_.find(handle); + if (it != proxyMap_.end()) { + it->second->SendObituary(); + proxyMap_.erase(it); + } +} + +}; // namespace OHOS \ No newline at end of file diff --git a/ipc_skeleton.cpp b/ipc_skeleton.cpp index 9f70d36..d7cfd20 100644 --- a/ipc_skeleton.cpp +++ b/ipc_skeleton.cpp @@ -8,12 +8,7 @@ namespace OHOS { -const char *IPC_SERVER_SOCKET_ADDR = "/tmp/ipc.socket.server"; -const char *IPC_CLIENT_SOCKET_ADDR = "/tmp/ipc.socket.client"; - sptr< IRemoteObject > IPCSkeleton::obj_ = nullptr; -int IPCSkeleton::socketFd_ = -1; -bool IPCSkeleton::isServer_ = true; pid_t IPCSkeleton::GetCallingPid() { @@ -39,20 +34,12 @@ sptr< IRemoteObject > IPCSkeleton::GetContextObject() return obj_; } -bool IPCSkeleton::SocketListening(bool isServer) +int IPCSkeleton::SocketListening(const char *addr) { - if (socketFd_ >= 0) { - IPC_LOG("Socket is opened\n"); - return false; - } + unlink(addr); - isServer_ = isServer; - - const char *ipcPath = isServer ? IPC_SERVER_SOCKET_ADDR : IPC_CLIENT_SOCKET_ADDR; - unlink(ipcPath); - - socketFd_ = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); - if (socketFd_ < 0) { + int socketFd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); + if (socketFd < 0) { IPC_LOG("Socket failed errno=%d\n", errno); return false; } @@ -60,35 +47,35 @@ bool IPCSkeleton::SocketListening(bool isServer) struct sockaddr_un socketAddr; memset(&socketAddr, 0, sizeof(socketAddr)); socketAddr.sun_family = AF_UNIX; - strcpy(socketAddr.sun_path, ipcPath); - int ret = bind(socketFd_, (struct sockaddr *)&socketAddr, sizeof(socketAddr)); + strcpy(socketAddr.sun_path, addr); + int ret = bind(socketFd, (struct sockaddr *)&socketAddr, sizeof(socketAddr)); if (ret < 0) { IPC_LOG("Bind socket failed errno=%d\n", errno); - close(socketFd_); - socketFd_ = -1; + close(socketFd); + socketFd = -1; return false; } - ret = listen(socketFd_, 3); + ret = listen(socketFd, 3); if (ret < 0) { IPC_LOG("listen socket failed errno=%d\n", errno); - close(socketFd_); - socketFd_ = -1; + close(socketFd); + socketFd = -1; return false; } - return true; + return socketFd; } -int IPCSkeleton::SocketReadFd() +int IPCSkeleton::SocketReadFd(int socketFd) { - if (socketFd_ < 0) { + if (socketFd < 0) { IPC_LOG("Read fd from an uninitialized socket\n"); return -1; } struct sockaddr_un acceptAddr; socklen_t sockLen = sizeof(acceptAddr); - int recvFd = accept(socketFd_, (struct sockaddr *)&acceptAddr, &sockLen); + int recvFd = accept(socketFd, (struct sockaddr *)&acceptAddr, &sockLen); if (recvFd < 0) { IPC_LOG("Accept failed errno=%d\n", errno); return -1; @@ -126,7 +113,7 @@ int IPCSkeleton::SocketReadFd() return *((int *)CMSG_DATA(cmsgPtr)); } -bool IPCSkeleton::SocketWriteFd(int fd) +bool IPCSkeleton::SocketWriteFd(const char *addr, int fd) { int socketFd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); if (socketFd < 0) { @@ -137,7 +124,7 @@ bool IPCSkeleton::SocketWriteFd(int fd) struct sockaddr_un socketAddr; memset(&socketAddr, 0, sizeof(socketAddr)); socketAddr.sun_family = AF_UNIX; - strcpy(socketAddr.sun_path, isServer_ ? IPC_CLIENT_SOCKET_ADDR : IPC_SERVER_SOCKET_ADDR); + strcpy(socketAddr.sun_path, addr); int ret = connect(socketFd, (struct sockaddr *)&socketAddr, sizeof(socketAddr)); if (ret < 0) { IPC_LOG("Connect failed errno=%d\n", errno); diff --git a/ipc_socket_manager.cpp b/ipc_socket_manager.cpp new file mode 100644 index 0000000..08c4635 --- /dev/null +++ b/ipc_socket_manager.cpp @@ -0,0 +1,24 @@ +#include "ipc_socket_manager.h" + +namespace OHOS { + +std::map< unsigned long long, int > IPCSocketManager::socketFdMap_; +std::mutex IPCSocketManager::mutex_; + +void IPCSocketManager::InsertSocketFd(unsigned long long handle, int socketFd) +{ + std::lock_guard< std::mutex > lock(mutex_); + socketFdMap_.emplace(handle, socketFd); +} + +int IPCSocketManager::FindSocketFd(unsigned long long handle) +{ + std::lock_guard< std::mutex > lock(mutex_); + auto it = socketFdMap_.find(handle); + if (it == socketFdMap_.end()) { + return -1; + } + return it->second; +} + +} // namespace OHOS \ No newline at end of file diff --git a/ipc_stub_manager.cpp b/ipc_stub_manager.cpp new file mode 100644 index 0000000..1f79ebd --- /dev/null +++ b/ipc_stub_manager.cpp @@ -0,0 +1,20 @@ +#include "ipc_stub_manager.h" + +namespace OHOS { + +std::map< unsigned long long, sptr< IPCObjectStub > > IPCStubManager::stubMap_; +std::mutex IPCStubManager::mutex_; + +unsigned long long IPCStubManager::GetHandleNum() +{ + std::lock_guard< std::mutex > lock(mutex_); + return stubMap_.size(); +} + +void IPCStubManager::InsertStub(unsigned long long handle, sptr< IPCObjectStub > stub) +{ + std::lock_guard< std::mutex > lock(mutex_); + stubMap_.emplace(handle, stub); +} + +}; // namespace OHOS \ No newline at end of file diff --git a/iremote_object.cpp b/iremote_object.cpp index 055258d..64887d2 100644 --- a/iremote_object.cpp +++ b/iremote_object.cpp @@ -1,13 +1,17 @@ #include "ipc_base.h" #include "iremote_object.h" #include "ipc_skeleton.h" +#include "ipc_socket_manager.h" -key_t g_send_shm_key = 0x544F53; -key_t g_receive_shm_key = 0x52544F; +key_t g_client_server_shmKey = 0x544F53; namespace OHOS { -const int32_t GET_SA_REQUEST_CODE = 2; +static const char *IPC_SERVER_SOCKET_ADDR = "/tmp/ipc.socket.server"; + +IRemoteObject::IRemoteObject() : handle_(0) {} + +IRemoteObject::~IRemoteObject() {} bool IRemoteObject::AddDeathRecipient(const sptr< DeathRecipient > &recipient) { @@ -23,41 +27,64 @@ int IRemoteObject::SendRequest(uint32_t code, MessageParcel &data, MessageParcel { IpcShmData *shmPtr = NULL; - if (code == GET_SA_REQUEST_CODE) { + if (code == GET_SA_REQUEST_CODE || (code >= WIFI_DEVICE_ABILITY_ID && code <= WIFI_P2P_ABILITY_ID)) { + reply.isContainHandle_ = true; + reply.RemoteObjectHandle_ = 0; return 0; } - shmPtr = OpenShm(g_send_shm_key); + shmPtr = OpenShm(g_client_server_shmKey); if (shmPtr == nullptr) { + IPC_LOG("Open server shm failed\n"); return -1; } + IPC_LOG("WAITING FOR PREVIOUS IPC\n"); + // waiting previous ipc while (shmPtr->needReply); + IPC_LOG("SENDING REQUEST with code=%u\n", code); + shmPtr->requestCode = code; shmPtr->inputSz = data.GetDataSize(); + if (shmPtr->inputSz > DATA_SIZE) { + IPC_LOG("Sending data overflow!"); + } memcpy(shmPtr->inputData, (void *)data.GetData(), shmPtr->inputSz); if (data.ContainFileDescriptors()) { + IPC_LOG("SENDING FD\n"); shmPtr->containFd = true; - if (!IPCSkeleton::SocketWriteFd(data.ReadFileDescriptor())) { + if (!IPCSkeleton::SocketWriteFd(IPC_SERVER_SOCKET_ADDR, data.ReadFileDescriptor())) { IPC_LOG("Send File Descriptor failed\n"); shmdt((void*)shmPtr); return -1; } } + if (data.isContainHandle_) { + shmPtr->containHandle = true; + shmPtr->handle = data.RemoteObjectHandle_; + } shmPtr->needReply = true; + // waiting receiver reply while (shmPtr->needReply); + IPC_LOG("RECEIVED DATA FROM REMOTE with code=%u\n", code); + reply.WriteUnpadBuffer(shmPtr->outputData, shmPtr->outputSz); if (shmPtr->containFd) { - if (!reply.WriteFileDescriptor(IPCSkeleton::SocketReadFd())) { - IPC_LOG("Reveive reply fd failed"); + if (!reply.WriteFileDescriptor(IPCSkeleton::SocketReadFd(IPCSocketManager::FindSocketFd(0)))) { + IPC_LOG("Receive reply fd failed"); shmdt((void *)shmPtr); return -1; } shmPtr->containFd = false; } + if (shmPtr->containHandle) { + reply.isContainHandle_ = true; + reply.RemoteObjectHandle_ = shmPtr->handle; + shmPtr->containHandle = false; + } shmdt((void *)shmPtr); return 0; } @@ -67,4 +94,9 @@ bool IRemoteObject::Marshalling(Parcel &parcel) const return true; } +unsigned long long IRemoteObject::GetHandle() +{ + return handle_; +} + } // namespace OHOS diff --git a/message_parcel.cpp b/message_parcel.cpp index 02253ef..4329fc9 100644 --- a/message_parcel.cpp +++ b/message_parcel.cpp @@ -6,10 +6,12 @@ #include "message_parcel.h" #include "ipc_skeleton.h" #include "iremote_object.h" +#include "ipc_proxy_manager.h" +#include "ipc_stub_manager.h" namespace OHOS { -MessageParcel::MessageParcel() : Parcel(), fd_(-1) {} +MessageParcel::MessageParcel() : Parcel(), isContainHandle_(false), fd_(-1) {} MessageParcel::~MessageParcel() {} @@ -60,13 +62,27 @@ const void *MessageParcel::ReadRawData(size_t size) return ReadUnpadBuffer(size); } +bool MessageParcel::ContainRemoteObject() +{ + return isContainHandle_; +} + sptr< IRemoteObject > MessageParcel::ReadRemoteObject() { - return IPCSkeleton::GetContextObject(); + if (!isContainHandle_) { + IPC_LOG("Read an invalid remote object!\n"); + return nullptr; + } + if (!RemoteObjectHandle_) { + return IPCSkeleton::GetContextObject(); + } + return IPCProxyManager::FindOrNewProxy(RemoteObjectHandle_); } bool MessageParcel::WriteRemoteObject(const sptr< IRemoteObject > &object) { + isContainHandle_ = true; + RemoteObjectHandle_ = object->GetHandle(); return true; } -- Gitee From 01a1571be35a2280c49b2f1afb02491bbb746300 Mon Sep 17 00:00:00 2001 From: zhengliming Date: Thu, 15 Sep 2022 20:32:48 +0800 Subject: [PATCH 2/2] Support to device_auth Now, IPC support two server, one for dsoftbus and the other for device_auth. Signed-off-by: zhengliming --- include/ipc_base.h | 5 ++- include/ipc_center.h | 8 +--- include/ipc_skeleton.h | 3 ++ include/iremote_broker.h | 92 +++++++++++++++++++++++++++++++++++++++- include/iremote_object.h | 25 ++++------- include/message_parcel.h | 5 +++ ipc_center.cpp | 20 +++++---- ipc_object_proxy.cpp | 13 +++--- ipc_proxy_manager.cpp | 2 +- ipc_skeleton.cpp | 17 ++++++++ ipc_stub_manager.cpp | 2 +- iremote_broker.cpp | 61 ++++++++++++++++++++++++++ iremote_object.cpp | 23 +++++++--- message_parcel.cpp | 17 +++++++- 14 files changed, 244 insertions(+), 49 deletions(-) create mode 100644 iremote_broker.cpp diff --git a/include/ipc_base.h b/include/ipc_base.h index 131bc06..9be4654 100644 --- a/include/ipc_base.h +++ b/include/ipc_base.h @@ -9,9 +9,12 @@ #include #define IPC_LOG(fmt, args...) \ - printf("[IPC LOG %s:%u]" fmt, __FILE__, __LINE__, ##args); + printf("[IPC LOG %s:%u]" fmt, __FILE__, __LINE__, ##args) +#define IPC_DEBUG(fmt, args...) \ +// printf("[IPC DEBUG %s:%u]" rmt, __FILE__, __LINE__, ##args) extern key_t g_client_server_shmKey; +extern key_t g_device_auth_shmKey; const int IPC_SHM_FLAG = IPC_CREAT | 0666; diff --git a/include/ipc_center.h b/include/ipc_center.h index ae14fa7..999bf54 100644 --- a/include/ipc_center.h +++ b/include/ipc_center.h @@ -8,15 +8,11 @@ namespace OHOS { class IpcCenter { public: - IpcCenter(); - ~IpcCenter(); static bool ShmInit(key_t ShmKey); - bool Init(bool isServer, IPCObjectStub *stub); - bool ThreadCreate(IPCObjectStub *stub); + static bool Init(bool isServer, IPCObjectStub *stub); + static bool ThreadCreate(IPCObjectStub *stub); static void ProcessHandle(key_t ShmKey, IPCObjectStub *ipcStub); static size_t threadNum_; -private: - key_t receive_shm_key_; }; } // namespace OHOS diff --git a/include/ipc_skeleton.h b/include/ipc_skeleton.h index d0157a8..3106243 100644 --- a/include/ipc_skeleton.h +++ b/include/ipc_skeleton.h @@ -22,9 +22,12 @@ public: static int SocketListening(const char *addr); static int SocketReadFd(int socketFd); static bool SocketWriteFd(const char *addr, int fd); + static bool SetDeviceAuthObj(sptr< IRemoteObject > obj); + static sptr< IRemoteObject > GetDeviceAuthObj(); private: static sptr< IRemoteObject > obj_; + static sptr< IRemoteObject > deviceAuthObj_; }; } // namespace OHOS diff --git a/include/iremote_broker.h b/include/iremote_broker.h index e6f5425..6d88e11 100644 --- a/include/iremote_broker.h +++ b/include/iremote_broker.h @@ -2,12 +2,102 @@ #define _IREMOTE_BROKER_H #ifdef __cplusplus +#include +#include +#include +#include "iremote_object.h" +#include "refbase.h" namespace OHOS { -template class BrokerDelegator { +class IRemoteBroker : public virtual RefBase { +public: + IRemoteBroker() = default; + virtual ~IRemoteBroker() override = default; + virtual sptr< IRemoteObject > AsObject() = 0; + static inline sptr< IRemoteBroker > AsImplement(const sptr< IRemoteObject > &object) + { + return nullptr; + } }; +#define DECLARE_INTERFACE_DESCRIPTOR(DESCRIPTOR) \ + static inline const std::u16string metaDescriptor_ = {DESCRIPTOR} ; \ + static inline const std::u16string &GetDescriptor() \ + { \ + return metaDescriptor_; \ + } + +template class BrokerCreator { +public: + BrokerCreator() = default; + ~BrokerCreator() = default; + sptr operator () (const sptr &object) + { + T *proxy = new (std::nothrow) T(object); + if (proxy != nullptr) { + return static_cast(proxy); + } + return nullptr; + }; +}; + +class BrokerRegistration { + using Constructor = std::function(const sptr &object)>; + +public: + static BrokerRegistration &Get(); + bool Register(const std::u16string &descriptor, const Constructor &creator); + void Unregister(const std::u16string &descriptor); + sptr NewInstance(const std::u16string &descriptor, const sptr &object); + +protected: + BrokerRegistration() = default; + ~BrokerRegistration(); + +private: + BrokerRegistration(const BrokerRegistration &) = delete; + BrokerRegistration(BrokerRegistration &&) = delete; + BrokerRegistration &operator = (const BrokerRegistration &) = delete; + BrokerRegistration &operator = (BrokerRegistration &&) = delete; + std::mutex creatorMutex_; + std::unordered_map creators_; +}; + +template class BrokerDelegator { +public: + BrokerDelegator(); + ~BrokerDelegator(); + +private: + BrokerDelegator(const BrokerDelegator &) = delete; + BrokerDelegator(BrokerDelegator &&) = delete; + BrokerDelegator &operator = (const BrokerDelegator &) = delete; + BrokerDelegator &operator = (BrokerDelegator &&) = delete; +}; + +template BrokerDelegator::BrokerDelegator() +{ + const std::u16string descriptor = T::GetDescriptor(); + BrokerRegistration ®istration = BrokerRegistration::Get(); + registration.Register(descriptor, BrokerCreator()); +} + +template BrokerDelegator::~BrokerDelegator() +{ + const std::u16string descriptor = T::GetDescriptor(); + BrokerRegistration ®istration = BrokerRegistration::Get(); + registration.Unregister(descriptor); +} + +template inline sptr iface_cast(const sptr &object) +{ + const std::u16string descriptor = INTERFACE::GetDescriptor(); + BrokerRegistration ®istration = BrokerRegistration::Get(); + sptr broker = registration.NewInstance(descriptor, object); + return static_cast(broker.GetRefPtr()); +} + }; #endif diff --git a/include/iremote_object.h b/include/iremote_object.h index ef1e6e3..dc422e0 100644 --- a/include/iremote_object.h +++ b/include/iremote_object.h @@ -3,26 +3,14 @@ #include "message_parcel.h" #include "message_option.h" +#include "iremote_broker.h" -namespace OHOS { +#define ERR_NONE 0 +#define NO_ERROR 0 -class IRemoteBroker : public virtual RefBase { -public: - IRemoteBroker() = default; - virtual ~IRemoteBroker() override = default; - virtual sptr< IRemoteObject > AsObject() = 0; - static inline sptr< IRemoteBroker > AsImplement(const sptr< IRemoteObject > &object) - { - return nullptr; - } -}; +namespace OHOS { -#define DECLARE_INTERFACE_DESCRIPTOR(DESCRIPTOR) \ - static inline const std::u16string metaDescriptor_ = {DESCRIPTOR} ; \ - static inline const std::u16string &GetDescriptor() \ - { \ - return metaDescriptor_; \ - } +class IRemoteBroker; class IRemoteObject : public virtual Parcelable { public: @@ -37,8 +25,11 @@ public: virtual bool AddDeathRecipient(const sptr< DeathRecipient > &recipient); virtual bool RemoveDeathRecipient(const sptr< DeathRecipient > &recipient); virtual bool Marshalling(Parcel &parcel) const override; + virtual bool IsProxyObject() const; + virtual sptr< IRemoteBroker > AsInterface(); unsigned long long GetHandle(); unsigned long long handle_; + bool isDSoftBusObj; }; } // namespace OHOS diff --git a/include/message_parcel.h b/include/message_parcel.h index 5390aea..91f93e1 100644 --- a/include/message_parcel.h +++ b/include/message_parcel.h @@ -1,6 +1,7 @@ #ifndef _MESSAGE_PARCEL_H_ #define _MESSAGE_PARCEL_H_ +#include #include "parcel.h" #include "refbase.h" @@ -18,12 +19,16 @@ public: bool ContainFileDescriptors() const; sptr< IRemoteObject > ReadRemoteObject(); bool WriteRemoteObject(const sptr< IRemoteObject > &object); + bool WriteInterfaceToken(std::u16string name); + std::u16string ReadInterfaceToken(); + size_t GetRawDataSize() const; bool ContainRemoteObject(); unsigned long long RemoteObjectHandle_; bool isContainHandle_; private: static constexpr size_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // 128M int fd_; + size_t rawDataSize_; }; } //namespace OHOS diff --git a/ipc_center.cpp b/ipc_center.cpp index e995935..1c33e6b 100644 --- a/ipc_center.cpp +++ b/ipc_center.cpp @@ -14,10 +14,6 @@ static const char *IPC_CLIENT_SOCKET_ADDR = "/tmp/ipc.socket.client"; size_t IpcCenter::threadNum_ = 0; -IpcCenter::IpcCenter() {} - -IpcCenter::~IpcCenter() {} - bool IpcCenter::ShmInit(key_t shmKey) { IpcShmData *shmPtr = OpenShm(shmKey); @@ -50,6 +46,11 @@ bool IpcCenter::Init(bool isServer, IPCObjectStub *stub) return false; } + if (isServer && !ShmInit(g_device_auth_shmKey)) { + IPC_LOG("Device auth shm init failed\n"); + return false; + } + if (stub->recvFd_ >= 0) { close(stub->recvFd_); } @@ -74,7 +75,7 @@ void IpcCenter::ProcessHandle(key_t shmKey, IPCObjectStub *ipcStub) IPC_LOG("Open shm failed"); return; } - IPC_LOG("STUB LISTENING with handle=%llx\n", ipcStub->handle_); + IPC_DEBUG("STUB LISTENING with handle=%llx\n", ipcStub->handle_); do { while (!shmPtr->needReply) { usleep(10); @@ -97,7 +98,7 @@ void IpcCenter::ProcessHandle(key_t shmKey, IPCObjectStub *ipcStub) continue; } - IPC_LOG("PROCESSING REMOTE REQUEST with handle=%llx\n", ipcStub->handle_); + IPC_DEBUG("PROCESSING REMOTE REQUEST with handle=%llx\n", ipcStub->handle_); MessageParcel data, reply; MessageOption option; data.WriteUnpadBuffer(shmPtr->inputData, shmPtr->inputSz); @@ -133,16 +134,17 @@ void IpcCenter::ProcessHandle(key_t shmKey, IPCObjectStub *ipcStub) shmPtr->containHandle = true; } shmPtr->needReply = false; - IPC_LOG("IPC STUB PROCESS END with handle=%llx\n", ipcStub->handle_); + IPC_DEBUG("IPC STUB PROCESS END with handle=%llx\n", ipcStub->handle_); } while (!ipcStub->needStop_); - IPC_LOG("STUB LISTENING END with handle=%llx\n", ipcStub->handle_); + IPC_DEBUG("STUB LISTENING END with handle=%llx\n", ipcStub->handle_); shmdt((void*)shmPtr); } bool IpcCenter::ThreadCreate(IPCObjectStub *stub) { ++threadNum_; - std::thread new_thread(std::bind(&IpcCenter::ProcessHandle, g_client_server_shmKey, stub)); + std::thread new_thread(std::bind(&IpcCenter::ProcessHandle, + stub->isDSoftBusObj ? g_client_server_shmKey : g_device_auth_shmKey, stub)); new_thread.detach(); return true; } diff --git a/ipc_object_proxy.cpp b/ipc_object_proxy.cpp index 2701e2d..8368e95 100644 --- a/ipc_object_proxy.cpp +++ b/ipc_object_proxy.cpp @@ -28,15 +28,16 @@ int IPCObjectProxy::SendRequest(uint32_t code, MessageParcel &data, MessageParce shmPtr = OpenShm(sendShmKey_); if (shmPtr == nullptr) { + IPC_LOG("Open Stub shm failed\n"); return -1; } - IPC_LOG("WAITING FOR PREVIOUS IPC\n"); + IPC_DEBUG("WAITING FOR PREVIOUS IPC\n"); // waiting previous ipc while (shmPtr->needReply); - IPC_LOG("SENDING REQUEST with code=%u\n", code); + IPC_DEBUG("SENDING REQUEST with code=%u\n", code); shmPtr->requestCode = code; shmPtr->inputSz = data.GetDataSize(); @@ -45,7 +46,7 @@ int IPCObjectProxy::SendRequest(uint32_t code, MessageParcel &data, MessageParce } memcpy(shmPtr->inputData, (void *)data.GetData(), shmPtr->inputSz); if (data.ContainFileDescriptors()) { - IPC_LOG("SENDING FD\n"); + IPC_DEBUG("SENDING FD\n"); shmPtr->containFd = true; if (!IPCSkeleton::SocketWriteFd(socketAddr_, data.ReadFileDescriptor())) { IPC_LOG("Send File Descriptor failed\n"); @@ -59,11 +60,11 @@ int IPCObjectProxy::SendRequest(uint32_t code, MessageParcel &data, MessageParce } shmPtr->needReply = true; - IPC_LOG("WAITING STUB REPLY with handle=%llx\n", handle_); + IPC_DEBUG("WAITING STUB REPLY with handle=%llx\n", handle_); // waiting receiver reply while (shmPtr->needReply); - IPC_LOG("RECEIVED DATA FROM REMOTE with code=%u\n", code); + IPC_DEBUG("RECEIVED DATA FROM REMOTE with code=%u\n", code); reply.WriteUnpadBuffer(shmPtr->outputData, shmPtr->outputSz); if (shmPtr->containFd) { @@ -97,4 +98,4 @@ void IPCObjectProxy::SendObituary() } } -}; // namespace OHOS \ No newline at end of file +} // namespace OHOS \ No newline at end of file diff --git a/ipc_proxy_manager.cpp b/ipc_proxy_manager.cpp index baf63e9..36f8295 100644 --- a/ipc_proxy_manager.cpp +++ b/ipc_proxy_manager.cpp @@ -28,4 +28,4 @@ void IPCProxyManager::CleanProxy(unsigned long long handle) } } -}; // namespace OHOS \ No newline at end of file +} // namespace OHOS \ No newline at end of file diff --git a/ipc_skeleton.cpp b/ipc_skeleton.cpp index d7cfd20..7259cf9 100644 --- a/ipc_skeleton.cpp +++ b/ipc_skeleton.cpp @@ -9,6 +9,7 @@ namespace OHOS { sptr< IRemoteObject > IPCSkeleton::obj_ = nullptr; +sptr< IRemoteObject > IPCSkeleton::deviceAuthObj_ = nullptr; pid_t IPCSkeleton::GetCallingPid() { @@ -34,6 +35,22 @@ sptr< IRemoteObject > IPCSkeleton::GetContextObject() return obj_; } +bool IPCSkeleton::SetDeviceAuthObj(sptr< IRemoteObject > obj) +{ + deviceAuthObj_ = obj; + deviceAuthObj_->isDSoftBusObj = false; + return true; +} + +sptr< IRemoteObject > IPCSkeleton::GetDeviceAuthObj() +{ + if (deviceAuthObj_ == nullptr) { + deviceAuthObj_ = new IRemoteObject(); + deviceAuthObj_->isDSoftBusObj = false; + } + return deviceAuthObj_; +} + int IPCSkeleton::SocketListening(const char *addr) { unlink(addr); diff --git a/ipc_stub_manager.cpp b/ipc_stub_manager.cpp index 1f79ebd..5ea2434 100644 --- a/ipc_stub_manager.cpp +++ b/ipc_stub_manager.cpp @@ -17,4 +17,4 @@ void IPCStubManager::InsertStub(unsigned long long handle, sptr< IPCObjectStub > stubMap_.emplace(handle, stub); } -}; // namespace OHOS \ No newline at end of file +} // namespace OHOS \ No newline at end of file diff --git a/iremote_broker.cpp b/iremote_broker.cpp new file mode 100644 index 0000000..b932228 --- /dev/null +++ b/iremote_broker.cpp @@ -0,0 +1,61 @@ +#include "iremote_broker.h" +#include + +namespace OHOS { +BrokerRegistration &BrokerRegistration::Get() +{ + static BrokerRegistration instance; + return instance; +} + +BrokerRegistration::~BrokerRegistration() +{ + std::lock_guard lockGuard(creatorMutex_); + for (auto it = creators_.begin(); it != creators_.end();) { + it = creators_.erase(it); + } +} + +bool BrokerRegistration::Register(const std::u16string &descriptor, const Constructor &creator) +{ + if (descriptor.empty()) { + return false; + } + + std::lock_guard lockGuard(creatorMutex_); + auto it = creators_.find(descriptor); + if (it == creators_.end()) { + return creators_.insert({ descriptor, creator }).second; + } + return false; +} + +void BrokerRegistration::Unregister(const std::u16string &descriptor) +{ + std::lock_guard lockGuard(creatorMutex_); + if (!descriptor.empty()) { + auto it = creators_.find(descriptor); + if (it != creators_.end()) { + creators_.erase(it); + } + } +} + +sptr BrokerRegistration::NewInstance(const std::u16string &descriptor, const sptr &object) +{ + std::lock_guard lockGuard(creatorMutex_); + + sptr broker; + if (object != nullptr) { + if (object->IsProxyObject()) { + auto it = creators_.find(descriptor); + if (it != creators_.end()) { + broker = it->second(object); + } + } else { + broker = object->AsInterface().GetRefPtr(); + } + } + return broker; +} +} // namespace OHOS diff --git a/iremote_object.cpp b/iremote_object.cpp index 64887d2..e2be133 100644 --- a/iremote_object.cpp +++ b/iremote_object.cpp @@ -4,12 +4,13 @@ #include "ipc_socket_manager.h" key_t g_client_server_shmKey = 0x544F53; +key_t g_device_auth_shmKey = 0x52544F; namespace OHOS { static const char *IPC_SERVER_SOCKET_ADDR = "/tmp/ipc.socket.server"; -IRemoteObject::IRemoteObject() : handle_(0) {} +IRemoteObject::IRemoteObject() : handle_(0), isDSoftBusObj(true) {} IRemoteObject::~IRemoteObject() {} @@ -33,18 +34,18 @@ int IRemoteObject::SendRequest(uint32_t code, MessageParcel &data, MessageParcel return 0; } - shmPtr = OpenShm(g_client_server_shmKey); + shmPtr = OpenShm(isDSoftBusObj ? g_client_server_shmKey : g_device_auth_shmKey); if (shmPtr == nullptr) { IPC_LOG("Open server shm failed\n"); return -1; } - IPC_LOG("WAITING FOR PREVIOUS IPC\n"); + IPC_DEBUG("WAITING FOR PREVIOUS IPC\n"); // waiting previous ipc while (shmPtr->needReply); - IPC_LOG("SENDING REQUEST with code=%u\n", code); + IPC_DEBUG("SENDING REQUEST with code=%u\n", code); shmPtr->requestCode = code; shmPtr->inputSz = data.GetDataSize(); @@ -53,7 +54,7 @@ int IRemoteObject::SendRequest(uint32_t code, MessageParcel &data, MessageParcel } memcpy(shmPtr->inputData, (void *)data.GetData(), shmPtr->inputSz); if (data.ContainFileDescriptors()) { - IPC_LOG("SENDING FD\n"); + IPC_DEBUG("SENDING FD\n"); shmPtr->containFd = true; if (!IPCSkeleton::SocketWriteFd(IPC_SERVER_SOCKET_ADDR, data.ReadFileDescriptor())) { IPC_LOG("Send File Descriptor failed\n"); @@ -69,7 +70,7 @@ int IRemoteObject::SendRequest(uint32_t code, MessageParcel &data, MessageParcel // waiting receiver reply while (shmPtr->needReply); - IPC_LOG("RECEIVED DATA FROM REMOTE with code=%u\n", code); + IPC_DEBUG("RECEIVED DATA FROM REMOTE with code=%u\n", code); reply.WriteUnpadBuffer(shmPtr->outputData, shmPtr->outputSz); if (shmPtr->containFd) { @@ -99,4 +100,14 @@ unsigned long long IRemoteObject::GetHandle() return handle_; } +sptr< IRemoteBroker > IRemoteObject::Asnterface() +{ + return nullptr; +} + +bool IRemoteObject::IsProxyObject() const +{ + return true; +} + } // namespace OHOS diff --git a/message_parcel.cpp b/message_parcel.cpp index 4329fc9..a1e0a81 100644 --- a/message_parcel.cpp +++ b/message_parcel.cpp @@ -49,7 +49,7 @@ bool MessageParcel::WriteRawData(const void *data, size_t size) if (!WriteInt32(size)) { return false; } - + rawDataSize_ = size; return WriteUnpadBuffer(data, size); } @@ -59,6 +59,7 @@ const void *MessageParcel::ReadRawData(size_t size) if (static_cast< unsigned int >(bufferSize) != size) { return nullptr; } + rawDataSize_ = size; return ReadUnpadBuffer(size); } @@ -86,4 +87,18 @@ bool MessageParcel::WriteRemoteObject(const sptr< IRemoteObject > &object) return true; } +bool MessageParcel::WriteInterfaceToken(std::u16string name) { + return WriteString16(name); +} + +std::u16string MessageParcel::ReadInterfaceToken() +{ + return ReadString16(); +} + +size_t MessageParcel::GetRawDataSize() const +{ + return rawDataSize_; +} + } //namespace OHOS -- Gitee