1a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai#include "uds/channel_parcelable.h" 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "uds/client_channel.h" 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <errno.h> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <log/log.h> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/epoll.h> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/socket.h> 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/client.h> 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/service_endpoint.h> 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/ipc_helper.h> 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx { 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace uds { 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace { 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct TransactionState { 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetLocalFileHandle(int index, LocalHandle* handle) { 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (index < 0) { 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko handle->Reset(index); 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(index) < response.file_descriptors.size()) { 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = std::move(response.file_descriptors[index]); 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetLocalChannelHandle(int index, LocalChannelHandle* handle) { 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (index < 0) { 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = LocalChannelHandle{nullptr, index}; 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(index) < response.channels.size()) { 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto& channel_info = response.channels[index]; 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = ChannelManager::Get().CreateHandle( 3752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka std::move(channel_info.data_fd), 3852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka std::move(channel_info.pollin_event_fd), 3952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka std::move(channel_info.pollhup_event_fd)); 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko FileReference PushFileHandle(BorrowedHandle handle) { 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request.file_descriptors.push_back(std::move(handle)); 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return request.file_descriptors.size() - 1; 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference PushChannelHandle(BorrowedChannelHandle handle) { 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 566890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 576890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (auto* channel_data = 586890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ChannelManager::Get().GetChannelData(handle.value())) { 5952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ChannelInfo<BorrowedHandle> channel_info{ 6052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka channel_data->data_fd(), channel_data->pollin_event_fd(), 6152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka channel_data->pollhup_event_fd()}; 626890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka request.channels.push_back(std::move(channel_info)); 636890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return request.channels.size() - 1; 646890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 656890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return -1; 666890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko RequestHeader<BorrowedHandle> request; 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ResponseHeader<LocalHandle> response; 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 7309aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReadAndDiscardData(const BorrowedHandle& socket_fd, size_t size) { 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (size > 0) { 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If there is more data to read in the message than the buffers provided 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // by the caller, read and discard the extra data from the socket. 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko char buffer[1024]; 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_to_read = std::min(sizeof(buffer), size); 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = ReceiveData(socket_fd, buffer, size_to_read); 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size -= size_to_read; 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // We still want to return EIO error to the caller in case we had unexpected 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // data in the socket stream. 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 8909aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> SendRequest(const BorrowedHandle& socket_fd, 9009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko TransactionState* transaction_state, int opcode, 9109aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko const iovec* send_vector, size_t send_count, 9209aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko size_t max_recv_len) { 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_len = CountVectorSize(send_vector, send_count); 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko InitRequest(&transaction_state->request, opcode, send_len, max_recv_len, 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko false); 96adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko if (send_len == 0) { 97adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko send_vector = nullptr; 98adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko send_count = 0; 99adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko } 100adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko return SendData(socket_fd, transaction_state->request, send_vector, 101adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko send_count); 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 10409aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReceiveResponse(const BorrowedHandle& socket_fd, 10509aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko TransactionState* transaction_state, 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, size_t receive_count, 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t max_recv_len) { 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = ReceiveData(socket_fd, &transaction_state->response); 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (transaction_state->response.recv_len > 0) { 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<iovec> read_buffers; 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_remaining = 0; 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (transaction_state->response.recv_len != max_recv_len) { 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If the receive buffer not exactly the size of data available, recreate 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the vector list to consume the data exactly since ReceiveDataVector() 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // validates that the number of bytes received equals the number of bytes 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // requested. 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_remaining = transaction_state->response.recv_len; 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < receive_count && size_remaining > 0; i++) { 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko read_buffers.push_back(receive_vector[i]); 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko iovec& last_vec = read_buffers.back(); 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (last_vec.iov_len > size_remaining) 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko last_vec.iov_len = size_remaining; 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_remaining -= last_vec.iov_len; 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector = read_buffers.data(); 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_count = read_buffers.size(); 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReceiveDataVector(socket_fd, receive_vector, receive_count); 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status && size_remaining > 0) 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReadAndDiscardData(socket_fd, size_remaining); 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoClientChannel::ClientChannel(LocalChannelHandle channel_handle) 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : channel_handle_{std::move(channel_handle)} { 1426890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_data_ = ChannelManager::Get().GetChannelData(channel_handle_.value()); 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::unique_ptr<pdx::ClientChannel> ClientChannel::Create( 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle channel_handle) { 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::unique_ptr<pdx::ClientChannel>{ 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko new ClientChannel{std::move(channel_handle)}}; 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoClientChannel::~ClientChannel() { 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_handle_) 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko shutdown(channel_handle_.value(), SHUT_WR); 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid* ClientChannel::AllocateTransactionState() { return new TransactionState; } 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid ClientChannel::FreeTransactionState(void* state) { 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko delete static_cast<TransactionState*>(state); 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> ClientChannel::SendImpulse(int opcode, const void* buffer, 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t length) { 164fd22b3e5ad1aae1fc3de54801f33466db3c9b3feAlex Vakulenko std::unique_lock<std::mutex> lock(socket_mutex_); 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<void> status; 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::pdx::uds::RequestHeader<BorrowedHandle> request; 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (length > request.impulse_payload.size() || 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko (buffer == nullptr && length != 0)) { 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetError(EINVAL); 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko InitRequest(&request, opcode, length, 0, true); 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(request.impulse_payload.data(), buffer, length); 17509aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko return SendData(BorrowedHandle{channel_handle_.value()}, request); 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> ClientChannel::SendAndReceive(void* transaction_state, int opcode, 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* send_vector, 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t receive_count) { 183fd22b3e5ad1aae1fc3de54801f33466db3c9b3feAlex Vakulenko std::unique_lock<std::mutex> lock(socket_mutex_); 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> result; 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if ((send_vector == nullptr && send_count != 0) || 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko (receive_vector == nullptr && receive_count != 0)) { 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko result.SetError(EINVAL); 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return result; 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t max_recv_len = CountVectorSize(receive_vector, receive_count); 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 19409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko auto status = SendRequest(BorrowedHandle{channel_handle_.value()}, state, 19509aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko opcode, send_vector, send_count, max_recv_len); 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) { 19709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko status = ReceiveResponse(BorrowedHandle{channel_handle_.value()}, state, 19809aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko receive_vector, receive_count, max_recv_len); 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!result.PropagateError(status)) { 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int return_code = state->response.ret_code; 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (return_code >= 0) 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko result.SetValue(return_code); 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko result.SetError(-return_code); 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return result; 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> ClientChannel::SendWithInt(void* transaction_state, int opcode, 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* send_vector, 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t receive_count) { 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return SendAndReceive(transaction_state, opcode, send_vector, send_count, 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector, receive_count); 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<LocalHandle> ClientChannel::SendWithFileHandle( 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, int opcode, const iovec* send_vector, 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, const iovec* receive_vector, size_t receive_count) { 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> int_status = 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko SendAndReceive(transaction_state, opcode, send_vector, send_count, 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector, receive_count); 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalHandle> status; 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status.PropagateError(int_status)) 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle handle; 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (state->GetLocalFileHandle(int_status.get(), &handle)) { 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetValue(std::move(handle)); 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetError(EINVAL); 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<LocalChannelHandle> ClientChannel::SendWithChannelHandle( 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, int opcode, const iovec* send_vector, 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t send_count, const iovec* receive_vector, size_t receive_count) { 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> int_status = 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko SendAndReceive(transaction_state, opcode, send_vector, send_count, 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko receive_vector, receive_count); 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalChannelHandle> status; 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status.PropagateError(int_status)) 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle handle; 251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (state->GetLocalChannelHandle(int_status.get(), &handle)) { 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetValue(std::move(handle)); 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.SetError(EINVAL); 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoFileReference ClientChannel::PushFileHandle(void* transaction_state, 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const LocalHandle& handle) { 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Borrow()); 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoFileReference ClientChannel::PushFileHandle(void* transaction_state, 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const BorrowedHandle& handle) { 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Duplicate()); 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoChannelReference ClientChannel::PushChannelHandle( 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, const LocalChannelHandle& handle) { 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Borrow()); 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoChannelReference ClientChannel::PushChannelHandle( 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* transaction_state, const BorrowedChannelHandle& handle) { 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Duplicate()); 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ClientChannel::GetFileHandle(void* transaction_state, FileReference ref, 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle* handle) const { 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->GetLocalFileHandle(ref, handle); 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ClientChannel::GetChannelHandle(void* transaction_state, 290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference ref, 291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle* handle) const { 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<TransactionState*>(transaction_state); 293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->GetLocalChannelHandle(ref, handle); 294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 296a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Caistd::unique_ptr<pdx::ChannelParcelable> ClientChannel::TakeChannelParcelable() 297a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai { 298a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai if (!channel_handle_) 299a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai return nullptr; 300a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai 301a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai if (auto* channel_data = 302a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai ChannelManager::Get().GetChannelData(channel_handle_.value())) { 303a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai auto fds = channel_data->TakeFds(); 304a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai auto parcelable = std::make_unique<ChannelParcelable>( 305a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai std::move(std::get<0>(fds)), std::move(std::get<1>(fds)), 306a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai std::move(std::get<2>(fds))); 307a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai 308a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai // Here we need to explicitly close the channel handle so that the channel 309a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai // won't get shutdown in the destructor, while the FDs in ChannelParcelable 310a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai // can keep the channel alive so that new client can be created from it 311a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai // later. 312a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai channel_handle_.Close(); 313a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai return parcelable; 314a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai } else { 315a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai return nullptr; 316a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai } 317a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai} 318a88e3ee3a33a60e72bd976cfb5b9fc0bd15a1078Jiwen 'Steve' Cai 319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace uds 320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 322