1c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui/*
2c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui * Copyright (C) 2015 The Android Open Source Project
3c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui *
4c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui * Licensed under the Apache License, Version 2.0 (the "License");
5c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui * you may not use this file except in compliance with the License.
6c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui * You may obtain a copy of the License at
7c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui *
8c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui *      http://www.apache.org/licenses/LICENSE-2.0
9c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui *
10c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui * Unless required by applicable law or agreed to in writing, software
11c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui * distributed under the License is distributed on an "AS IS" BASIS,
12c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui * See the License for the specific language governing permissions and
14c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui * limitations under the License.
15c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui */
16c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
17c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui#ifndef __ADB_SOCKET_H
18c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui#define __ADB_SOCKET_H
19c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
20c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui#include <stddef.h>
21c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
2227cb7dca773616f2946e941c02798db3275deeeaJosh Gao#include <deque>
2355c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao#include <memory>
2427cb7dca773616f2946e941c02798db3275deeeaJosh Gao#include <string>
2555c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao
26c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui#include "fdevent.h"
2727cb7dca773616f2946e941c02798db3275deeeaJosh Gao#include "range.h"
28c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
29c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cuistruct apacket;
30c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cuiclass atransport;
31c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
32c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui/* An asocket represents one half of a connection between a local and
3355c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao * remote entity.  A local asocket is bound to a file descriptor.  A
3455c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao * remote asocket is bound to the protocol engine.
3555c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao */
36c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cuistruct asocket {
3755c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao    /* the unique identifier for this asocket
3855c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     */
39e0361d1e90a1eff2866e14e9cd886322344f929cJosh Gao    unsigned id = 0;
40c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
4155c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao    /* flag: set when the socket's peer has closed
4255c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * but packets are still queued for delivery
4355c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     */
44e0361d1e90a1eff2866e14e9cd886322344f929cJosh Gao    int closing = 0;
45c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
46c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui    // flag: set when the socket failed to write, so the socket will not wait to
47c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui    // write packets and close directly.
48e0361d1e90a1eff2866e14e9cd886322344f929cJosh Gao    bool has_write_error = 0;
49c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
5055c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao    /* flag: quit adbd when both ends close the
5155c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * local service socket
5255c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     */
53e0361d1e90a1eff2866e14e9cd886322344f929cJosh Gao    int exit_on_close = 0;
54c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
5555c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao    // the asocket we are connected to
56e0361d1e90a1eff2866e14e9cd886322344f929cJosh Gao    asocket* peer = nullptr;
57c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
5855c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao    /* For local asockets, the fde is used to bind
5955c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * us to our fd event system.  For remote asockets
6055c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * these fields are not used.
6155c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     */
621b58bbf2ef0dcb009954688d3df0857db16c5267Josh Gao    fdevent fde = {};
63e0361d1e90a1eff2866e14e9cd886322344f929cJosh Gao    int fd = 0;
64c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
6527cb7dca773616f2946e941c02798db3275deeeaJosh Gao    // queue of data waiting to be written
6627cb7dca773616f2946e941c02798db3275deeeaJosh Gao    std::deque<Range> packet_queue;
6727cb7dca773616f2946e941c02798db3275deeeaJosh Gao
6827cb7dca773616f2946e941c02798db3275deeeaJosh Gao    std::string smart_socket_data;
6955c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao
7055c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao    /* enqueue is called by our peer when it has data
7155c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * for us.  It should return 0 if we can accept more
7255c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * data or 1 if not.  If we return 1, we must call
7355c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * peer->ready() when we once again are ready to
7455c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * receive data.
7555c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     */
76e0361d1e90a1eff2866e14e9cd886322344f929cJosh Gao    int (*enqueue)(asocket* s, std::string data) = nullptr;
7755c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao
7855c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao    /* ready is called by the peer when it is ready for
7955c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * us to send data via enqueue again
8055c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     */
81e0361d1e90a1eff2866e14e9cd886322344f929cJosh Gao    void (*ready)(asocket* s) = nullptr;
8255c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao
8355c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao    /* shutdown is called by the peer before it goes away.
8455c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * the socket should not do any further calls on its peer.
8555c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * Always followed by a call to close. Optional, i.e. can be NULL.
8655c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     */
87e0361d1e90a1eff2866e14e9cd886322344f929cJosh Gao    void (*shutdown)(asocket* s) = nullptr;
8855c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao
8955c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao    /* close is called by the peer when it has gone away.
9055c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * we are not allowed to make any further calls on the
9155c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     * peer once our close method is called.
9255c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao     */
93e0361d1e90a1eff2866e14e9cd886322344f929cJosh Gao    void (*close)(asocket* s) = nullptr;
9455c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao
9555c8b34f144ab37f0e8a9df4b2399b74f155408fJosh Gao    /* A socket is bound to atransport */
96e0361d1e90a1eff2866e14e9cd886322344f929cJosh Gao    atransport* transport = nullptr;
97c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
98c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui    size_t get_max_payload() const;
99c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui};
100c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
101c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cuiasocket *find_local_socket(unsigned local_id, unsigned remote_id);
102c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cuivoid install_local_socket(asocket *s);
103c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cuivoid remove_socket(asocket *s);
104c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cuivoid close_all_sockets(atransport *t);
105c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
106c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cuiasocket *create_local_socket(int fd);
107a98aab2a722105b569917b400cb0937bbcf85b2eJosh Gaoasocket* create_local_service_socket(const char* destination, atransport* transport);
108c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
109c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cuiasocket *create_remote_socket(unsigned id, atransport *t);
110c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cuivoid connect_to_remote(asocket *s, const char *destination);
111c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cuivoid connect_to_smartsocket(asocket *s);
112c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui
1133f902aad5b427a8162bf860a758878b55b13e775David Pursell// Internal functions that are only made available here for testing purposes.
1143f902aad5b427a8162bf860a758878b55b13e775David Pursellnamespace internal {
1153f902aad5b427a8162bf860a758878b55b13e775David Pursell
1163f902aad5b427a8162bf860a758878b55b13e775David Pursell#if ADB_HOST
117b4cff495a1f93b6c92f4327cbfb9e564b28913d8Dan Austinchar* skip_host_serial(char* service);
1183f902aad5b427a8162bf860a758878b55b13e775David Pursell#endif
1193f902aad5b427a8162bf860a758878b55b13e775David Pursell
1203f902aad5b427a8162bf860a758878b55b13e775David Pursell}  // namespace internal
1213f902aad5b427a8162bf860a758878b55b13e775David Pursell
122c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui#endif  // __ADB_SOCKET_H
123