client_channel.cpp revision fd22b3e5ad1aae1fc3de54801f33466db3c9b3fe
1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "uds/client_channel.h" 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <errno.h> 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <log/log.h> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/epoll.h> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/socket.h> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/client.h> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/service_endpoint.h> 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/ipc_helper.h> 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx { 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace uds { 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace { 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct TransactionState { 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetLocalFileHandle(int index, LocalHandle* handle) { 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (index < 0) { 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko handle->Reset(index); 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(index) < response.file_descriptors.size()) { 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = std::move(response.file_descriptors[index]); 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetLocalChannelHandle(int index, LocalChannelHandle* handle) { 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (index < 0) { 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = LocalChannelHandle{nullptr, index}; 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(index) < response.channels.size()) { 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto& channel_info = response.channels[index]; 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = ChannelManager::Get().CreateHandle( 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::move(channel_info.data_fd), std::move(channel_info.event_fd)); 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko FileReference PushFileHandle(BorrowedHandle handle) { 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request.file_descriptors.push_back(std::move(handle)); 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return request.file_descriptors.size() - 1; 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference PushChannelHandle(BorrowedChannelHandle handle) { 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 536890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 546890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (auto* channel_data = 556890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ChannelManager::Get().GetChannelData(handle.value())) { 566890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ChannelInfo<BorrowedHandle> channel_info; 576890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_info.data_fd.Reset(handle.value()); 586890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_info.event_fd = channel_data->event_receiver.event_fd(); 596890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka request.channels.push_back(std::move(channel_info)); 606890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return request.channels.size() - 1; 616890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 626890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return -1; 636890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko RequestHeader<BorrowedHandle> request; 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ResponseHeader<LocalHandle> response; 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 7009aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReadAndDiscardData(const BorrowedHandle& socket_fd, size_t size) { 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (size > 0) { 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If there is more data to read in the message than the buffers provided 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // by the caller, read and discard the extra data from the socket. 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko char buffer[1024]; 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_to_read = std::min(sizeof(buffer), size); 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = ReceiveData(socket_fd, buffer, size_to_read); 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size -= size_to_read; 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // We still want to return EIO error to the caller in case we had unexpected 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // data in the socket stream. 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 8609aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> SendRequest(const BorrowedHandle& socket_fd, 8709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko TransactionState* transaction_state, int opcode, 8809aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko const iovec* send_vector, size_t send_count, 8909aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko size_t max_recv_len) { 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_len = CountVectorSize(send_vector, send_count); 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko InitRequest(&transaction_state->request, opcode, send_len, max_recv_len, 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko false); 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = SendData(socket_fd, transaction_state->request); 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status && send_len > 0) 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = SendDataVector(socket_fd, send_vector, send_count); 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 9909aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReceiveResponse(const BorrowedHandle& socket_fd, 10009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko TransactionState* transaction_state, 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, size_t receive_count, 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t max_recv_len) { 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = ReceiveData(socket_fd, &transaction_state->response); 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (transaction_state->response.recv_len > 0) { 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<iovec> read_buffers; 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_remaining = 0; 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (transaction_state->response.recv_len != max_recv_len) { 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If the receive buffer not exactly the size of data available, recreate 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the vector list to consume the data exactly since ReceiveDataVector() 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // validates that the number of bytes received equals the number of bytes 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // requested. 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_remaining = transaction_state->response.recv_len; 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < receive_count && size_remaining > 0; i++) { 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko read_buffers.push_back(receive_vector[i]); 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko iovec& last_vec = read_buffers.back(); 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (last_vec.iov_len > size_remaining) 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko last_vec.iov_len = size_remaining; 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_remaining -= last_vec.iov_len; 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector = read_buffers.data(); 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_count = read_buffers.size(); 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReceiveDataVector(socket_fd, receive_vector, receive_count); 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status && size_remaining > 0) 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReadAndDiscardData(socket_fd, size_remaining); 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoClientChannel::ClientChannel(LocalChannelHandle channel_handle) 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : channel_handle_{std::move(channel_handle)} { 1376890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_data_ = ChannelManager::Get().GetChannelData(channel_handle_.value()); 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::unique_ptr<pdx::ClientChannel> ClientChannel::Create( 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle channel_handle) { 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::unique_ptr<pdx::ClientChannel>{ 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko new ClientChannel{std::move(channel_handle)}}; 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoClientChannel::~ClientChannel() { 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_handle_) 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko shutdown(channel_handle_.value(), SHUT_WR); 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid* ClientChannel::AllocateTransactionState() { return new TransactionState; } 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid ClientChannel::FreeTransactionState(void* state) { 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko delete static_cast<TransactionState*>(state); 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> ClientChannel::SendImpulse(int opcode, const void* buffer, 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t length) { 159fd22b3e5ad1aae1fc3de54801f33466db3c9b3feAlex Vakulenko std::unique_lock<std::mutex> lock(socket_mutex_); 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<void> status; 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::pdx::uds::RequestHeader<BorrowedHandle> request; 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (length > request.impulse_payload.size() || 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko (buffer == nullptr && length != 0)) { 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetError(EINVAL); 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko InitRequest(&request, opcode, length, 0, true); 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(request.impulse_payload.data(), buffer, length); 17009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko return SendData(BorrowedHandle{channel_handle_.value()}, request); 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> ClientChannel::SendAndReceive(void* transaction_state, int opcode, 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* send_vector, 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t receive_count) { 178fd22b3e5ad1aae1fc3de54801f33466db3c9b3feAlex Vakulenko std::unique_lock<std::mutex> lock(socket_mutex_); 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> result; 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if ((send_vector == nullptr && send_count != 0) || 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko (receive_vector == nullptr && receive_count != 0)) { 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko result.SetError(EINVAL); 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return result; 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t max_recv_len = CountVectorSize(receive_vector, receive_count); 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 18909aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko auto status = SendRequest(BorrowedHandle{channel_handle_.value()}, state, 19009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko opcode, send_vector, send_count, max_recv_len); 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) { 19209aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko status = ReceiveResponse(BorrowedHandle{channel_handle_.value()}, state, 19309aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko receive_vector, receive_count, max_recv_len); 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!result.PropagateError(status)) { 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int return_code = state->response.ret_code; 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (return_code >= 0) 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko result.SetValue(return_code); 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko result.SetError(-return_code); 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return result; 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> ClientChannel::SendWithInt(void* transaction_state, int opcode, 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* send_vector, 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t receive_count) { 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return SendAndReceive(transaction_state, opcode, send_vector, send_count, 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector, receive_count); 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<LocalHandle> ClientChannel::SendWithFileHandle( 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, int opcode, const iovec* send_vector, 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, const iovec* receive_vector, size_t receive_count) { 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> int_status = 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko SendAndReceive(transaction_state, opcode, send_vector, send_count, 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector, receive_count); 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalHandle> status; 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status.PropagateError(int_status)) 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle handle; 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (state->GetLocalFileHandle(int_status.get(), &handle)) { 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetValue(std::move(handle)); 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetError(EINVAL); 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<LocalChannelHandle> ClientChannel::SendWithChannelHandle( 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, int opcode, const iovec* send_vector, 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, const iovec* receive_vector, size_t receive_count) { 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> int_status = 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko SendAndReceive(transaction_state, opcode, send_vector, send_count, 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector, receive_count); 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalChannelHandle> status; 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status.PropagateError(int_status)) 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle handle; 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (state->GetLocalChannelHandle(int_status.get(), &handle)) { 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetValue(std::move(handle)); 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetError(EINVAL); 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoFileReference ClientChannel::PushFileHandle(void* transaction_state, 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const LocalHandle& handle) { 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Borrow()); 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoFileReference ClientChannel::PushFileHandle(void* transaction_state, 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const BorrowedHandle& handle) { 262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Duplicate()); 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoChannelReference ClientChannel::PushChannelHandle( 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, const LocalChannelHandle& handle) { 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Borrow()); 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoChannelReference ClientChannel::PushChannelHandle( 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, const BorrowedChannelHandle& handle) { 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Duplicate()); 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ClientChannel::GetFileHandle(void* transaction_state, FileReference ref, 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle* handle) const { 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->GetLocalFileHandle(ref, handle); 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ClientChannel::GetChannelHandle(void* transaction_state, 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference ref, 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle* handle) const { 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->GetLocalChannelHandle(ref, handle); 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace uds 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 294