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