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