support "sideload over ADB" mode

Rather than depending on the existence of some place to store a file
that is accessible to users on an an unbootable device (eg, a physical
sdcard, external USB drive, etc.), add support for sideloading
packages sent to the device with adb.

This change adds a "minimal adbd" which supports nothing but receiving
a package over adb (with the "adb sideload" command) and storing it to
a fixed filename in the /tmp ramdisk, from where it can be verified
and sideloaded in the usual way.  This should be leave available even
on locked user-build devices.

The user can select "apply package from ADB" from the recovery menu,
which starts minimal-adb mode (shutting down any real adbd that may be
running).  Once minimal-adb has received a package it exits
(restarting real adbd if appropriate) and then verification and
installation of the received package proceeds.

Change-Id: I6fe13161ca064a98d06fa32104e1f432826582f5
diff --git a/minadbd/adb.h b/minadbd/adb.h
new file mode 100644
index 0000000..a989edd
--- /dev/null
+++ b/minadbd/adb.h
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2007 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_H
+#define __ADB_H
+
+#include <limits.h>
+
+#include "transport.h"  /* readx(), writex() */
+#include "fdevent.h"
+
+#define MAX_PAYLOAD 4096
+
+#define A_SYNC 0x434e5953
+#define A_CNXN 0x4e584e43
+#define A_OPEN 0x4e45504f
+#define A_OKAY 0x59414b4f
+#define A_CLSE 0x45534c43
+#define A_WRTE 0x45545257
+
+#define A_VERSION 0x01000000        // ADB protocol version
+
+#define ADB_VERSION_MAJOR 1         // Used for help/version information
+#define ADB_VERSION_MINOR 0         // Used for help/version information
+
+#define ADB_SERVER_VERSION    29    // Increment this when we want to force users to start a new adb server
+
+typedef struct amessage amessage;
+typedef struct apacket apacket;
+typedef struct asocket asocket;
+typedef struct alistener alistener;
+typedef struct aservice aservice;
+typedef struct atransport atransport;
+typedef struct adisconnect  adisconnect;
+typedef struct usb_handle usb_handle;
+
+struct amessage {
+    unsigned command;       /* command identifier constant      */
+    unsigned arg0;          /* first argument                   */
+    unsigned arg1;          /* second argument                  */
+    unsigned data_length;   /* length of payload (0 is allowed) */
+    unsigned data_check;    /* checksum of data payload         */
+    unsigned magic;         /* command ^ 0xffffffff             */
+};
+
+struct apacket
+{
+    apacket *next;
+
+    unsigned len;
+    unsigned char *ptr;
+
+    amessage msg;
+    unsigned char data[MAX_PAYLOAD];
+};
+
+/* 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.
+*/
+struct asocket {
+        /* chain pointers for the local/remote list of
+        ** asockets that this asocket lives in
+        */
+    asocket *next;
+    asocket *prev;
+
+        /* the unique identifier for this asocket
+        */
+    unsigned id;
+
+        /* flag: set when the socket's peer has closed
+        ** but packets are still queued for delivery
+        */
+    int    closing;
+
+        /* the asocket we are connected to
+        */
+
+    asocket *peer;
+
+        /* For local asockets, the fde is used to bind
+        ** us to our fd event system.  For remote asockets
+        ** these fields are not used.
+        */
+    fdevent fde;
+    int fd;
+
+        /* queue of apackets waiting to be written
+        */
+    apacket *pkt_first;
+    apacket *pkt_last;
+
+        /* 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 *pkt);
+
+        /* ready is called by the peer when it is ready for
+        ** us to send data via enqueue again
+        */
+    void (*ready)(asocket *s);
+
+        /* 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);
+
+        /* socket-type-specific extradata */
+    void *extra;
+
+    	/* A socket is bound to atransport */
+    atransport *transport;
+};
+
+
+/* the adisconnect structure is used to record a callback that
+** will be called whenever a transport is disconnected (e.g. by the user)
+** this should be used to cleanup objects that depend on the
+** transport (e.g. remote sockets, listeners, etc...)
+*/
+struct  adisconnect
+{
+    void        (*func)(void*  opaque, atransport*  t);
+    void*         opaque;
+    adisconnect*  next;
+    adisconnect*  prev;
+};
+
+
+/* a transport object models the connection to a remote device or emulator
+** there is one transport per connected device/emulator. a "local transport"
+** connects through TCP (for the emulator), while a "usb transport" through
+** USB (for real devices)
+**
+** note that kTransportHost doesn't really correspond to a real transport
+** object, it's a special value used to indicate that a client wants to
+** connect to a service implemented within the ADB server itself.
+*/
+typedef enum transport_type {
+        kTransportUsb,
+        kTransportLocal,
+        kTransportAny,
+        kTransportHost,
+} transport_type;
+
+struct atransport
+{
+    atransport *next;
+    atransport *prev;
+
+    int (*read_from_remote)(apacket *p, atransport *t);
+    int (*write_to_remote)(apacket *p, atransport *t);
+    void (*close)(atransport *t);
+    void (*kick)(atransport *t);
+
+    int fd;
+    int transport_socket;
+    fdevent transport_fde;
+    int ref_count;
+    unsigned sync_token;
+    int connection_state;
+    transport_type type;
+
+        /* usb handle or socket fd as needed */
+    usb_handle *usb;
+    int sfd;
+
+        /* used to identify transports for clients */
+    char *serial;
+    char *product;
+    int adb_port; // Use for emulators (local transport)
+
+        /* a list of adisconnect callbacks called when the transport is kicked */
+    int          kicked;
+    adisconnect  disconnects;
+};
+
+
+/* A listener is an entity which binds to a local port
+** and, upon receiving a connection on that port, creates
+** an asocket to connect the new local connection to a
+** specific remote service.
+**
+** TODO: some listeners read from the new connection to
+** determine what exact service to connect to on the far
+** side.
+*/
+struct alistener
+{
+    alistener *next;
+    alistener *prev;
+
+    fdevent fde;
+    int fd;
+
+    const char *local_name;
+    const char *connect_to;
+    atransport *transport;
+    adisconnect  disconnect;
+};
+
+
+void print_packet(const char *label, apacket *p);
+
+asocket *find_local_socket(unsigned id);
+void install_local_socket(asocket *s);
+void remove_socket(asocket *s);
+void close_all_sockets(atransport *t);
+
+#define  LOCAL_CLIENT_PREFIX  "emulator-"
+
+asocket *create_local_socket(int fd);
+asocket *create_local_service_socket(const char *destination);
+
+asocket *create_remote_socket(unsigned id, atransport *t);
+void connect_to_remote(asocket *s, const char *destination);
+void connect_to_smartsocket(asocket *s);
+
+void fatal(const char *fmt, ...);
+void fatal_errno(const char *fmt, ...);
+
+void handle_packet(apacket *p, atransport *t);
+void send_packet(apacket *p, atransport *t);
+
+void get_my_path(char *s, size_t maxLen);
+int launch_server(int server_port);
+int adb_main();
+
+
+/* transports are ref-counted
+** get_device_transport does an acquire on your behalf before returning
+*/
+void init_transport_registration(void);
+int  list_transports(char *buf, size_t  bufsize);
+void update_transports(void);
+
+asocket*  create_device_tracker(void);
+
+/* Obtain a transport from the available transports.
+** If state is != CS_ANY, only transports in that state are considered.
+** If serial is non-NULL then only the device with that serial will be chosen.
+** If no suitable transport is found, error is set.
+*/
+atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char **error_out);
+void   add_transport_disconnect( atransport*  t, adisconnect*  dis );
+void   remove_transport_disconnect( atransport*  t, adisconnect*  dis );
+void   run_transport_disconnects( atransport*  t );
+void   kick_transport( atransport*  t );
+
+/* initialize a transport object's func pointers and state */
+#if ADB_HOST
+int get_available_local_transport_index();
+#endif
+int  init_socket_transport(atransport *t, int s, int port, int local);
+void init_usb_transport(atransport *t, usb_handle *usb, int state);
+
+/* for MacOS X cleanup */
+void close_usb_devices();
+
+/* cause new transports to be init'd and added to the list */
+void register_socket_transport(int s, const char *serial, int port, int local);
+
+/* these should only be used for the "adb disconnect" command */
+void unregister_transport(atransport *t);
+void unregister_all_tcp_transports();
+
+void register_usb_transport(usb_handle *h, const char *serial, unsigned writeable);
+
+/* this should only be used for transports with connection_state == CS_NOPERM */
+void unregister_usb_transport(usb_handle *usb);
+
+atransport *find_transport(const char *serial);
+#if ADB_HOST
+atransport* find_emulator_transport_by_adb_port(int adb_port);
+#endif
+
+int service_to_fd(const char *name);
+#if ADB_HOST
+asocket *host_service_to_socket(const char*  name, const char *serial);
+#endif
+
+#if !ADB_HOST
+typedef enum {
+    BACKUP,
+    RESTORE
+} BackupOperation;
+int backup_service(BackupOperation operation, char* args);
+void framebuffer_service(int fd, void *cookie);
+void log_service(int fd, void *cookie);
+void remount_service(int fd, void *cookie);
+char * get_log_file_path(const char * log_name);
+#endif
+
+/* packet allocator */
+apacket *get_apacket(void);
+void put_apacket(apacket *p);
+
+int check_header(apacket *p);
+int check_data(apacket *p);
+
+/* define ADB_TRACE to 1 to enable tracing support, or 0 to disable it */
+
+#define  ADB_TRACE    1
+
+/* IMPORTANT: if you change the following list, don't
+ * forget to update the corresponding 'tags' table in
+ * the adb_trace_init() function implemented in adb.c
+ */
+typedef enum {
+    TRACE_ADB = 0,   /* 0x001 */
+    TRACE_SOCKETS,
+    TRACE_PACKETS,
+    TRACE_TRANSPORT,
+    TRACE_RWX,       /* 0x010 */
+    TRACE_USB,
+    TRACE_SYNC,
+    TRACE_SYSDEPS,
+    TRACE_JDWP,      /* 0x100 */
+    TRACE_SERVICES,
+} AdbTrace;
+
+#if ADB_TRACE
+
+  extern int     adb_trace_mask;
+  extern unsigned char    adb_trace_output_count;
+  void    adb_trace_init(void);
+
+#  define ADB_TRACING  ((adb_trace_mask & (1 << TRACE_TAG)) != 0)
+
+  /* you must define TRACE_TAG before using this macro */
+#  define  D(...)                                      \
+        do {                                           \
+            if (ADB_TRACING) {                         \
+                int save_errno = errno;                \
+                adb_mutex_lock(&D_lock);               \
+                fprintf(stderr, "%s::%s():",           \
+                        __FILE__, __FUNCTION__);       \
+                errno = save_errno;                    \
+                fprintf(stderr, __VA_ARGS__ );         \
+                fflush(stderr);                        \
+                adb_mutex_unlock(&D_lock);             \
+                errno = save_errno;                    \
+           }                                           \
+        } while (0)
+#  define  DR(...)                                     \
+        do {                                           \
+            if (ADB_TRACING) {                         \
+                int save_errno = errno;                \
+                adb_mutex_lock(&D_lock);               \
+                errno = save_errno;                    \
+                fprintf(stderr, __VA_ARGS__ );         \
+                fflush(stderr);                        \
+                adb_mutex_unlock(&D_lock);             \
+                errno = save_errno;                    \
+           }                                           \
+        } while (0)
+#else
+#  define  D(...)          ((void)0)
+#  define  DR(...)         ((void)0)
+#  define  ADB_TRACING     0
+#endif
+
+
+#if !TRACE_PACKETS
+#define print_packet(tag,p) do {} while (0)
+#endif
+
+#if ADB_HOST_ON_TARGET
+/* adb and adbd are coexisting on the target, so use 5038 for adb
+ * to avoid conflicting with adbd's usage of 5037
+ */
+#  define DEFAULT_ADB_PORT 5038
+#else
+#  define DEFAULT_ADB_PORT 5037
+#endif
+
+#define DEFAULT_ADB_LOCAL_TRANSPORT_PORT 5555
+
+#define ADB_CLASS              0xff
+#define ADB_SUBCLASS           0x42
+#define ADB_PROTOCOL           0x1
+
+
+void local_init(int port);
+int  local_connect(int  port);
+int  local_connect_arbitrary_ports(int console_port, int adb_port);
+
+/* usb host/client interface */
+void usb_init();
+void usb_cleanup();
+int usb_write(usb_handle *h, const void *data, int len);
+int usb_read(usb_handle *h, void *data, int len);
+int usb_close(usb_handle *h);
+void usb_kick(usb_handle *h);
+
+/* used for USB device detection */
+#if ADB_HOST
+int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);
+#endif
+
+unsigned host_to_le32(unsigned n);
+int adb_commandline(int argc, char **argv);
+
+int connection_state(atransport *t);
+
+#define CS_ANY       -1
+#define CS_OFFLINE    0
+#define CS_BOOTLOADER 1
+#define CS_DEVICE     2
+#define CS_HOST       3
+#define CS_RECOVERY   4
+#define CS_NOPERM     5 /* Insufficient permissions to communicate with the device */
+#define CS_SIDELOAD   6
+
+extern int HOST;
+extern int SHELL_EXIT_NOTIFY_FD;
+
+#define CHUNK_SIZE (64*1024)
+
+int sendfailmsg(int fd, const char *reason);
+int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s);
+
+#define ADB_SIDELOAD_FILENAME "/tmp/update.zip"
+
+#endif