Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "qemu-common.h"
     18 #include "android/globals.h"  /* for android_hw */
     19 #include "android/hw-qemud.h"
     20 #include "android/utils/misc.h"
     21 #include "android/utils/system.h"
     22 #include "android/utils/debug.h"
     23 #include "android/adb-server.h"
     24 #include "android/adb-qemud.h"
     25 
     26 #define  E(...)    derror(__VA_ARGS__)
     27 #define  W(...)    dwarning(__VA_ARGS__)
     28 #define  D(...)    VERBOSE_PRINT(adbclient,__VA_ARGS__)
     29 #define  DD(...)   VERBOSE_PRINT(adb,__VA_ARGS__)
     30 #define  D_ACTIVE  VERBOSE_CHECK(adbclient)
     31 #define  DD_ACTIVE VERBOSE_CHECK(adb)
     32 #define  QB(b, s)  quote_bytes((const char*)b, (s < 32) ? s : 32)
     33 
     34 #define SERVICE_NAME        "adb"
     35 #define DEBUG_SERVICE_NAME  "adb-debug"
     36 
     37 /* Enumerates ADB client state values. */
     38 typedef enum AdbClientState {
     39     /* Waiting on a connection from ADB host. */
     40     ADBC_STATE_WAIT_ON_HOST,
     41     /* ADB host is connected. Waiting on the transport initialization completion
     42      * in the guest. */
     43     ADBC_STATE_HOST_CONNECTED,
     44     /* Connection between ADB host and ADB guest is fully established. */
     45     ADBC_STATE_CONNECTED,
     46     /* ADB host has been disconnected. */
     47     ADBC_STATE_HOST_DISCONNECTED,
     48     /* ADB guest has been disconnected. */
     49     ADBC_STATE_GUEST_DISCONNECTED,
     50 } AdbClientState;
     51 
     52 /* ADB client descriptor. */
     53 typedef struct AdbClient AdbClient;
     54 struct AdbClient {
     55     /* Opaque pointer returned from adb_server_register_guest API. */
     56     void*           opaque;
     57     /* QEMUD client pipe for this client. */
     58     QemudClient*    qemud_client;
     59     /* Connection state. */
     60     AdbClientState  state;
     61 };
     62 
     63 /* ADB debugging client descriptor. */
     64 typedef struct AdbDbgClient AdbDbgClient;
     65 struct AdbDbgClient {
     66     /* QEMUD client pipe for this client. */
     67     QemudClient*    qemud_client;
     68 };
     69 
     70 /********************************************************************************
     71  *                      ADB host communication.
     72  *******************************************************************************/
     73 
     74 /* A callback that is invoked when the host is connected.
     75  * Param:
     76  *  opaque - AdbClient instance.
     77  *  connection - An opaque pointer that identifies connection with the ADB host.
     78  */
     79 static void
     80 _adb_on_host_connected(void* opaque, void* connection)
     81 {
     82     AdbClient* const adb_client = (AdbClient*)opaque;
     83 
     84     if (adb_client->state == ADBC_STATE_WAIT_ON_HOST) {
     85         D("ADB client %p(o=%p) is connected to the host %p",
     86           adb_client, adb_client->opaque, connection);
     87 
     88         /* Bump the state up. */
     89          adb_client->state = ADBC_STATE_HOST_CONNECTED;
     90 
     91         /* Notify the ADB guest that host has been  connected.This will unblock
     92          * the guest from a 'read', then guest will register the transport, and
     93          * will send 'setart' request, indicating that it is ready to receive
     94          * data from the host. */
     95         qemud_client_send(adb_client->qemud_client, (const uint8_t*)"ok", 2);
     96     } else {
     97         D("Unexpected ADB host connection while state is %d", adb_client->state);
     98     }
     99 }
    100 
    101 /* A callback that is invoked when the host gets disconnected.
    102  * Param:
    103  *  opaque - AdbClient instance.
    104  *  connection - An opaque pointer that identifies connection with the ADB host.
    105  */
    106 static void
    107 _adb_on_host_disconnect(void* opaque, void* connection)
    108 {
    109     AdbClient* const adb_client = (AdbClient*)opaque;
    110 
    111     D("ADB client %p(o=%p) is disconnected from the host %p",
    112       adb_client, adb_client->opaque, connection);
    113     adb_client->state = ADBC_STATE_HOST_DISCONNECTED;
    114 }
    115 
    116 /* A callback that is invoked when the host sends data.
    117  * Param:
    118  *  opaque - AdbClient instance.
    119  *  connection - An opaque pointer that identifies connection with the ADB host.
    120  *  buff, size - Buffer containing the host data.
    121  */
    122 static void
    123 _adb_on_host_data(void* opaque, void* connection, const void* buff, int size)
    124 {
    125     AdbClient* const adb_client = (AdbClient*)opaque;
    126     D("ADB client %p(o=%p) received from the host %p %d bytes in %s",
    127       adb_client, adb_client->opaque, connection, size, QB(buff, size));
    128 
    129     if (adb_client->state == ADBC_STATE_CONNECTED) {
    130         /* Dispatch data down to the guest. */
    131         qemud_client_send(adb_client->qemud_client, (const uint8_t*)buff, size);
    132     } else {
    133         D("Unexpected data from ADB host %p while client %p(o=%p) is in state %d",
    134           connection, adb_client, adb_client->opaque, adb_client->state);
    135     }
    136 }
    137 
    138 /* ADB guest API required for adb_server_register_guest */
    139 static AdbGuestRoutines _adb_client_routines = {
    140     /* A callback that is invoked when the host is connected. */
    141     _adb_on_host_connected,
    142     /* A callback that is invoked when the host gets disconnected. */
    143     _adb_on_host_disconnect,
    144     /* A callback that is invoked when the host sends data. */
    145     _adb_on_host_data,
    146 };
    147 
    148 /********************************************************************************
    149  *                      ADB guest communication.
    150  *******************************************************************************/
    151 
    152 /* Allocates AdbClient instance. */
    153 static AdbClient*
    154 _adb_client_new(void)
    155 {
    156     AdbClient* adb_client;
    157 
    158     ANEW0(adb_client);
    159 
    160     return adb_client;
    161 }
    162 
    163 /* Frees AdbClient instance, allocated with _adb_client_new */
    164 static void
    165 _adb_client_free(AdbClient* adb_client)
    166 {
    167     if (adb_client != NULL) {
    168         free(adb_client);
    169     }
    170 }
    171 
    172 /* A callback that is invoked when ADB guest sends data to the service.
    173  * Param:
    174  *  opaque - AdbClient instance.
    175  *  msg, msglen - Message received from the ADB guest.
    176  *  client - adb QEMUD client.
    177  */
    178 static void
    179 _adb_client_recv(void* opaque, uint8_t* msg, int msglen, QemudClient* client)
    180 {
    181     AdbClient* const adb_client = (AdbClient*)opaque;
    182 
    183     D("ADB client %p(o=%p) received from guest %d bytes in %s",
    184       adb_client, adb_client->opaque, msglen, QB(msg, msglen));
    185 
    186     /* Properly dispatch the message, depending on the client state. */
    187     switch (adb_client->state) {
    188         case ADBC_STATE_CONNECTED:
    189             /* Connection is fully established. Dispatch the message to the
    190              * host. */
    191             adb_server_on_guest_message(adb_client->opaque, msg, msglen);
    192             break;
    193 
    194         case ADBC_STATE_WAIT_ON_HOST:
    195             /* At this state the only message that is allowed is 'accept' */
    196             if (msglen == 6 && !memcmp(msg, "accept", 6)) {
    197                 /* Register ADB guest connection with the ADB server. */
    198                 adb_client->opaque =
    199                     adb_server_register_guest(adb_client, &_adb_client_routines);
    200                 if (adb_client->opaque == NULL) {
    201                     D("Unable to register ADB guest with the ADB server.");
    202                     /* KO the guest. */
    203                     qemud_client_send(adb_client->qemud_client,
    204                                       (const uint8_t*)"ko", 2);
    205                 }
    206             } else {
    207                 D("Unexpected guest request while waiting on ADB host to connect.");
    208             }
    209             break;
    210 
    211         case ADBC_STATE_HOST_CONNECTED:
    212             /* At this state the only message that is allowed is 'start' */
    213             if (msglen == 5 && !memcmp(msg, "start", 5)) {
    214                 adb_client->state = ADBC_STATE_CONNECTED;
    215                 adb_server_complete_connection(adb_client->opaque);
    216             } else {
    217                 D("Unexpected request while waiting on connection to start.");
    218             }
    219             break;
    220 
    221         default:
    222             D("Unexpected ADB guest request '%s' while client state is %d.",
    223               QB(msg, msglen), adb_client->state);
    224             break;
    225     }
    226 }
    227 
    228 /* A callback that is invoked when ADB guest disconnects from the service. */
    229 static void
    230 _adb_client_close(void* opaque)
    231 {
    232     AdbClient* const adb_client = (AdbClient*)opaque;
    233 
    234     D("ADB client %p(o=%p) is disconnected from the guest.",
    235       adb_client, adb_client->opaque);
    236     adb_client->state = ADBC_STATE_GUEST_DISCONNECTED;
    237     if (adb_client->opaque != NULL) {
    238         /* Close connection with the host. */
    239         adb_server_on_guest_closed(adb_client->opaque);
    240     }
    241     _adb_client_free(adb_client);
    242 }
    243 
    244 /* A callback that is invoked when ADB daemon running inside the guest connects
    245  * to the service.
    246  * Client parameters are ignored here. Typically they contain the ADB port number
    247  * which is always 5555 for the device / emulated system.
    248  */
    249 static QemudClient*
    250 _adb_service_connect(void*          opaque,
    251                      QemudService*  serv,
    252                      int            channel,
    253                      const char*    client_param)
    254 {
    255     /* Create new QEMUD client for the connection with ADB daemon. */
    256     AdbClient* const adb_client = _adb_client_new();
    257 
    258     D("Connecting ADB guest: '%s'", client_param ? client_param : "<null>");
    259     adb_client->qemud_client =
    260         qemud_client_new(serv, channel, client_param, adb_client,
    261                          _adb_client_recv, _adb_client_close, NULL, NULL);
    262     if (adb_client->qemud_client == NULL) {
    263         D("Unable to create QEMUD client for ADB guest.");
    264         _adb_client_free(adb_client);
    265         return NULL;
    266     }
    267 
    268     return adb_client->qemud_client;
    269 }
    270 
    271 /********************************************************************************
    272  *                      Debugging ADB guest communication.
    273  *******************************************************************************/
    274 
    275 /* Allocates AdbDbgClient instance. */
    276 static AdbDbgClient*
    277 _adb_dbg_client_new(void)
    278 {
    279     AdbDbgClient* adb_dbg_client;
    280 
    281     ANEW0(adb_dbg_client);
    282 
    283     return adb_dbg_client;
    284 }
    285 
    286 /* Frees AdbDbgClient instance, allocated with _adb_dbg_client_new */
    287 static void
    288 _adb_dbg_client_free(AdbDbgClient* adb_dbg_client)
    289 {
    290     if (adb_dbg_client != NULL) {
    291         free(adb_dbg_client);
    292     }
    293 }
    294 
    295 /* A callback that is invoked when ADB debugging guest sends data to the service.
    296  * Param:
    297  *  opaque - AdbDbgClient instance.
    298  *  msg, msglen - Message received from the ADB guest.
    299  *  client - adb-debug QEMUD client.
    300  */
    301 static void
    302 _adb_dbg_client_recv(void* opaque, uint8_t* msg, int msglen, QemudClient* client)
    303 {
    304     if (DD_ACTIVE) {
    305         fprintf(stderr, "ADB: %s", (const char*)msg);
    306     }
    307 }
    308 
    309 /* A callback that is invoked when ADB debugging guest disconnects from the
    310  * service. */
    311 static void
    312 _adb_dbg_client_close(void* opaque)
    313 {
    314     AdbDbgClient* const adb_dbg_client = (AdbDbgClient*)opaque;
    315 
    316     DD("ADB debugging client %p is disconnected from the guest.", adb_dbg_client);
    317     _adb_dbg_client_free(adb_dbg_client);
    318 }
    319 
    320 /* A callback that is invoked when ADB daemon running inside the guest connects
    321  * to the debugging service.
    322  * Client parameters are ignored here.
    323  */
    324 static QemudClient*
    325 _adb_debug_service_connect(void*          opaque,
    326                            QemudService*  serv,
    327                            int            channel,
    328                            const char*    client_param)
    329 {
    330     /* Create new QEMUD client for the connection with ADB debugger. */
    331     AdbDbgClient* const adb_dbg_client = _adb_dbg_client_new();
    332 
    333     DD("Connecting ADB debugging guest: '%s'",
    334        client_param ? client_param : "<null>");
    335     adb_dbg_client->qemud_client =
    336         qemud_client_new(serv, channel, client_param, adb_dbg_client,
    337                          _adb_dbg_client_recv, _adb_dbg_client_close, NULL, NULL);
    338     if (adb_dbg_client->qemud_client == NULL) {
    339         DD("Unable to create QEMUD client for ADB debugging guest.");
    340         _adb_dbg_client_free(adb_dbg_client);
    341         return NULL;
    342     }
    343 
    344     return adb_dbg_client->qemud_client;
    345 }
    346 
    347 /********************************************************************************
    348  *                      ADB service API.
    349  *******************************************************************************/
    350 
    351 void
    352 android_adb_service_init(void)
    353 {
    354 static int _inited = 0;
    355 
    356     if (!adb_server_is_initialized()) {
    357         return;
    358     }
    359 
    360     if (!_inited) {
    361         /* Register main ADB service. */
    362         QemudService*  serv = qemud_service_register(SERVICE_NAME, 0, NULL,
    363                                                      _adb_service_connect,
    364                                                      NULL, NULL);
    365         if (serv == NULL) {
    366             derror("%s: Could not register '%s' service",
    367                    __FUNCTION__, SERVICE_NAME);
    368             return;
    369         }
    370         D("%s: Registered '%s' qemud service", __FUNCTION__, SERVICE_NAME);
    371 
    372         /* Register debugging ADB service. */
    373         serv = qemud_service_register(DEBUG_SERVICE_NAME, 0, NULL,
    374                                       _adb_debug_service_connect, NULL, NULL);
    375         if (serv != NULL) {
    376             DD("Registered '%s' qemud service", DEBUG_SERVICE_NAME);
    377         } else {
    378             dwarning("%s: Could not register '%s' service",
    379                    __FUNCTION__, DEBUG_SERVICE_NAME);
    380         }
    381     }
    382 }
    383