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