diff options
author | 2023-02-14 18:19:51 +0000 | |
---|---|---|
committer | 2023-02-14 18:19:51 +0000 | |
commit | 968b998ac37b8389b69ee5c500476140eef1969c (patch) | |
tree | b67fec99d6b540ac2a1e8fbfc25219972b67f24b | |
parent | 2aef5c6509035028f71f9f6518faa097085f134c (diff) | |
parent | 346370604e11bcfaa0a5eaa4aff70a784d59fdbd (diff) |
Merge "rpc_binder: Create C/Rust bindings for inet socket"
-rw-r--r-- | libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp | 13 | ||||
-rw-r--r-- | libs/binder/libbinder_rpc_unstable.cpp | 21 | ||||
-rw-r--r-- | libs/binder/libbinder_rpc_unstable.map.txt | 1 | ||||
-rw-r--r-- | libs/binder/rust/rpcbinder/src/server.rs | 23 | ||||
-rw-r--r-- | libs/binder/rust/rpcbinder/src/session.rs | 26 |
5 files changed, 84 insertions, 0 deletions
diff --git a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp index 3ebbed6965..42d226b805 100644 --- a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp +++ b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp @@ -57,6 +57,15 @@ enum class ARpcSession_FileDescriptorTransportMode { // could not be started. [[nodiscard]] ARpcServer* ARpcServer_newUnixDomainBootstrap(AIBinder* service, int bootstrapFd); +// Starts an RPC server on a given IP address+port and a given IBinder object. +// Returns an opaque handle to the running server instance, or null if the server +// could not be started. +// Does not take ownership of `service`. +// Returns an opaque handle to the running service instance, or null if the server +// could not be started. +[[nodiscard]] ARpcServer* ARpcServer_newInet(AIBinder* service, const char* address, + unsigned int port); + // Sets the list of supported file descriptor transport modes of this RPC server. void ARpcServer_setSupportedFileDescriptorTransportModes( ARpcServer* handle, @@ -98,6 +107,10 @@ AIBinder* ARpcSession_setupUnixDomainClient(ARpcSession* session, const char* na AIBinder* ARpcSession_setupUnixDomainBootstrapClient(ARpcSession* session, int bootstrapFd); +// Connects to an RPC server over an INET socket at a given IP address on a given port. +// Returns the root Binder object of the server. +AIBinder* ARpcSession_setupInet(ARpcSession* session, const char* address, unsigned int port); + // Connects to an RPC server with preconnected file descriptors. // // requestFd should connect to the server and return a valid file descriptor, or diff --git a/libs/binder/libbinder_rpc_unstable.cpp b/libs/binder/libbinder_rpc_unstable.cpp index e7943ddf2f..daff8c1e16 100644 --- a/libs/binder/libbinder_rpc_unstable.cpp +++ b/libs/binder/libbinder_rpc_unstable.cpp @@ -145,6 +145,17 @@ ARpcServer* ARpcServer_newUnixDomainBootstrap(AIBinder* service, int bootstrapFd return createObjectHandle<ARpcServer>(server); } +ARpcServer* ARpcServer_newInet(AIBinder* service, const char* address, unsigned int port) { + auto server = RpcServer::make(); + if (status_t status = server->setupInetServer(address, port, nullptr); status != OK) { + LOG(ERROR) << "Failed to set up inet RPC server with address " << address << " and port " + << port << " error: " << statusToString(status).c_str(); + return nullptr; + } + server->setRootObject(AIBinder_toPlatformBinder(service)); + return createObjectHandle<ARpcServer>(server); +} + void ARpcServer_setSupportedFileDescriptorTransportModes( ARpcServer* handle, const ARpcSession_FileDescriptorTransportMode modes[], size_t modes_len) { @@ -222,6 +233,16 @@ AIBinder* ARpcSession_setupUnixDomainBootstrapClient(ARpcSession* handle, int bo return AIBinder_fromPlatformBinder(session->getRootObject()); } +AIBinder* ARpcSession_setupInet(ARpcSession* handle, const char* address, unsigned int port) { + auto session = handleToStrongPointer<RpcSession>(handle); + if (status_t status = session->setupInetClient(address, port); status != OK) { + LOG(ERROR) << "Failed to set up inet RPC client with address " << address << " and port " + << port << " error: " << statusToString(status).c_str(); + return nullptr; + } + return AIBinder_fromPlatformBinder(session->getRootObject()); +} + AIBinder* ARpcSession_setupPreconnectedClient(ARpcSession* handle, int (*requestFd)(void* param), void* param) { auto session = handleToStrongPointer<RpcSession>(handle); diff --git a/libs/binder/libbinder_rpc_unstable.map.txt b/libs/binder/libbinder_rpc_unstable.map.txt index 1bc2416533..63679c28d0 100644 --- a/libs/binder/libbinder_rpc_unstable.map.txt +++ b/libs/binder/libbinder_rpc_unstable.map.txt @@ -2,6 +2,7 @@ LIBBINDER_RPC_UNSTABLE_SHIM { # platform-only global: ARpcServer_free; ARpcServer_join; + ARpcServer_newInet; ARpcServer_newInitUnixDomain; ARpcServer_newVsock; ARpcServer_shutdown; diff --git a/libs/binder/rust/rpcbinder/src/server.rs b/libs/binder/rust/rpcbinder/src/server.rs index 761b306a1e..c87876ac15 100644 --- a/libs/binder/rust/rpcbinder/src/server.rs +++ b/libs/binder/rust/rpcbinder/src/server.rs @@ -102,6 +102,29 @@ impl RpcServer { } } + /// Creates a binder RPC server, serving the supplied binder service implementation on the given + /// IP address and port. + pub fn new_inet(mut service: SpIBinder, address: &str, port: u32) -> Result<RpcServer, Error> { + let address = match CString::new(address) { + Ok(s) => s, + Err(e) => { + log::error!("Cannot convert {} to CString. Error: {:?}", address, e); + return Err(Error::from(ErrorKind::InvalidInput)); + } + }; + let service = service.as_native_mut(); + + // SAFETY: Service ownership is transferring to the server and won't be valid afterward. + // Plus the binder objects are threadsafe. + unsafe { + Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newInet( + service, + address.as_ptr(), + port, + )) + } + } + unsafe fn checked_from_ptr(ptr: *mut ARpcServer) -> Result<RpcServer, Error> { if ptr.is_null() { return Err(Error::new(ErrorKind::Other, "Failed to start server")); diff --git a/libs/binder/rust/rpcbinder/src/session.rs b/libs/binder/rust/rpcbinder/src/session.rs index 62fedb1ffa..0b517cf613 100644 --- a/libs/binder/rust/rpcbinder/src/session.rs +++ b/libs/binder/rust/rpcbinder/src/session.rs @@ -144,6 +144,32 @@ impl RpcSessionRef { Self::get_interface(service) } + /// Connects to an RPC Binder server over inet socket at the given address and port. + pub fn setup_inet_client<T: FromIBinder + ?Sized>( + &self, + address: &str, + port: u32, + ) -> Result<Strong<T>, StatusCode> { + let address = match CString::new(address) { + Ok(s) => s, + Err(e) => { + log::error!("Cannot convert {} to CString. Error: {:?}", address, e); + return Err(StatusCode::BAD_VALUE); + } + }; + + // SAFETY: AIBinder returned by ARpcSession_setupInet has correct reference + // count, and the ownership can safely be taken by new_spibinder. + let service = unsafe { + new_spibinder(binder_rpc_unstable_bindgen::ARpcSession_setupInet( + self.as_ptr(), + address.as_ptr(), + port, + )) + }; + Self::get_interface(service) + } + /// Connects to an RPC Binder server, using the given callback to get (and /// take ownership of) file descriptors already connected to it. pub fn setup_preconnected_client<T: FromIBinder + ?Sized>( |