ipc_helper.h revision e4eec20f6263f4a42ae462456f60ea6c4518bb0a
1#ifndef ANDROID_PDX_UDS_IPC_HELPER_H_ 2#define ANDROID_PDX_UDS_IPC_HELPER_H_ 3 4#include <sys/socket.h> 5#include <utility> 6#include <vector> 7 8#include <pdx/rpc/serializable.h> 9#include <pdx/rpc/serialization.h> 10#include <pdx/status.h> 11#include <pdx/utility.h> 12 13namespace android { 14namespace pdx { 15namespace uds { 16 17#define RETRY_EINTR(fnc_call) \ 18 ([&]() -> decltype(fnc_call) { \ 19 decltype(fnc_call) result; \ 20 do { \ 21 result = (fnc_call); \ 22 } while (result == -1 && errno == EINTR); \ 23 return result; \ 24 })() 25 26class SendPayload : public MessageWriter, public OutputResourceMapper { 27 public: 28 Status<void> Send(int socket_fd); 29 Status<void> Send(int socket_fd, const ucred* cred); 30 31 // MessageWriter 32 void* GetNextWriteBufferSection(size_t size) override; 33 OutputResourceMapper* GetOutputResourceMapper() override; 34 35 // OutputResourceMapper 36 FileReference PushFileHandle(const LocalHandle& handle) override; 37 FileReference PushFileHandle(const BorrowedHandle& handle) override; 38 FileReference PushFileHandle(const RemoteHandle& handle) override; 39 ChannelReference PushChannelHandle(const LocalChannelHandle& handle) override; 40 ChannelReference PushChannelHandle( 41 const BorrowedChannelHandle& handle) override; 42 ChannelReference PushChannelHandle( 43 const RemoteChannelHandle& handle) override; 44 45 private: 46 ByteBuffer buffer_; 47 std::vector<int> file_handles_; 48}; 49 50class ReceivePayload : public MessageReader, public InputResourceMapper { 51 public: 52 Status<void> Receive(int socket_fd); 53 Status<void> Receive(int socket_fd, ucred* cred); 54 55 // MessageReader 56 BufferSection GetNextReadBufferSection() override; 57 void ConsumeReadBufferSectionData(const void* new_start) override; 58 InputResourceMapper* GetInputResourceMapper() override; 59 60 // InputResourceMapper 61 bool GetFileHandle(FileReference ref, LocalHandle* handle) override; 62 bool GetChannelHandle(ChannelReference ref, 63 LocalChannelHandle* handle) override; 64 65 private: 66 ByteBuffer buffer_; 67 std::vector<LocalHandle> file_handles_; 68 size_t read_pos_{0}; 69}; 70 71template <typename FileHandleType> 72class ChannelInfo { 73 public: 74 FileHandleType data_fd; 75 FileHandleType event_fd; 76 77 private: 78 PDX_SERIALIZABLE_MEMBERS(ChannelInfo, data_fd, event_fd); 79}; 80 81template <typename FileHandleType> 82class RequestHeader { 83 public: 84 int32_t op{0}; 85 ucred cred; 86 uint32_t send_len{0}; 87 uint32_t max_recv_len{0}; 88 std::vector<FileHandleType> file_descriptors; 89 std::vector<ChannelInfo<FileHandleType>> channels; 90 std::array<uint8_t, 32> impulse_payload; 91 bool is_impulse{false}; 92 93 private: 94 PDX_SERIALIZABLE_MEMBERS(RequestHeader, op, send_len, max_recv_len, 95 file_descriptors, channels, impulse_payload, 96 is_impulse); 97}; 98 99template <typename FileHandleType> 100class ResponseHeader { 101 public: 102 int32_t ret_code{0}; 103 uint32_t recv_len{0}; 104 std::vector<FileHandleType> file_descriptors; 105 std::vector<ChannelInfo<FileHandleType>> channels; 106 107 private: 108 PDX_SERIALIZABLE_MEMBERS(ResponseHeader, ret_code, recv_len, file_descriptors, 109 channels); 110}; 111 112template <typename T> 113inline Status<void> SendData(int socket_fd, const T& data) { 114 SendPayload payload; 115 rpc::Serialize(data, &payload); 116 return payload.Send(socket_fd); 117} 118 119template <typename FileHandleType> 120inline Status<void> SendData(int socket_fd, 121 const RequestHeader<FileHandleType>& request) { 122 SendPayload payload; 123 rpc::Serialize(request, &payload); 124 return payload.Send(socket_fd, &request.cred); 125} 126 127Status<void> SendData(int socket_fd, const void* data, size_t size); 128Status<void> SendDataVector(int socket_fd, const iovec* data, size_t count); 129 130template <typename T> 131inline Status<void> ReceiveData(int socket_fd, T* data) { 132 ReceivePayload payload; 133 Status<void> status = payload.Receive(socket_fd); 134 if (status && rpc::Deserialize(data, &payload) != rpc::ErrorCode::NO_ERROR) 135 status.SetError(EIO); 136 return status; 137} 138 139template <typename FileHandleType> 140inline Status<void> ReceiveData(int socket_fd, 141 RequestHeader<FileHandleType>* request) { 142 ReceivePayload payload; 143 Status<void> status = payload.Receive(socket_fd, &request->cred); 144 if (status && rpc::Deserialize(request, &payload) != rpc::ErrorCode::NO_ERROR) 145 status.SetError(EIO); 146 return status; 147} 148 149Status<void> ReceiveData(int socket_fd, void* data, size_t size); 150Status<void> ReceiveDataVector(int socket_fd, const iovec* data, size_t count); 151 152size_t CountVectorSize(const iovec* data, size_t count); 153void InitRequest(android::pdx::uds::RequestHeader<BorrowedHandle>* request, 154 int opcode, uint32_t send_len, uint32_t max_recv_len, 155 bool is_impulse); 156 157Status<void> WaitForEndpoint(const std::string& endpoint_path, 158 int64_t timeout_ms); 159 160} // namespace uds 161} // namespace pdx 162} // namespace android 163 164#endif // ANDROID_PDX_UDS_IPC_HELPER_H_ 165