1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __ADB_SOCKET_H
#define __ADB_SOCKET_H
#include <stddef.h>
#include <deque>
#include <memory>
#include <optional>
#include <string>
#include "adb_unique_fd.h"
#include "fdevent/fdevent.h"
#include "types.h"
class atransport;
/* An asocket represents one half of a connection between a local and
remote entity. A local asocket is bound to a file descriptor. A
remote asocket is bound to the protocol engine.
Example (two local_sockets) :
ASOCKET(THIS)
┌────────────────────────────────────────────────┐
┌──┐ write(3) │ ┌─────┐ enqueue() │
│ │◄─────────┼──┤Queue├─────────────◄────────────┐ │
│fd│ │ └─────┘ ▲ │
│ ├──────────►─────────────────┐ │ │
└──┘ read(3) └─────────────────┼─────────────────┼────────────┘
outgoing │ │ incoming
┌─────────────────▼─────────────────▲────────────┐ read(3) ┌──┐
│ │ └────────────┼─────────◄─┤ │
│ │ ┌─────┐ │ │fd│
│ └─────────────────────►│Queue├─┼─────────►─┤ │
│ enqueue() └─────┘ │ write(3) └──┘
└────────────────────────────────────────────────┘
ASOCKET(PEER)
Note that sockets can be peered regardless of their kind. A remote socket can be peered with
a smart socket, a local socket can be peered with a remote socket and so on.
*/
struct asocket {
/* the unique identifier for this asocket
*/
unsigned id = 0;
// Start Local socket fields
// TODO: move all the local socket fields together
/* flag: set when the socket's peer has closed
* but packets are still queued for delivery
* TODO: This should be a boolean.
*/
bool closing = false;
// flag: set when the socket failed to write, so the socket will not wait to
// write packets and close directly.
bool has_write_error = false;
/* flag: quit adbd when both ends close the
* local service socket
*/
int exit_on_close = 0;
// End Local socket fields
// the asocket we are connected to
asocket* peer = nullptr;
/* enqueue is called by our peer when it has data
* for us. It should return 0 if we can accept more
* data or 1 if not. If we return 1, we must call
* peer->ready() when we once again are ready to
* receive data.
*/
int (*enqueue)(asocket* s, apacket::payload_type data) = nullptr;
/* ready is called by the peer when it is ready for
* us to send data via enqueue again
*/
void (*ready)(asocket* s) = nullptr;
/* shutdown is called by the peer before it goes away.
* the socket should not do any further calls on its peer.
* Always followed by a call to close. Optional, i.e. can be NULL.
*/
void (*shutdown)(asocket* s) = nullptr;
/* close is called by the peer when it has gone away.
* we are not allowed to make any further calls on the
* peer once our close method is called.
*/
void (*close)(asocket* s) = nullptr;
/* A socket is bound to atransport */
atransport* transport = nullptr;
size_t get_max_payload() const;
// TODO: Make asocket an actual class and use inheritance instead of having an ever-growing
// struct with random use-specific fields stuffed into it.
// Start Local socket fields
fdevent* fde = nullptr;
int fd = -1;
// Queue of data that we've received from our peer, and are waiting to write into fd.
IOVector packet_queue;
// End Local socket fields
// The number of bytes that have been acknowledged by the other end if delayed_ack is available.
// This value can go negative: if we have a MAX_PAYLOAD's worth of bytes available to send,
// we'll send out a full packet.
std::optional<int64_t> available_send_bytes;
// Start Smart socket fields
// A temporary buffer used to hold a partially-read service string for smartsockets.
std::string smart_socket_data;
// End Smart socket fields
};
asocket *find_local_socket(unsigned local_id, unsigned remote_id);
void install_local_socket(asocket *s);
void remove_socket(asocket *s);
void close_all_sockets(atransport *t);
void local_socket_ack(asocket* s, std::optional<int32_t> acked_bytes);
asocket* create_local_socket(unique_fd fd);
asocket* create_local_service_socket(std::string_view destination, atransport* transport);
asocket *create_remote_socket(unsigned id, atransport *t);
void connect_to_remote(asocket* s, std::string_view destination);
#if ADB_HOST
void connect_to_smartsocket(asocket *s);
#endif
// Internal functions that are only made available here for testing purposes.
namespace internal {
#if ADB_HOST
bool parse_host_service(std::string_view* out_serial, std::string_view* out_command,
std::string_view service);
#endif
} // namespace internal
#endif // __ADB_SOCKET_H
|