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( 3652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka std::move(channel_info.data_fd), 3752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka std::move(channel_info.pollin_event_fd), 3852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka std::move(channel_info.pollhup_event_fd)); 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko FileReference PushFileHandle(BorrowedHandle handle) { 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request.file_descriptors.push_back(std::move(handle)); 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return request.file_descriptors.size() - 1; 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference PushChannelHandle(BorrowedChannelHandle handle) { 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 556890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 566890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (auto* channel_data = 576890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ChannelManager::Get().GetChannelData(handle.value())) { 5852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ChannelInfo<BorrowedHandle> channel_info{ 5952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka channel_data->data_fd(), channel_data->pollin_event_fd(), 6052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka channel_data->pollhup_event_fd()}; 616890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka request.channels.push_back(std::move(channel_info)); 626890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return request.channels.size() - 1; 636890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 646890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return -1; 656890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko RequestHeader<BorrowedHandle> request; 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ResponseHeader<LocalHandle> response; 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 7209aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReadAndDiscardData(const BorrowedHandle& socket_fd, size_t size) { 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (size > 0) { 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If there is more data to read in the message than the buffers provided 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // by the caller, read and discard the extra data from the socket. 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko char buffer[1024]; 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_to_read = std::min(sizeof(buffer), size); 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = ReceiveData(socket_fd, buffer, size_to_read); 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size -= size_to_read; 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // We still want to return EIO error to the caller in case we had unexpected 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // data in the socket stream. 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 8809aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> SendRequest(const BorrowedHandle& socket_fd, 8909aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko TransactionState* transaction_state, int opcode, 9009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko const iovec* send_vector, size_t send_count, 9109aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko size_t max_recv_len) { 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_len = CountVectorSize(send_vector, send_count); 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko InitRequest(&transaction_state->request, opcode, send_len, max_recv_len, 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko false); 95adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko if (send_len == 0) { 96adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko send_vector = nullptr; 97adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko send_count = 0; 98adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko } 99adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko return SendData(socket_fd, transaction_state->request, send_vector, 100adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko send_count); 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 10309aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReceiveResponse(const BorrowedHandle& socket_fd, 10409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko TransactionState* transaction_state, 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, size_t receive_count, 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t max_recv_len) { 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = ReceiveData(socket_fd, &transaction_state->response); 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (transaction_state->response.recv_len > 0) { 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<iovec> read_buffers; 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_remaining = 0; 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (transaction_state->response.recv_len != max_recv_len) { 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If the receive buffer not exactly the size of data available, recreate 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the vector list to consume the data exactly since ReceiveDataVector() 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // validates that the number of bytes received equals the number of bytes 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // requested. 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_remaining = transaction_state->response.recv_len; 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < receive_count && size_remaining > 0; i++) { 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko read_buffers.push_back(receive_vector[i]); 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko iovec& last_vec = read_buffers.back(); 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (last_vec.iov_len > size_remaining) 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko last_vec.iov_len = size_remaining; 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_remaining -= last_vec.iov_len; 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector = read_buffers.data(); 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_count = read_buffers.size(); 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReceiveDataVector(socket_fd, receive_vector, receive_count); 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status && size_remaining > 0) 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReadAndDiscardData(socket_fd, size_remaining); 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoClientChannel::ClientChannel(LocalChannelHandle channel_handle) 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : channel_handle_{std::move(channel_handle)} { 1416890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_data_ = ChannelManager::Get().GetChannelData(channel_handle_.value()); 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::unique_ptr<pdx::ClientChannel> ClientChannel::Create( 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle channel_handle) { 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::unique_ptr<pdx::ClientChannel>{ 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko new ClientChannel{std::move(channel_handle)}}; 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoClientChannel::~ClientChannel() { 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_handle_) 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko shutdown(channel_handle_.value(), SHUT_WR); 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid* ClientChannel::AllocateTransactionState() { return new TransactionState; } 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid ClientChannel::FreeTransactionState(void* state) { 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko delete static_cast<TransactionState*>(state); 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> ClientChannel::SendImpulse(int opcode, const void* buffer, 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t length) { 163fd22b3e5ad1aae1fc3de54801f33466db3c9b3feAlex Vakulenko std::unique_lock<std::mutex> lock(socket_mutex_); 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<void> status; 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::pdx::uds::RequestHeader<BorrowedHandle> request; 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (length > request.impulse_payload.size() || 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko (buffer == nullptr && length != 0)) { 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetError(EINVAL); 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko InitRequest(&request, opcode, length, 0, true); 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(request.impulse_payload.data(), buffer, length); 17409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko return SendData(BorrowedHandle{channel_handle_.value()}, request); 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> ClientChannel::SendAndReceive(void* transaction_state, int opcode, 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* send_vector, 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t receive_count) { 182fd22b3e5ad1aae1fc3de54801f33466db3c9b3feAlex Vakulenko std::unique_lock<std::mutex> lock(socket_mutex_); 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> result; 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if ((send_vector == nullptr && send_count != 0) || 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko (receive_vector == nullptr && receive_count != 0)) { 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko result.SetError(EINVAL); 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return result; 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t max_recv_len = CountVectorSize(receive_vector, receive_count); 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 19309aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko auto status = SendRequest(BorrowedHandle{channel_handle_.value()}, state, 19409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko opcode, send_vector, send_count, max_recv_len); 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) { 19609aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko status = ReceiveResponse(BorrowedHandle{channel_handle_.value()}, state, 19709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko receive_vector, receive_count, max_recv_len); 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!result.PropagateError(status)) { 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int return_code = state->response.ret_code; 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (return_code >= 0) 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko result.SetValue(return_code); 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko result.SetError(-return_code); 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return result; 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> ClientChannel::SendWithInt(void* transaction_state, int opcode, 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* send_vector, 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t receive_count) { 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return SendAndReceive(transaction_state, opcode, send_vector, send_count, 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector, receive_count); 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<LocalHandle> ClientChannel::SendWithFileHandle( 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, int opcode, const iovec* send_vector, 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, const iovec* receive_vector, size_t receive_count) { 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> int_status = 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko SendAndReceive(transaction_state, opcode, send_vector, send_count, 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector, receive_count); 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalHandle> status; 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status.PropagateError(int_status)) 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle handle; 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (state->GetLocalFileHandle(int_status.get(), &handle)) { 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetValue(std::move(handle)); 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetError(EINVAL); 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<LocalChannelHandle> ClientChannel::SendWithChannelHandle( 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, int opcode, const iovec* send_vector, 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, const iovec* receive_vector, size_t receive_count) { 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> int_status = 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko SendAndReceive(transaction_state, opcode, send_vector, send_count, 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector, receive_count); 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalChannelHandle> status; 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status.PropagateError(int_status)) 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle handle; 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (state->GetLocalChannelHandle(int_status.get(), &handle)) { 251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetValue(std::move(handle)); 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetError(EINVAL); 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoFileReference ClientChannel::PushFileHandle(void* transaction_state, 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const LocalHandle& handle) { 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Borrow()); 262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoFileReference ClientChannel::PushFileHandle(void* transaction_state, 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const BorrowedHandle& handle) { 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Duplicate()); 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoChannelReference ClientChannel::PushChannelHandle( 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, const LocalChannelHandle& handle) { 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Borrow()); 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoChannelReference ClientChannel::PushChannelHandle( 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, const BorrowedChannelHandle& handle) { 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Duplicate()); 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ClientChannel::GetFileHandle(void* transaction_state, FileReference ref, 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle* handle) const { 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->GetLocalFileHandle(ref, handle); 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ClientChannel::GetChannelHandle(void* transaction_state, 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference ref, 290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle* handle) const { 291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->GetLocalChannelHandle(ref, handle); 293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace uds 296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 298