client_channel.cpp revision 6890d95ec8b96970202518b439bfa8ab2d9dbf77
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "uds/client_channel.h"
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <log/log.h>
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/epoll.h>
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/socket.h>
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pdx/client.h>
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pdx/service_endpoint.h>
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <uds/ipc_helper.h>
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace pdx {
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace uds {
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace {
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstruct TransactionState {
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  bool GetLocalFileHandle(int index, LocalHandle* handle) {
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index < 0) {
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      handle->Reset(index);
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (static_cast<size_t>(index) < response.file_descriptors.size()) {
2313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      *handle = std::move(response.file_descriptors[index]);
2413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
2513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      return false;
2613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
2713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
2813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  }
2913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3090ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian  bool GetLocalChannelHandle(int index, LocalChannelHandle* handle) {
3190ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian    if (index < 0) {
323330b203039dea366d4981db1408a460134b2d2cMathias Agopian      *handle = LocalChannelHandle{nullptr, index};
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (static_cast<size_t>(index) < response.channels.size()) {
3413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      auto& channel_info = response.channels[index];
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      *handle = ChannelManager::Get().CreateHandle(
3690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian          std::move(channel_info.data_fd), std::move(channel_info.event_fd));
3790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian    } else {
3813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      return false;
39076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
4082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    return true;
4113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  }
4213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  FileReference PushFileHandle(BorrowedHandle handle) {
44a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (!handle)
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      return handle.Get();
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    request.file_descriptors.push_back(std::move(handle));
4713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return request.file_descriptors.size() - 1;
4813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  }
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  ChannelReference PushChannelHandle(BorrowedChannelHandle handle) {
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!handle)
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      return handle.value();
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
543e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (auto* channel_data =
5513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            ChannelManager::Get().GetChannelData(handle.value())) {
5613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      ChannelInfo<BorrowedHandle> channel_info;
5713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      channel_info.data_fd.Reset(handle.value());
581f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian      channel_info.event_fd = channel_data->event_receiver.event_fd();
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      request.channels.push_back(std::move(channel_info));
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      return request.channels.size() - 1;
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
62882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden      return -1;
63882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden    }
64882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden  }
65882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden
66882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden  RequestHeader<BorrowedHandle> request;
67882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden  ResponseHeader<LocalHandle> response;
68882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden};
6913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7013127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianStatus<void> ReadAndDiscardData(int socket_fd, size_t size) {
7113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  while (size > 0) {
72d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    // If there is more data to read in the message than the buffers provided
7313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // by the caller, read and discard the extra data from the socket.
7413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    char buffer[1024];
7513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    size_t size_to_read = std::min(sizeof(buffer), size);
7613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    auto status = ReceiveData(socket_fd, buffer, size_to_read);
7713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!status)
7813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      return status;
7913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    size -= size_to_read;
8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  }
8113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  // We still want to return EIO error to the caller in case we had unexpected
8213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  // data in the socket stream.
8313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  return ErrorStatus(EIO);
8413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
8513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
8613127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianStatus<void> SendRequest(int socket_fd, TransactionState* transaction_state,
8713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                         int opcode, const iovec* send_vector,
8813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                         size_t send_count, size_t max_recv_len) {
8913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  size_t send_len = CountVectorSize(send_vector, send_count);
9013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  InitRequest(&transaction_state->request, opcode, send_len, max_recv_len,
9113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian              false);
9213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  auto status = SendData(socket_fd, transaction_state->request);
9313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  if (status && send_len > 0)
9413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    status = SendDataVector(socket_fd, send_vector, send_count);
9513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  return status;
9613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
9713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9813127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianStatus<void> ReceiveResponse(int socket_fd, TransactionState* transaction_state,
9913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                             const iovec* receive_vector, size_t receive_count,
10013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                             size_t max_recv_len) {
10113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  auto status = ReceiveData(socket_fd, &transaction_state->response);
10213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  if (!status)
10313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return status;
10413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  if (transaction_state->response.recv_len > 0) {
10613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    std::vector<iovec> read_buffers;
1072ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    size_t size_remaining = 0;
1082ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    if (transaction_state->response.recv_len != max_recv_len) {
1092ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian      // If the receive buffer not exactly the size of data available, recreate
1102ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian      // the vector list to consume the data exactly since ReceiveDataVector()
1112ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian      // validates that the number of bytes received equals the number of bytes
11213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      // requested.
11313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      size_remaining = transaction_state->response.recv_len;
11413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      for (size_t i = 0; i < receive_count && size_remaining > 0; i++) {
11513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        read_buffers.push_back(receive_vector[i]);
11613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        iovec& last_vec = read_buffers.back();
11713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (last_vec.iov_len > size_remaining)
11813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian          last_vec.iov_len = size_remaining;
11913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        size_remaining -= last_vec.iov_len;
12013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      }
12113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      receive_vector = read_buffers.data();
12213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      receive_count = read_buffers.size();
12313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
12413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    status = ReceiveDataVector(socket_fd, receive_vector, receive_count);
12513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (status && size_remaining > 0)
12613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      status = ReadAndDiscardData(socket_fd, size_remaining);
12713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  }
12813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  return status;
12913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
13013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
13113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}  // anonymous namespace
1324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianClientChannel::ClientChannel(LocalChannelHandle channel_handle)
1341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    : channel_handle_{std::move(channel_handle)} {
135b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian  channel_data_ = ChannelManager::Get().GetChannelData(channel_handle_.value());
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
137b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstd::unique_ptr<pdx::ClientChannel> ClientChannel::Create(
13913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    LocalChannelHandle channel_handle) {
14013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  return std::unique_ptr<pdx::ClientChannel>{
14113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      new ClientChannel{std::move(channel_handle)}};
14213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
14313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14413127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianClientChannel::~ClientChannel() {
14513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  if (channel_handle_)
14613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    shutdown(channel_handle_.value(), SHUT_WR);
14713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
14813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid* ClientChannel::AllocateTransactionState() { return new TransactionState; }
15013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid ClientChannel::FreeTransactionState(void* state) {
15213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  delete static_cast<TransactionState*>(state);
15313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
15413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
15513127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianStatus<void> ClientChannel::SendImpulse(int opcode, const void* buffer,
15613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                                        size_t length) {
1574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian  Status<void> status;
1584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian  android::pdx::uds::RequestHeader<BorrowedHandle> request;
1591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  if (length > request.impulse_payload.size() ||
16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      (buffer == nullptr && length != 0)) {
1614d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status.SetError(EINVAL);
1621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    return status;
16313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  }
16413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
16513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  InitRequest(&request, opcode, length, 0, true);
1661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  memcpy(request.impulse_payload.data(), buffer, length);
1671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  return SendData(channel_handle_.value(), request);
1681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian}
1691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian
1701eae0ee49402c39f1b08cc8fec129023f86494b7Mathias AgopianStatus<int> ClientChannel::SendAndReceive(void* transaction_state, int opcode,
1711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                          const iovec* send_vector,
1721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                          size_t send_count,
1731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                          const iovec* receive_vector,
1741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                          size_t receive_count) {
1751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  Status<int> result;
1761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  if ((send_vector == nullptr && send_count != 0) ||
1771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian      (receive_vector == nullptr && receive_count != 0)) {
1781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    result.SetError(EINVAL);
1791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    return result;
1801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  }
1811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian
1821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  auto* state = static_cast<TransactionState*>(transaction_state);
1831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  size_t max_recv_len = CountVectorSize(receive_vector, receive_count);
1841eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian
1851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  auto status = SendRequest(channel_handle_.value(), state, opcode, send_vector,
1861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                            send_count, max_recv_len);
1871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  if (status) {
1881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    status = ReceiveResponse(channel_handle_.value(), state, receive_vector,
1891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             receive_count, max_recv_len);
1901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  }
1911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  if (!result.PropagateError(status)) {
1921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const int return_code = state->response.ret_code;
1931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (return_code >= 0)
1941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian      result.SetValue(return_code);
1951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    else
1961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian      result.SetError(-return_code);
1971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  }
1981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  return result;
1991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian}
2001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian
2011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias AgopianStatus<int> ClientChannel::SendWithInt(void* transaction_state, int opcode,
2021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                       const iovec* send_vector,
2034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                                       size_t send_count,
2041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                       const iovec* receive_vector,
205d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                                       size_t receive_count) {
2061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  return SendAndReceive(transaction_state, opcode, send_vector, send_count,
207d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                        receive_vector, receive_count);
20813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
20913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21013127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianStatus<LocalHandle> ClientChannel::SendWithFileHandle(
21113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    void* transaction_state, int opcode, const iovec* send_vector,
2121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    size_t send_count, const iovec* receive_vector, size_t receive_count) {
213d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian  Status<int> int_status =
21413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      SendAndReceive(transaction_state, opcode, send_vector, send_count,
21513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                     receive_vector, receive_count);
21613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  Status<LocalHandle> status;
21713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  if (status.PropagateError(int_status))
21813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return status;
2191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian
22013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  auto* state = static_cast<TransactionState*>(transaction_state);
22113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  LocalHandle handle;
22213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  if (state->GetLocalFileHandle(int_status.get(), &handle)) {
22313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    status.SetValue(std::move(handle));
2241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  } else {
2254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    status.SetError(EINVAL);
22613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  }
22713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  return status;
22813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
22913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2301eae0ee49402c39f1b08cc8fec129023f86494b7Mathias AgopianStatus<LocalChannelHandle> ClientChannel::SendWithChannelHandle(
2311eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    void* transaction_state, int opcode, const iovec* send_vector,
23213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    size_t send_count, const iovec* receive_vector, size_t receive_count) {
23313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  Status<int> int_status =
23413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian      SendAndReceive(transaction_state, opcode, send_vector, send_count,
23513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                     receive_vector, receive_count);
23613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  Status<LocalChannelHandle> status;
2371eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  if (status.PropagateError(int_status))
23813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return status;
23913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
24013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  auto* state = static_cast<TransactionState*>(transaction_state);
24113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  LocalChannelHandle handle;
24213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  if (state->GetLocalChannelHandle(int_status.get(), &handle)) {
2431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    status.SetValue(std::move(handle));
24413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  } else {
24513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    status.SetError(EINVAL);
24613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  }
24713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  return status;
24813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
24913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias AgopianFileReference ClientChannel::PushFileHandle(void* transaction_state,
25113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                                            const LocalHandle& handle) {
25213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  auto* state = static_cast<TransactionState*>(transaction_state);
25313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  return state->PushFileHandle(handle.Borrow());
25413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
25513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias AgopianFileReference ClientChannel::PushFileHandle(void* transaction_state,
25713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                                            const BorrowedHandle& handle) {
25813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  auto* state = static_cast<TransactionState*>(transaction_state);
25913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  return state->PushFileHandle(handle.Duplicate());
26013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
26113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
26213127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianChannelReference ClientChannel::PushChannelHandle(
26313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    void* transaction_state, const LocalChannelHandle& handle) {
26413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  auto* state = static_cast<TransactionState*>(transaction_state);
2651eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  return state->PushChannelHandle(handle.Borrow());
26613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
26713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
26813127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianChannelReference ClientChannel::PushChannelHandle(
26913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    void* transaction_state, const BorrowedChannelHandle& handle) {
27013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  auto* state = static_cast<TransactionState*>(transaction_state);
2711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  return state->PushChannelHandle(handle.Duplicate());
272582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
27313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
274bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFaddenbool ClientChannel::GetFileHandle(void* transaction_state, FileReference ref,
2758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                                  LocalHandle* handle) const {
2761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian  auto* state = static_cast<TransactionState*>(transaction_state);
2776905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden  return state->GetLocalFileHandle(ref, handle);
27813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
27913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool ClientChannel::GetChannelHandle(void* transaction_state,
28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                                     ChannelReference ref,
2821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                     LocalChannelHandle* handle) const {
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  auto* state = static_cast<TransactionState*>(transaction_state);
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian  return state->GetLocalChannelHandle(ref, handle);
28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}  // namespace uds
2881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian}  // namespace pdx
289a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian}  // namespace android
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian