1#pragma once
2
3/*
4 * Copyright (C) 2017 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include "common/libs/fs/shared_fd.h"
20
21#include <unistd.h>
22
23#include <cstddef>
24#include <cstdint>
25#include <mutex>
26#include <vector>
27
28namespace cvd {
29using Message = std::vector<std::uint8_t>;
30
31class ServerSocket;
32
33// Recv and Send wait until all data has been received or sent.
34// Send is thread safe in this regard, Recv is not.
35class ClientSocket {
36 public:
37  ClientSocket(ClientSocket&& other) : fd_{other.fd_} {}
38
39  ClientSocket& operator=(ClientSocket&& other) {
40    fd_ = other.fd_;
41    return *this;
42  }
43
44  ClientSocket(int port);
45
46  ClientSocket(const ClientSocket&) = delete;
47  ClientSocket& operator=(const ClientSocket&) = delete;
48
49  Message Recv(std::size_t length);
50  // RecvAny will receive whatever is available.
51  // An empty message returned indicates error or close.
52  Message RecvAny(size_t length);
53  ssize_t Send(const std::uint8_t* data, std::size_t size);
54  ssize_t Send(const Message& message);
55
56  template <std::size_t N>
57  ssize_t Send(const std::uint8_t (&data)[N]) {
58    return Send(data, N);
59  }
60
61  bool closed() const;
62
63 private:
64  friend ServerSocket;
65  explicit ClientSocket(cvd::SharedFD fd) : fd_(fd) {}
66
67  cvd::SharedFD fd_;
68  bool other_side_closed_{};
69  mutable std::mutex closed_lock_;
70  std::mutex send_lock_;
71};
72
73class ServerSocket {
74 public:
75  explicit ServerSocket(int port);
76
77  ServerSocket(const ServerSocket&) = delete;
78  ServerSocket& operator=(const ServerSocket&) = delete;
79
80  ClientSocket Accept();
81
82 private:
83  cvd::SharedFD fd_;
84};
85
86}  // namespace cvd
87