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 /* Maximum length of the message that can be received from the guest. */
     37 #define ADB_MAX_MSG_LEN     8
     38 /* Enumerates ADB client state values. */
     39 typedef enum AdbClientState {
     40     /* Waiting on a connection from ADB host. */
     41     ADBC_STATE_WAIT_ON_HOST,
     42     /* ADB host is connected. Waiting on the transport initialization completion
     43      * in the guest. */
     44     ADBC_STATE_HOST_CONNECTED,
     45     /* Connection between ADB host and ADB guest is fully established. */
     46     ADBC_STATE_CONNECTED,
     47     /* ADB host has been disconnected. */
     48     ADBC_STATE_HOST_DISCONNECTED,
     49     /* ADB guest has been disconnected. */
     50     ADBC_STATE_GUEST_DISCONNECTED,
     51 } AdbClientState;
     52 
     53 /* ADB client descriptor. */
     54 typedef struct AdbClient AdbClient;
     55 struct AdbClient {
     56     /* Opaque pointer returned from adb_server_register_guest API. */
     57     void*           opaque;
     58     /* QEMUD client pipe for this client. */
     59     QemudClient*    qemud_client;
     60     /* Connection state. */
     61     AdbClientState  state;
     62     /* Buffer, collecting accept / stop messages from client. */
     63     char            msg_buffer[ADB_MAX_MSG_LEN];
     64     /* Current position in message buffer. */
     65     int             msg_cur;
     66 };
     67 
     68 /* ADB debugging client descriptor. */
     69 typedef struct AdbDbgClient AdbDbgClient;
     70 struct AdbDbgClient {
     71     /* QEMUD client pipe for this client. */
     72     QemudClient*    qemud_client;
     73 };
     74 
     75 /********************************************************************************
     76  *                      ADB host communication.
     77  *******************************************************************************/
     78 
     79 /* A callback that is invoked when the host is connected.
     80  * Param:
     81  *  opaque - AdbClient instance.
     82  *  connection - An opaque pointer that identifies connection with the ADB host.
     83  */
     84 static void
     85 _adb_on_host_connected(void* opaque, void* connection)
     86 {
     87     AdbClient* const adb_client = (AdbClient*)opaque;
     88 
     89     if (adb_client->state == ADBC_STATE_WAIT_ON_HOST) {
     90         D("ADB client %p(o=%p) is connected to the host %p",
     91           adb_client, adb_client->opaque, connection);
     92 
     93         /* Bump the state up. */
     94          adb_client->state = ADBC_STATE_HOST_CONNECTED;
     95 
     96         /* Notify the ADB guest that host has been  connected.This will unblock
     97          * the guest from a 'read', then guest will register the transport, and
     98          * will send 'setart' request, indicating that it is ready to receive
     99          * data from the host. */
    100         qemud_client_send(adb_client->qemud_client, (const uint8_t*)"ok", 2);
    101     } else {
    102         D("Unexpected ADB host connection while state is %d", adb_client->state);
    103     }
    104 }
    105 
    106 /* A callback that is invoked when the host gets disconnected.
    107  * Param:
    108  *  opaque - AdbClient instance.
    109  *  connection - An opaque pointer that identifies connection with the ADB host.
    110  */
    111 static void
    112 _adb_on_host_disconnect(void* opaque, void* connection)
    113 {
    114     AdbClient* const adb_client = (AdbClient*)opaque;
    115 
    116     D("ADB client %p(o=%p) is disconnected from the host %p",
    117       adb_client, adb_client->opaque, connection);
    118     adb_client->state = ADBC_STATE_HOST_DISCONNECTED;
    119 }
    120 
    121 /* A callback that is invoked when the host sends data.
    122  * Param:
    123  *  opaque - AdbClient instance.
    124  *  connection - An opaque pointer that identifies connection with the ADB host.
    125  *  buff, size - Buffer containing the host data.
    126  */
    127 static void
    128 _adb_on_host_data(void* opaque, void* connection, const void* buff, int size)
    129 {
    130     AdbClient* const adb_client = (AdbClient*)opaque;
    131     D("ADB client %p(o=%p) received from the host %p %d bytes in %s",
    132       adb_client, adb_client->opaque, connection, size, QB(buff, size));
    133 
    134     if (adb_client->state == ADBC_STATE_CONNECTED) {
    135         /* Dispatch data down to the guest. */
    136         qemud_client_send(adb_client->qemud_client, (const uint8_t*)buff, size);
    137     } else {
    138         D("Unexpected data from ADB host %p while client %p(o=%p) is in state %d",
    139           connection, adb_client, adb_client->opaque, adb_client->state);
    140     }
    141 }
    142 
    143 /* ADB guest API required for adb_server_register_guest */
    144 static AdbGuestRoutines _adb_client_routines = {
    145     /* A callback that is invoked when the host is connected. */
    146     _adb_on_host_connected,
    147     /* A callback that is invoked when the host gets disconnected. */
    148     _adb_on_host_disconnect,
    149     /* A callback that is invoked when the host sends data. */
    150     _adb_on_host_data,
    151 };
    152 
    153 /********************************************************************************
    154  *                      ADB guest communication.
    155  *******************************************************************************/
    156 
    157 /* Allocates AdbClient instance. */
    158 static AdbClient*
    159 _adb_client_new(void)
    160 {
    161     AdbClient* adb_client;
    162 
    163     ANEW0(adb_client);
    164 
    165     return adb_client;
    166 }
    167 
    168 /* Frees AdbClient instance, allocated with _adb_client_new */
    169 static void
    170 _adb_client_free(AdbClient* adb_client)
    171 {
    172     if (adb_client != NULL) {
    173         free(adb_client);
    174     }
    175 }
    176 
    177 /* A callback that is invoked when ADB guest sends data to the service.
    178  * Param:
    179  *  opaque - AdbClient instance.
    180  *  msg, msglen - Message received from the ADB guest.
    181  *  client - adb QEMUD client.
    182  */
    183 static void
    184 _adb_client_recv(void* opaque, uint8_t* msg, int msglen, QemudClient* client)
    185 {
    186     AdbClient* const adb_client = (AdbClient*)opaque;
    187 
    188     D("ADB client %p(o=%p) received from guest %d bytes in %s",
    189       adb_client, adb_client->opaque, msglen, QB(msg, msglen));
    190 
    191     if (adb_client->state == ADBC_STATE_CONNECTED) {
    192         /* Connection is fully established. Dispatch the message to the host. */
    193         adb_server_on_guest_message(adb_client->opaque, msg, msglen);
    194         return;
    195     }
    196 
    197     /*
    198      * At this point we expect either "accept", or "start" messages. Depending
    199      * on the state of the pipe (although small) these messages could be broken
    200      * into pieces. So, simply checking msg for "accept", or "start" may not
    201      * work. Lets collect them first in internal buffer, and then will see.
    202      */
    203 
    204     /* Make sure tha message doesn't overflow the buffer. */
    205     if ((msglen + adb_client->msg_cur) > sizeof(adb_client->msg_buffer)) {
    206         D("Unexpected message in ADB client.");
    207         adb_client->msg_cur = 0;
    208         return;
    209     }
    210     /* Append to current message. */
    211     memcpy(adb_client->msg_buffer + adb_client->msg_cur, msg, msglen);
    212     adb_client->msg_cur += msglen;
    213 
    214     /* Properly dispatch the message, depending on the client state. */
    215     switch (adb_client->state) {
    216         case ADBC_STATE_WAIT_ON_HOST:
    217             /* At this state the only message that is allowed is 'accept' */
    218             if (adb_client->msg_cur == 6 &&
    219                 !memcmp(adb_client->msg_buffer, "accept", 6)) {
    220                 adb_client->msg_cur = 0;
    221                 /* Register ADB guest connection with the ADB server. */
    222                 adb_client->opaque =
    223                     adb_server_register_guest(adb_client, &_adb_client_routines);
    224                 if (adb_client->opaque == NULL) {
    225                     D("Unable to register ADB guest with the ADB server.");
    226                     /* KO the guest. */
    227                     qemud_client_send(adb_client->qemud_client,
    228                                       (const uint8_t*)"ko", 2);
    229                 }
    230             } else {
    231                 D("Unexpected guest request while waiting on ADB host to connect.");
    232             }
    233             break;
    234 
    235         case ADBC_STATE_HOST_CONNECTED:
    236             /* At this state the only message that is allowed is 'start' */
    237             if (adb_client->msg_cur &&
    238                 !memcmp(adb_client->msg_buffer, "start", 5)) {
    239                 adb_client->msg_cur = 0;
    240                 adb_client->state = ADBC_STATE_CONNECTED;
    241                 adb_server_complete_connection(adb_client->opaque);
    242             } else {
    243                 D("Unexpected request while waiting on connection to start.");
    244             }
    245             break;
    246 
    247         default:
    248             D("Unexpected ADB guest request '%s' while client state is %d.",
    249               QB(msg, msglen), adb_client->state);
    250             break;
    251     }
    252 }
    253 
    254 /* A callback that is invoked when ADB guest disconnects from the service. */
    255 static void
    256 _adb_client_close(void* opaque)
    257 {
    258     AdbClient* const adb_client = (AdbClient*)opaque;
    259 
    260     D("ADB client %p(o=%p) is disconnected from the guest.",
    261       adb_client, adb_client->opaque);
    262     adb_client->state = ADBC_STATE_GUEST_DISCONNECTED;
    263     if (adb_client->opaque != NULL) {
    264         /* Close connection with the host. */
    265         adb_server_on_guest_closed(adb_client->opaque);
    266     }
    267     _adb_client_free(adb_client);
    268 }
    269 
    270 /* A callback that is invoked when ADB daemon running inside the guest connects
    271  * to the service.
    272  * Client parameters are ignored here. Typically they contain the ADB port number
    273  * which is always 5555 for the device / emulated system.
    274  */
    275 static QemudClient*
    276 _adb_service_connect(void*          opaque,
    277                      QemudService*  serv,
    278                      int            channel,
    279                      const char*    client_param)
    280 {
    281     /* Create new QEMUD client for the connection with ADB daemon. */
    282     AdbClient* const adb_client = _adb_client_new();
    283 
    284     D("Connecting ADB guest: '%s'", client_param ? client_param : "<null>");
    285     adb_client->qemud_client =
    286         qemud_client_new(serv, channel, client_param, adb_client,
    287                          _adb_client_recv, _adb_client_close, NULL, NULL);
    288     if (adb_client->qemud_client == NULL) {
    289         D("Unable to create QEMUD client for ADB guest.");
    290         _adb_client_free(adb_client);
    291         return NULL;
    292     }
    293 
    294     return adb_client->qemud_client;
    295 }
    296 
    297 /********************************************************************************
    298  *                      Debugging ADB guest communication.
    299  *******************************************************************************/
    300 
    301 /* Allocates AdbDbgClient instance. */
    302 static AdbDbgClient*
    303 _adb_dbg_client_new(void)
    304 {
    305     AdbDbgClient* adb_dbg_client;
    306 
    307     ANEW0(adb_dbg_client);
    308 
    309     return adb_dbg_client;
    310 }
    311 
    312 /* Frees AdbDbgClient instance, allocated with _adb_dbg_client_new */
    313 static void
    314 _adb_dbg_client_free(AdbDbgClient* adb_dbg_client)
    315 {
    316     if (adb_dbg_client != NULL) {
    317         free(adb_dbg_client);
    318     }
    319 }
    320 
    321 /* A callback that is invoked when ADB debugging guest sends data to the service.
    322  * Param:
    323  *  opaque - AdbDbgClient instance.
    324  *  msg, msglen - Message received from the ADB guest.
    325  *  client - adb-debug QEMUD client.
    326  */
    327 static void
    328 _adb_dbg_client_recv(void* opaque, uint8_t* msg, int msglen, QemudClient* client)
    329 {
    330     if (DD_ACTIVE) {
    331         fprintf(stderr, "ADB: %s", (const char*)msg);
    332     }
    333 }
    334 
    335 /* A callback that is invoked when ADB debugging guest disconnects from the
    336  * service. */
    337 static void
    338 _adb_dbg_client_close(void* opaque)
    339 {
    340     AdbDbgClient* const adb_dbg_client = (AdbDbgClient*)opaque;
    341 
    342     DD("ADB debugging client %p is disconnected from the guest.", adb_dbg_client);
    343     _adb_dbg_client_free(adb_dbg_client);
    344 }
    345 
    346 /* A callback that is invoked when ADB daemon running inside the guest connects
    347  * to the debugging service.
    348  * Client parameters are ignored here.
    349  */
    350 static QemudClient*
    351 _adb_debug_service_connect(void*          opaque,
    352                            QemudService*  serv,
    353                            int            channel,
    354                            const char*    client_param)
    355 {
    356     /* Create new QEMUD client for the connection with ADB debugger. */
    357     AdbDbgClient* const adb_dbg_client = _adb_dbg_client_new();
    358 
    359     DD("Connecting ADB debugging guest: '%s'",
    360        client_param ? client_param : "<null>");
    361     adb_dbg_client->qemud_client =
    362         qemud_client_new(serv, channel, client_param, adb_dbg_client,
    363                          _adb_dbg_client_recv, _adb_dbg_client_close, NULL, NULL);
    364     if (adb_dbg_client->qemud_client == NULL) {
    365         DD("Unable to create QEMUD client for ADB debugging guest.");
    366         _adb_dbg_client_free(adb_dbg_client);
    367         return NULL;
    368     }
    369 
    370     return adb_dbg_client->qemud_client;
    371 }
    372 
    373 /********************************************************************************
    374  *                      ADB service API.
    375  *******************************************************************************/
    376 
    377 void
    378 android_adb_service_init(void)
    379 {
    380 static int _inited = 0;
    381 
    382     if (!adb_server_is_initialized()) {
    383         return;
    384     }
    385 
    386     if (!_inited) {
    387         /* Register main ADB service. */
    388         QemudService*  serv = qemud_service_register(SERVICE_NAME, 0, NULL,
    389                                                      _adb_service_connect,
    390                                                      NULL, NULL);
    391         if (serv == NULL) {
    392             derror("%s: Could not register '%s' service",
    393                    __FUNCTION__, SERVICE_NAME);
    394             return;
    395         }
    396         D("%s: Registered '%s' qemud service", __FUNCTION__, SERVICE_NAME);
    397 
    398         /* Register debugging ADB service. */
    399         serv = qemud_service_register(DEBUG_SERVICE_NAME, 0, NULL,
    400                                       _adb_debug_service_connect, NULL, NULL);
    401         if (serv != NULL) {
    402             DD("Registered '%s' qemud service", DEBUG_SERVICE_NAME);
    403         } else {
    404             dwarning("%s: Could not register '%s' service",
    405                    __FUNCTION__, DEBUG_SERVICE_NAME);
    406         }
    407     }
    408 }
    409