• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
_adb_on_host_connected(void * opaque,void * connection)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
_adb_on_host_disconnect(void * opaque,void * connection)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
_adb_on_host_data(void * opaque,void * connection,const void * buff,int size)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*
_adb_client_new(void)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
_adb_client_free(AdbClient * adb_client)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
_adb_client_recv(void * opaque,uint8_t * msg,int msglen,QemudClient * client)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
_adb_client_close(void * opaque)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*
_adb_service_connect(void * opaque,QemudService * serv,int channel,const char * client_param)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*
_adb_dbg_client_new(void)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
_adb_dbg_client_free(AdbDbgClient * adb_dbg_client)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
_adb_dbg_client_recv(void * opaque,uint8_t * msg,int msglen,QemudClient * client)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
_adb_dbg_client_close(void * opaque)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*
_adb_debug_service_connect(void * opaque,QemudService * serv,int channel,const char * client_param)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
android_adb_service_init(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