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 /* 18 * Encapsulates exchange protocol between the emulator, and an Android device 19 * that is connected to the host via USB. The communication is established over 20 * a TCP port forwarding, enabled by ADB. 21 */ 22 23 #include "android/android-device.h" 24 #include "utils/panic.h" 25 #include "iolooper.h" 26 27 #define E(...) derror(__VA_ARGS__) 28 #define W(...) dwarning(__VA_ARGS__) 29 #define D(...) VERBOSE_PRINT(adevice,__VA_ARGS__) 30 #define D_ACTIVE VERBOSE_CHECK(adevice) 31 32 /******************************************************************************** 33 * Common android device socket 34 *******************************************************************************/ 35 36 /* Milliseconds between retrying asynchronous connections to the device. */ 37 #define ADS_RETRY_CONNECTION_TIMEOUT 3000 38 39 /* Socket type. */ 40 typedef enum ADSType { 41 /* Query socket. */ 42 ADS_TYPE_QUERY = 0, 43 /* Events socket. */ 44 ADS_TYPE_EVENT = 1 45 } ADSType; 46 47 /* Status of the socket. */ 48 typedef enum ADSStatus { 49 /* Socket is disconnected. */ 50 ADS_DISCONNECTED, 51 /* Connection process has been started. */ 52 ADS_CONNECTING, 53 /* Connection has been established. */ 54 ADS_CONNECTED, 55 /* Socket has been registered with the server. */ 56 ADS_REGISTERED, 57 } ADSStatus; 58 59 /* Identifies socket as a "query" socket with the server. */ 60 static const char* _ads_query_socket_id = "query"; 61 /* Identifies socket as an "event" socket with the server. */ 62 static const char* _ads_event_socket_id = "event"; 63 64 /* Android device socket descriptor. */ 65 typedef struct AndroidDevSocket AndroidDevSocket; 66 67 /* 68 * Callback routines. 69 */ 70 71 /* Callback routine that is called when a socket is connected. 72 * Param: 73 * opaque - Opaque pointer associated with the socket. Typicaly it's the same 74 * pointer that is associated with AndroidDevice instance. 75 * ads - Connection socket. 76 * failure - If zero, indicates that socket has been successuly connected. If a 77 * connection error has occured, this parameter contains the error code (as 78 * in 'errno). 79 */ 80 typedef void (*ads_socket_connected_cb)(void* opaque, 81 struct AndroidDevSocket* ads, 82 int failure); 83 84 /* Android device socket descriptor. */ 85 struct AndroidDevSocket { 86 /* Socket type. */ 87 ADSType type; 88 /* Socket status. */ 89 ADSStatus socket_status; 90 /* TCP address for the socket. */ 91 SockAddress address; 92 /* Android device descriptor that owns the socket. */ 93 AndroidDevice* ad; 94 /* Opaque pointer associated with the socket. Typicaly it's the same 95 * pointer that is associated with AndroidDevice instance.*/ 96 void* opaque; 97 /* Deadline for current I/O performed on the socket. */ 98 Duration deadline; 99 /* Socket's file descriptor. */ 100 int fd; 101 }; 102 103 /* Query socket descriptor. */ 104 typedef struct AndroidQuerySocket { 105 /* Common device socket. */ 106 AndroidDevSocket dev_socket; 107 } AndroidQuerySocket; 108 109 /* Describes data to send via an asynchronous socket. */ 110 typedef struct AsyncSendBuffer { 111 /* Next buffer to send. */ 112 struct AsyncSendBuffer* next; 113 /* Callback to invoke when data transfer is completed. */ 114 async_send_cb complete_cb; 115 /* An opaque pointer to pass to the transfer completion callback. */ 116 void* complete_opaque; 117 /* Data to send. */ 118 uint8_t* data; 119 /* Size of the entire data buffer. */ 120 int data_size; 121 /* Remaining bytes to send. */ 122 int data_remaining; 123 /* Boolean flag indicating whether to free data buffer upon completion. */ 124 int free_on_completion; 125 } AsyncSendBuffer; 126 127 /* Event socket descriptor. */ 128 typedef struct AndroidEventSocket { 129 /* Common socket descriptor. */ 130 AndroidDevSocket dev_socket; 131 /* Asynchronous connector to the device. */ 132 AsyncConnector connector[1]; 133 /* I/O port for asynchronous I/O on this socket. */ 134 LoopIo io[1]; 135 /* Asynchronous string reader. */ 136 AsyncLineReader alr; 137 /* Callback to call at the end of the asynchronous connection to this socket. 138 * Can be NULL. */ 139 ads_socket_connected_cb on_connected; 140 /* Callback to call when an event is received on this socket. Can be NULL. */ 141 event_cb on_event; 142 /* Lists buffers that are pending to be sent. */ 143 AsyncSendBuffer* send_pending; 144 } AndroidEventSocket; 145 146 /* Android device descriptor. */ 147 struct AndroidDevice { 148 /* Query socket for the device. */ 149 AndroidQuerySocket query_socket; 150 /* Event socket for the device. */ 151 AndroidEventSocket event_socket; 152 /* An opaque pointer associated with this descriptor. */ 153 void* opaque; 154 /* I/O looper for synchronous I/O on the sockets for this device. */ 155 IoLooper* io_looper; 156 /* Timer that is used to retry asynchronous connections. */ 157 LoopTimer timer[1]; 158 /* I/O looper for asynchronous I/O. */ 159 Looper* looper; 160 /* Callback to call when device is fully connected. */ 161 device_connected_cb on_connected; 162 /* I/O failure callback .*/ 163 io_failure_cb on_io_failure; 164 }; 165 166 /* Creates descriptor for a buffer to send asynchronously. 167 * Param: 168 * data, size - Buffer to send. 169 * free_on_close - Boolean flag indicating whether to free data buffer upon 170 * completion. 171 * cb - Callback to invoke when data transfer is completed. 172 * opaque - An opaque pointer to pass to the transfer completion callback. 173 */ 174 static AsyncSendBuffer* 175 _async_send_buffer_create(void* data, 176 int size, 177 int free_on_close, 178 async_send_cb cb, 179 void* opaque) 180 { 181 AsyncSendBuffer* desc = malloc(sizeof(AsyncSendBuffer)); 182 if (desc == NULL) { 183 APANIC("Unable to allocate %d bytes for AsyncSendBuffer", 184 sizeof(AsyncSendBuffer)); 185 } 186 desc->next = NULL; 187 desc->data = (uint8_t*)data; 188 desc->data_size = desc->data_remaining = size; 189 desc->free_on_completion = free_on_close; 190 desc->complete_cb = cb; 191 desc->complete_opaque = opaque; 192 193 return desc; 194 } 195 196 /* Completes data transfer for the given descriptor. 197 * Note that this routine will free the descriptor. 198 * Param: 199 * desc - Asynchronous data transfer descriptor. Will be freed upon the exit 200 * from this routine. 201 * res - Data transfer result. 202 */ 203 static void 204 _async_send_buffer_complete(AsyncSendBuffer* desc, ATResult res) 205 { 206 /* Invoke completion callback (if present) */ 207 if (desc->complete_cb) { 208 desc->complete_cb(desc->complete_opaque, res, desc->data, desc->data_size, 209 desc->data_size - desc->data_remaining); 210 } 211 212 /* Free data buffer (if required) */ 213 if (desc->free_on_completion) { 214 free(desc->data); 215 } 216 217 /* Free the descriptor itself. */ 218 free(desc); 219 } 220 221 /******************************************************************************** 222 * Common socket declarations 223 *******************************************************************************/ 224 225 /* Initializes common device socket. 226 * Param: 227 * ads - Socket descriptor to initialize. 228 * opaque - An opaque pointer to associate with the socket. Typicaly it's the 229 * same pointer that is associated with AndroidDevice instance. 230 * ad - Android device descriptor that owns the socket. 231 * port - Socket's TCP port. 232 * type - Socket type (query, or event). 233 */ 234 static int _android_dev_socket_init(AndroidDevSocket* ads, 235 void* opaque, 236 AndroidDevice* ad, 237 int port, 238 ADSType type); 239 240 /* Destroys socket descriptor. */ 241 static void _android_dev_socket_destroy(AndroidDevSocket* ads); 242 243 /* Callback that is ivoked from _android_dev_socket_connect when a file 244 * descriptor has been created for a socket. 245 * Param: 246 * ads - Socket descritor. 247 * opaque - An opaque pointer associated with the callback. 248 */ 249 typedef void (*on_socked_fd_created)(AndroidDevSocket* ads, void* opaque); 250 251 /* Synchronously connects to the socket, and registers it with the server. 252 * Param: 253 * ads - Socket to connect. Must have 'deadline' field properly setup. 254 * cb, opaque - A callback to invoke (and opaque parameters to pass to the 255 * callback) when a file descriptor has been created for a socket. These 256 * parameters are optional and can be NULL. 257 * Return: 258 * 0 on success, -1 on failure with errno containing the reason for failure. 259 */ 260 static int _android_dev_socket_connect(AndroidDevSocket* ads, 261 on_socked_fd_created cb, 262 void* opaque); 263 264 /* Synchronously registers a connected socket with the server. 265 * Param: 266 * ads - Socket to register. Must be connected, and must have 'deadline' field 267 * properly setup. 268 * Return: 269 * 0 on success, -1 on failure with errno containing the reason for failure. 270 */ 271 static int _android_dev_socket_register(AndroidDevSocket* ads); 272 273 /* Disconnects the socket (if it was connected) */ 274 static void _android_dev_socket_disconnect(AndroidDevSocket* ads); 275 276 /* Synchronously sends data to the socket. 277 * Param: 278 * ads - Socket to send the data to. Must be connected, and must have 'deadline' 279 * field properly setup. 280 * buff, buffsize - Buffer to send. 281 * Return: 282 * Number of bytes sent on success, or -1 on failure with errno containing the 283 * reason for failure. 284 */ 285 static int _android_dev_socket_send(AndroidDevSocket* ads, 286 const char* buff, 287 int buffsize); 288 289 /* Synchronously receives data from the socket. 290 * Param: 291 * ads - Socket to receive the data from. Must be connected, and must have 292 * 'deadline' field properly setup. 293 * buff, buffsize - Buffer where to receive data. 294 * Return: 295 * Number of bytes received on success, or -1 on failure with errno containing 296 * the reason for failure. 297 */ 298 static int _android_dev_socket_recv(AndroidDevSocket* ads, 299 char* buf, 300 int bufsize); 301 302 /* Synchronously reads zero-terminated string from the socket. 303 * Param: 304 * ads - Socket to read the string from. Must be connected, and must have 305 * 'deadline' field properly setup. 306 * str, strsize - Buffer where to read the string. 307 * Return: 308 * Number of charactes read into the string buffer (including zero-terminator) 309 * on success, or -1 on failure with 'errno' containing the reason for failure. 310 * If this routine returns -1, and errno contains ENOMEM, this is an indicator 311 * that supplied string buffer was too small for the receiving string. 312 */ 313 static int _android_dev_socket_read_string(AndroidDevSocket* ads, 314 char* str, 315 int strsize); 316 317 /* Synchronously reads zero-terminated query response from the socket. 318 * All queries respond with an 'ok', or 'ko' prefix, indicating a success, or 319 * failure. Prefix can be followed by more query response data, separated from 320 * the prefix with a ':' character. This routine helps separating prefix from the 321 * data, by placing only the query response data into provided buffer. 'ko' or 322 * 'ok' will be encoded in the return value. 323 * Param: 324 * ads - Socket to read the response from. Must be connected, and must have 325 * 'deadline' field properly setup. 326 * data, datasize - Buffer where to read the query response data. 327 * Return: 328 * Number of charactes read into the data buffer (including zero-terminator) on 329 * success, or -1 on failure with errno containing the reason for failure. 330 * If the query has been completed with 'ko', this routine will return -1, with 331 * errno set to 0. If this routine returned -1, and errno is set to EINVAL, this 332 * indicates that reply string didn't match expected query reply format. 333 */ 334 static int _android_dev_socket_read_response(AndroidDevSocket* ads, 335 char* str, 336 int strsize); 337 338 /* Gets ID string for the channel. */ 339 AINLINED const char* 340 _ads_id_str(AndroidDevSocket* ads) 341 { 342 return (ads->type == ADS_TYPE_QUERY) ? _ads_query_socket_id : 343 _ads_event_socket_id; 344 } 345 346 /* Gets socket's TCP port. */ 347 AINLINED int 348 _ads_port(AndroidDevSocket* ads) 349 { 350 return sock_address_get_port(&ads->address); 351 } 352 353 /* Gets synchronous I/O looper for the socket. */ 354 AINLINED IoLooper* 355 _ads_io_looper(AndroidDevSocket* ads) 356 { 357 return ads->ad->io_looper; 358 } 359 360 /* Sets deadline on a socket operation, given relative timeout. 361 * Param: 362 * ads - Socket descriptor to set deadline for. 363 * to - Relative timeout (in millisec) for the operation. 364 * AD_INFINITE_WAIT passed in this parameter means "no deadline". 365 */ 366 AINLINED void 367 _ads_set_deadline(AndroidDevSocket* ads, int to) 368 { 369 ads->deadline = (to == AD_INFINITE_WAIT) ? DURATION_INFINITE : 370 iolooper_now() + to; 371 } 372 373 /******************************************************************************** 374 * Common socket implementation 375 *******************************************************************************/ 376 377 static int 378 _android_dev_socket_init(AndroidDevSocket* ads, 379 void* opaque, 380 AndroidDevice* ad, 381 int port, 382 ADSType type) 383 { 384 ads->type = type; 385 ads->socket_status = ADS_DISCONNECTED; 386 ads->opaque = opaque; 387 ads->ad = ad; 388 ads->fd = -1; 389 sock_address_init_inet(&ads->address, SOCK_ADDRESS_INET_LOOPBACK, port); 390 391 return 0; 392 } 393 394 static void 395 _android_dev_socket_destroy(AndroidDevSocket* ads) 396 { 397 /* Make sure it's disconnected. */ 398 _android_dev_socket_disconnect(ads); 399 400 /* Finalize socket address. */ 401 sock_address_done(&ads->address); 402 memset(&ads->address, 0, sizeof(ads->address)); 403 } 404 405 static int 406 _android_dev_socket_connect(AndroidDevSocket* ads, 407 on_socked_fd_created cb, 408 void* opaque) 409 { 410 int res; 411 412 /* Create communication socket. */ 413 ads->fd = socket_create_inet(SOCKET_STREAM); 414 if (ads->fd < 0) { 415 D("Unable to create socket for channel '%s'@%d: %s", 416 _ads_id_str(ads), _ads_port(ads), strerror(errno)); 417 return -1; 418 } 419 socket_set_nonblock(ads->fd); 420 421 /* Invoke FD creation callback (if required) */ 422 if (cb != NULL) { 423 cb(ads, opaque); 424 } 425 426 /* Synchronously connect to it. */ 427 ads->socket_status = ADS_CONNECTING; 428 iolooper_add_write(_ads_io_looper(ads), ads->fd); 429 res = socket_connect(ads->fd, &ads->address); 430 while (res < 0 && errno == EINTR) { 431 res = socket_connect(ads->fd, &ads->address); 432 } 433 434 if (res && (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN)) { 435 /* Connection is delayed. Wait for it until timeout expires. */ 436 res = iolooper_wait_absolute(_ads_io_looper(ads), ads->deadline); 437 if (res > 0) { 438 /* Pick up on possible connection error. */ 439 errno = socket_get_error(ads->fd); 440 res = (errno == 0) ? 0 : -1; 441 } else { 442 res = -1; 443 } 444 } 445 iolooper_del_write(_ads_io_looper(ads), ads->fd); 446 447 if (res == 0) { 448 D("Channel '%s'@%d is connected", _ads_id_str(ads), _ads_port(ads)); 449 /* Socket is connected. Now register it with the server. */ 450 ads->socket_status = ADS_CONNECTED; 451 res = _android_dev_socket_register(ads); 452 } else { 453 D("Unable to connect channel '%s' to port %d: %s", 454 _ads_id_str(ads), _ads_port(ads), strerror(errno)); 455 } 456 457 if (res) { 458 _android_dev_socket_disconnect(ads); 459 } 460 461 return res; 462 } 463 464 static int 465 _android_dev_socket_register(AndroidDevSocket* ads) 466 { 467 /* Make sure that socket is connected. */ 468 if (ads->socket_status < ADS_CONNECTED) { 469 D("Attempt to register a disconnected channel '%s'@%d", 470 _ads_id_str(ads), _ads_port(ads)); 471 errno = ECONNRESET; 472 return -1; 473 } 474 475 /* Register this socket accordingly to its type. */ 476 const char* reg_str = _ads_id_str(ads); 477 int res = _android_dev_socket_send(ads, reg_str, strlen(reg_str) + 1); 478 if (res > 0) { 479 /* Receive reply. Note that according to the protocol, the server should 480 * reply to channel registration with 'ok', or 'ko' (just like with queries), 481 * so we can use query reply reader here. */ 482 char reply[256]; 483 res = _android_dev_socket_read_response(ads, reply, sizeof(reply)); 484 if (res >= 0) { 485 /* Socket is now registered. */ 486 ads->socket_status = ADS_REGISTERED; 487 D("Channel '%s'@%d is registered", _ads_id_str(ads), _ads_port(ads)); 488 res = 0; 489 } else { 490 if (errno == 0) { 491 /* 'ko' condition */ 492 D("Device failed registration of channel '%s'@%d: %s", 493 _ads_id_str(ads), _ads_port(ads), reply); 494 errno = EINVAL; 495 } else { 496 D("I/O failure while registering channel '%s'@%d: %s", 497 _ads_id_str(ads), _ads_port(ads), strerror(errno)); 498 } 499 res = -1; 500 } 501 } else { 502 D("Unable to send registration query for channel '%s'@%d: %s", 503 _ads_id_str(ads), _ads_port(ads), strerror(errno)); 504 res = -1; 505 } 506 507 return res; 508 } 509 510 static void 511 _android_dev_socket_disconnect(AndroidDevSocket* ads) 512 { 513 /* Preserve errno */ 514 const int save_error = errno; 515 if (ads->socket_status != ADS_DISCONNECTED) { 516 /* Reset I/O looper for this socket. */ 517 iolooper_modify(_ads_io_looper(ads), ads->fd, 518 IOLOOPER_READ | IOLOOPER_WRITE, 0); 519 520 /* Mark as disconnected. */ 521 ads->socket_status = ADS_DISCONNECTED; 522 523 /* Close socket. */ 524 if (ads->fd >= 0) { 525 socket_close(ads->fd); 526 ads->fd = -1; 527 } 528 } 529 errno = save_error; 530 } 531 532 static int 533 _android_dev_socket_send(AndroidDevSocket* ads, const char* buff, int to_send) 534 { 535 int sent = 0; 536 537 /* Make sure that socket is connected. */ 538 if (ads->socket_status < ADS_CONNECTED) { 539 D("Attempt to send via disconnected channel '%s'@%d", 540 _ads_id_str(ads), _ads_port(ads)); 541 errno = ECONNRESET; 542 return -1; 543 } 544 545 iolooper_add_write(_ads_io_looper(ads), ads->fd); 546 do { 547 int res = socket_send(ads->fd, buff + sent, to_send - sent); 548 if (res == 0) { 549 /* Disconnection. */ 550 errno = ECONNRESET; 551 sent = -1; 552 break; 553 } 554 555 if (res < 0) { 556 if (errno == EINTR) { 557 /* loop on EINTR */ 558 continue; 559 } 560 561 if (errno == EWOULDBLOCK || errno == EAGAIN) { 562 res = iolooper_wait_absolute(_ads_io_looper(ads), ads->deadline); 563 if (res > 0) { 564 /* Ready to write. */ 565 continue; 566 } 567 } 568 sent = -1; 569 break; 570 } 571 sent += res; 572 } while (sent < to_send); 573 iolooper_del_write(_ads_io_looper(ads), ads->fd); 574 575 /* In case of an I/O failure we have to invoke failure callback. Note that we 576 * report I/O failures only on registered sockets. */ 577 if (sent < 0) { 578 D("I/O error while sending data via channel '%s'@%d: %s", 579 _ads_id_str(ads), _ads_port(ads), strerror(errno)); 580 581 if (ads->ad->on_io_failure != NULL && ads->socket_status > ADS_CONNECTED) { 582 const char save_error = errno; 583 ads->ad->on_io_failure(ads->opaque, ads->ad, save_error); 584 errno = save_error; 585 } 586 } 587 588 return sent; 589 } 590 591 static int 592 _android_dev_socket_recv(AndroidDevSocket* ads, char* buf, int bufsize) 593 { 594 int recvd = 0; 595 596 /* Make sure that socket is connected. */ 597 if (ads->socket_status < ADS_CONNECTED) { 598 D("Attempt to receive from disconnected channel '%s'@%d", 599 _ads_id_str(ads), _ads_port(ads)); 600 errno = ECONNRESET; 601 return -1; 602 } 603 604 iolooper_add_read(_ads_io_looper(ads), ads->fd); 605 do { 606 int res = socket_recv(ads->fd, buf + recvd, bufsize - recvd); 607 if (res == 0) { 608 /* Disconnection. */ 609 errno = ECONNRESET; 610 recvd = -1; 611 break; 612 } 613 614 if (res < 0) { 615 if (errno == EINTR) { 616 /* loop on EINTR */ 617 continue; 618 } 619 620 if (errno == EWOULDBLOCK || errno == EAGAIN) { 621 res = iolooper_wait_absolute(_ads_io_looper(ads), ads->deadline); 622 if (res > 0) { 623 /* Ready to read. */ 624 continue; 625 } 626 } 627 recvd = -1; 628 break; 629 } 630 recvd += res; 631 } while (recvd < bufsize); 632 iolooper_del_read(_ads_io_looper(ads), ads->fd); 633 634 /* In case of an I/O failure we have to invoke failure callback. Note that we 635 * report I/O failures only on registered sockets. */ 636 if (recvd < 0) { 637 D("I/O error while receiving from channel '%s'@%d: %s", 638 _ads_id_str(ads), _ads_port(ads), strerror(errno)); 639 640 if (ads->ad->on_io_failure != NULL && ads->socket_status > ADS_CONNECTED) { 641 const char save_error = errno; 642 ads->ad->on_io_failure(ads->opaque, ads->ad, save_error); 643 errno = save_error; 644 } 645 } 646 647 return recvd; 648 } 649 650 static int 651 _android_dev_socket_read_string(AndroidDevSocket* ads, char* str, int strsize) 652 { 653 int n; 654 655 /* Char by char read from the socket, until zero-terminator is read. */ 656 for (n = 0; n < strsize; n++) { 657 if (_android_dev_socket_recv(ads, str + n, 1) > 0) { 658 if (str[n] == '\0') { 659 /* Done. */ 660 return n + 1; /* Including zero-terminator. */ 661 } 662 } else { 663 /* I/O error. */ 664 return -1; 665 } 666 } 667 668 /* Buffer was too small. Report that by setting errno to ENOMEM. */ 669 D("Buffer %d is too small to receive a string from channel '%s'@%d", 670 strsize, _ads_id_str(ads), _ads_port(ads)); 671 errno = ENOMEM; 672 return -1; 673 } 674 675 static int 676 _android_dev_socket_read_response(AndroidDevSocket* ads, char* data, int datasize) 677 { 678 int n, res; 679 int success = 0; 680 int failure = 0; 681 int bad_format = 0; 682 char ok[4]; 683 684 *data = '\0'; 685 686 /* Char by char read from the socket, until ok/ko is read. */ 687 for (n = 0; n < 2; n++) { 688 res = _android_dev_socket_recv(ads, ok + n, 1); 689 if (res > 0) { 690 if (ok[n] == '\0') { 691 /* EOS is unexpected here! */ 692 D("Bad query reply format on channel '%s'@%d: '%s' is too short.", 693 _ads_id_str(ads), _ads_port(ads), ok); 694 errno = EINVAL; 695 return -1; 696 } 697 } else { 698 /* I/O error. */ 699 return -1; 700 } 701 } 702 703 /* Next character must be either ':', or '\0' */ 704 res = _android_dev_socket_recv(ads, ok + n, 1); 705 if (res <= 0) { 706 /* I/O error. */ 707 return -1; 708 } 709 710 /* 711 * Verify format. 712 */ 713 714 /* Check ok / ko */ 715 success = memcmp(ok, "ok", 2) == 0; 716 failure = memcmp(ok, "ko", 2) == 0; 717 718 /* Check the prefix: 'ok'|'ko' & ':'|'\0' */ 719 if ((success || failure) && (ok[n] == '\0' || ok[n] == ':')) { 720 /* Format is good. */ 721 if (ok[n] == '\0') { 722 /* We're done: no extra data in response. */ 723 errno = 0; 724 return success ? 0 : -1; 725 } 726 /* Reset buffer offset, so we will start to read the remaining query 727 * data to the beginning of the supplied buffer. */ 728 n = 0; 729 } else { 730 /* Bad format. Lets move what we've read to the main buffer, and 731 * continue filling it in. */ 732 bad_format = 1; 733 n++; 734 memcpy(data, ok, n); 735 } 736 737 /* Read the remainder of reply to the supplied data buffer. */ 738 res = _android_dev_socket_read_string(ads, data + n, datasize - n); 739 if (res < 0) { 740 return res; 741 } 742 743 /* Lets see if format was bad */ 744 if (bad_format) { 745 D("Bad query reply format on channel '%s'@%d: %s.", 746 _ads_id_str(ads), _ads_port(ads), data); 747 errno = EINVAL; 748 return -1; 749 } else { 750 errno = 0; 751 return success ? n : -1; 752 } 753 } 754 755 /******************************************************************************** 756 * Query socket declarations 757 *******************************************************************************/ 758 759 /* Initializes query socket descriptor. 760 * Param: 761 * adsquery - Socket descriptor to initialize. 762 * opaque - An opaque pointer to associate with the socket. Typicaly it's the 763 * same pointer that is associated with AndroidDevice instance. 764 * ad - Android device descriptor that owns the socket. 765 * port - TCP socket port. 766 */ 767 static int _android_query_socket_init(AndroidQuerySocket* adsquery, 768 void* opaque, 769 AndroidDevice* ad, 770 int port); 771 772 /* Destroys query socket descriptor. */ 773 static void _android_query_socket_destroy(AndroidQuerySocket* adsquery); 774 775 /* Synchronously connects the query socket, and registers it with the server. 776 * Param: 777 * adsquery - Descriptor for the query socket to connect. Must have 'deadline' 778 * field properly setup. 779 * cb - Callback to invoke when socket connection is completed. Can be NULL. 780 * Return: 781 * Zero on success, or non-zero on failure. 782 */ 783 static int _android_query_socket_connect(AndroidQuerySocket* adsquery); 784 785 /* Disconnects the query socket. */ 786 static void _android_query_socket_disconnect(AndroidQuerySocket* adsquery); 787 788 /******************************************************************************** 789 * Query socket implementation 790 *******************************************************************************/ 791 792 static int 793 _android_query_socket_init(AndroidQuerySocket* adsquery, 794 void* opaque, 795 AndroidDevice* ad, 796 int port) 797 { 798 return _android_dev_socket_init(&adsquery->dev_socket, opaque, ad, port, 799 ADS_TYPE_QUERY); 800 } 801 802 static void 803 _android_query_socket_destroy(AndroidQuerySocket* adsquery) 804 { 805 _android_query_socket_disconnect(adsquery); 806 _android_dev_socket_destroy(&adsquery->dev_socket); 807 } 808 809 static int 810 _android_query_socket_connect(AndroidQuerySocket* adsquery) 811 { 812 return _android_dev_socket_connect(&adsquery->dev_socket, NULL, NULL); 813 } 814 815 static void 816 _android_query_socket_disconnect(AndroidQuerySocket* adsquery) 817 { 818 _android_dev_socket_disconnect(&adsquery->dev_socket); 819 } 820 821 /******************************************************************************** 822 * Events socket declarations 823 *******************************************************************************/ 824 825 /* Initializes event socket descriptor. 826 * Param: 827 * adsevent - Socket descriptor to initialize. 828 * opaque - An opaque pointer to associate with the socket. Typicaly it's the 829 * same pointer that is associated with AndroidDevice instance. 830 * ad - Android device descriptor that owns the socket. 831 * port - TCP socket port. 832 */ 833 static int _android_event_socket_init(AndroidEventSocket* adsevent, 834 void* opaque, 835 AndroidDevice* ad, 836 int port); 837 838 /* Destroys the event socket descriptor. */ 839 static void _android_event_socket_destroy(AndroidEventSocket* adsevent); 840 841 /* Synchronously connects event socket. 842 * Param: 843 * adsevent - Descriptor for the event socket to connect. Must have 'deadline' 844 * field properly setup. 845 * Return: 846 * Zero on success, or non-zero on failure. 847 */ 848 static int _android_event_socket_connect_sync(AndroidEventSocket* adsevent); 849 850 /* Initiates asynchronous event socket connection. 851 * Param: 852 * adsevent - Descriptor for the event socket to connect. Must have 'deadline' 853 * field properly setup. 854 * cb - Callback to invoke when socket connection is completed. Can be NULL. 855 * Return: 856 * Zero on success, or non-zero on failure. 857 */ 858 static int _android_event_socket_connect_async(AndroidEventSocket* adsevent, 859 ads_socket_connected_cb cb); 860 861 /* Disconnects the event socket. */ 862 static void _android_event_socket_disconnect(AndroidEventSocket* adsevent); 863 864 /* Initiates listening on the event socket. 865 * Param: 866 * adsevent - Descriptor for the event socket to listen on. 867 * str, strsize - Buffer where to read the string. 868 * cb - A callback to call when the event string is read. Can be NULL. 869 * Return: 870 * Zero on success, or non-zero on failure. 871 */ 872 static int _android_event_socket_listen(AndroidEventSocket* adsevent, 873 char* str, 874 int strsize, 875 event_cb cb); 876 877 /* Asynchronously sends data via event socket. 878 * Param: 879 * adsevent - Descriptor for the event socket to send data to. 880 * data, size - Buffer containing data to send. 881 * free_on_close - A boolean flag indicating whether the data buffer should be 882 * freed upon data transfer completion. 883 * cb - Callback to invoke when data transfer is completed. 884 * opaque - An opaque pointer to pass to the transfer completion callback. 885 */ 886 static int _android_event_socket_send(AndroidEventSocket* adsevent, 887 void* data, 888 int size, 889 int free_on_close, 890 async_send_cb cb, 891 void* opaque); 892 893 /* Cancels all asynchronous data transfers on the event socket. 894 * Param: 895 * adsevent - Descriptor for the event socket to cancel data transfer. 896 * reason - Reason for the cancellation. 897 */ 898 static void _android_event_socket_cancel_send(AndroidEventSocket* adsevent, 899 ATResult reason); 900 901 /* Event socket's asynchronous I/O looper callback. 902 * Param: 903 * opaque - AndroidEventSocket instance. 904 * fd - Socket's FD. 905 * events - I/O type bitsmask (read | write). 906 */ 907 static void _on_event_socket_io(void* opaque, int fd, unsigned events); 908 909 /* Callback that is invoked when asynchronous event socket connection is 910 * completed. */ 911 static void _on_event_socket_connected(AndroidEventSocket* adsevent, int failure); 912 913 /* Callback that is invoked when an event is received from the device. */ 914 static void _on_event_received(AndroidEventSocket* adsevent); 915 916 /* Gets I/O looper for asynchronous I/O on event socket. */ 917 AINLINED Looper* 918 _aes_looper(AndroidEventSocket* adsevent) 919 { 920 return adsevent->dev_socket.ad->looper; 921 } 922 923 /******************************************************************************** 924 * Events socket implementation 925 *******************************************************************************/ 926 927 static int 928 _android_event_socket_init(AndroidEventSocket* adsevent, 929 void* opaque, 930 AndroidDevice* ad, 931 int port) 932 { 933 return _android_dev_socket_init(&adsevent->dev_socket, opaque, ad, port, 934 ADS_TYPE_EVENT); 935 } 936 937 static void 938 _android_event_socket_destroy(AndroidEventSocket* adsevent) 939 { 940 _android_event_socket_disconnect(adsevent); 941 _android_dev_socket_destroy(&adsevent->dev_socket); 942 } 943 944 /* A callback invoked when file descriptor is created for the event socket. 945 * We use this callback to initialize the event socket for async I/O right after 946 * the FD has been created. 947 */ 948 static void 949 _on_event_fd_created(AndroidDevSocket* ads, void* opaque) 950 { 951 AndroidEventSocket* adsevent = (AndroidEventSocket*)opaque; 952 /* Prepare for async I/O on the event socket. */ 953 loopIo_init(adsevent->io, _aes_looper(adsevent), ads->fd, 954 _on_event_socket_io, adsevent); 955 } 956 957 static int 958 _android_event_socket_connect_sync(AndroidEventSocket* adsevent) 959 { 960 return _android_dev_socket_connect(&adsevent->dev_socket, 961 _on_event_fd_created, adsevent); 962 } 963 964 static int 965 _android_event_socket_connect_async(AndroidEventSocket* adsevent, 966 ads_socket_connected_cb cb) 967 { 968 AsyncStatus status; 969 AndroidDevSocket* ads = &adsevent->dev_socket; 970 971 /* Create asynchronous socket. */ 972 ads->fd = socket_create_inet(SOCKET_STREAM); 973 if (ads->fd < 0) { 974 D("Unable to create socket for channel '%s'@%d: %s", 975 _ads_id_str(ads), _ads_port(ads), strerror(errno)); 976 if (cb != NULL) { 977 cb(ads->opaque, ads, errno); 978 } 979 return -1; 980 } 981 socket_set_nonblock(ads->fd); 982 983 /* Prepare for async I/O on the event socket. */ 984 loopIo_init(adsevent->io, _aes_looper(adsevent), ads->fd, 985 _on_event_socket_io, adsevent); 986 987 /* Try to connect. */ 988 ads->socket_status = ADS_CONNECTING; 989 adsevent->on_connected = cb; 990 status = asyncConnector_init(adsevent->connector, &ads->address, adsevent->io); 991 switch (status) { 992 case ASYNC_COMPLETE: 993 /* We're connected to the device socket. */ 994 ads->socket_status = ADS_CONNECTED; 995 _on_event_socket_connected(adsevent, 0); 996 break; 997 case ASYNC_ERROR: 998 _on_event_socket_connected(adsevent, errno); 999 break; 1000 case ASYNC_NEED_MORE: 1001 /* Attempt to connect would block, so connection competion is 1002 * delegates to the looper's I/O routine. */ 1003 default: 1004 break; 1005 } 1006 1007 return 0; 1008 } 1009 1010 static void 1011 _android_event_socket_disconnect(AndroidEventSocket* adsevent) 1012 { 1013 AndroidDevSocket* ads = &adsevent->dev_socket; 1014 1015 if (ads->socket_status != ADS_DISCONNECTED) { 1016 /* Cancel data transfer. */ 1017 _android_event_socket_cancel_send(adsevent, ATR_DISCONNECT); 1018 1019 /* Stop all async I/O. */ 1020 loopIo_done(adsevent->io); 1021 1022 /* Disconnect common socket. */ 1023 _android_dev_socket_disconnect(ads); 1024 } 1025 } 1026 1027 static int 1028 _android_event_socket_listen(AndroidEventSocket* adsevent, 1029 char* str, 1030 int strsize, 1031 event_cb cb) 1032 { 1033 AsyncStatus status; 1034 AndroidDevSocket* ads = &adsevent->dev_socket; 1035 1036 /* Make sure that device is connected. */ 1037 if (ads->socket_status < ADS_CONNECTED) { 1038 D("Attempt to listen on a disconnected channel '%s'@%d", 1039 _ads_id_str(ads), _ads_port(ads)); 1040 errno = ECONNRESET; 1041 return -1; 1042 } 1043 1044 /* NOTE: only one reader at any given time! */ 1045 adsevent->on_event = cb; 1046 asyncLineReader_init(&adsevent->alr, str, strsize, adsevent->io); 1047 /* Default EOL for the line reader was '\n'. */ 1048 asyncLineReader_setEOL(&adsevent->alr, '\0'); 1049 status = asyncLineReader_read(&adsevent->alr); 1050 if (status == ASYNC_COMPLETE) { 1051 /* Data has been transferred immediately. Do the callback here. */ 1052 _on_event_received(adsevent); 1053 } else if (status == ASYNC_ERROR) { 1054 D("Error while listening on channel '%s'@%d: %s", 1055 _ads_id_str(ads), _ads_port(ads), strerror(errno)); 1056 /* There is one special failure here, when buffer was too small to 1057 * contain the entire string. This is not an I/O, but rather a 1058 * protocol error. So we don't report it to the I/O failure 1059 * callback. */ 1060 if (errno == ENOMEM) { 1061 _on_event_received(adsevent); 1062 } else { 1063 if (ads->ad->on_io_failure != NULL) { 1064 ads->ad->on_io_failure(ads->ad->opaque, ads->ad, errno); 1065 } 1066 } 1067 return -1; 1068 } 1069 return 0; 1070 } 1071 1072 static int 1073 _android_event_socket_send(AndroidEventSocket* adsevent, 1074 void* data, 1075 int size, 1076 int free_on_close, 1077 async_send_cb cb, 1078 void* opaque) 1079 { 1080 /* Create data transfer descriptor, and place it at the end of the list. */ 1081 AsyncSendBuffer* const desc = 1082 _async_send_buffer_create(data, size, free_on_close, cb, opaque); 1083 AsyncSendBuffer** place = &adsevent->send_pending; 1084 while (*place != NULL) { 1085 place = &((*place)->next); 1086 } 1087 *place = desc; 1088 1089 /* We're ready to transfer data. */ 1090 loopIo_wantWrite(adsevent->io); 1091 1092 return 0; 1093 } 1094 1095 static void 1096 _android_event_socket_cancel_send(AndroidEventSocket* adsevent, ATResult reason) 1097 { 1098 while (adsevent->send_pending != NULL) { 1099 AsyncSendBuffer* const to_cancel = adsevent->send_pending; 1100 adsevent->send_pending = to_cancel->next; 1101 _async_send_buffer_complete(to_cancel, reason); 1102 } 1103 loopIo_dontWantWrite(adsevent->io); 1104 } 1105 1106 static void 1107 _on_event_socket_io(void* opaque, int fd, unsigned events) 1108 { 1109 AsyncStatus status; 1110 AndroidEventSocket* adsevent = (AndroidEventSocket*)opaque; 1111 AndroidDevSocket* ads = &adsevent->dev_socket; 1112 1113 /* Lets see if we're still wating on a connection to occur. */ 1114 if (ads->socket_status == ADS_CONNECTING) { 1115 /* Complete socket connection. */ 1116 status = asyncConnector_run(adsevent->connector); 1117 if (status == ASYNC_COMPLETE) { 1118 /* We're connected to the device socket. */ 1119 ads->socket_status = ADS_CONNECTED; 1120 D("Channel '%s'@%d is connected asynchronously", 1121 _ads_id_str(ads), _ads_port(ads)); 1122 _on_event_socket_connected(adsevent, 0); 1123 } else if (status == ASYNC_ERROR) { 1124 _on_event_socket_connected(adsevent, adsevent->connector->error); 1125 } 1126 return; 1127 } 1128 1129 /* 1130 * Device is connected. Continue with the data transfer. 1131 */ 1132 1133 if ((events & LOOP_IO_READ) != 0) { 1134 /* Continue reading data. */ 1135 status = asyncLineReader_read(&adsevent->alr); 1136 if (status == ASYNC_COMPLETE) { 1137 errno = 0; 1138 _on_event_received(adsevent); 1139 } else if (status == ASYNC_ERROR) { 1140 D("I/O failure while reading from channel '%s'@%d: %s", 1141 _ads_id_str(ads), _ads_port(ads), strerror(errno)); 1142 /* There is one special failure here, when buffer was too small to 1143 * contain the entire string. This is not an I/O, but rather a 1144 * protocol error. So we don't report it to the I/O failure 1145 * callback. */ 1146 if (errno == ENOMEM) { 1147 _on_event_received(adsevent); 1148 } else { 1149 if (ads->ad->on_io_failure != NULL) { 1150 ads->ad->on_io_failure(ads->ad->opaque, ads->ad, errno); 1151 } 1152 } 1153 } 1154 } 1155 1156 if ((events & LOOP_IO_WRITE) != 0) { 1157 while (adsevent->send_pending != NULL) { 1158 AsyncSendBuffer* to_send = adsevent->send_pending; 1159 const int offset = to_send->data_size - to_send->data_remaining; 1160 const int sent = socket_send(ads->fd, to_send->data + offset, 1161 to_send->data_remaining); 1162 if (sent < 0) { 1163 if (errno == EWOULDBLOCK) { 1164 /* Try again later. */ 1165 return; 1166 } else { 1167 /* An error has occured. */ 1168 _android_event_socket_cancel_send(adsevent, ATR_IO_ERROR); 1169 if (ads->ad->on_io_failure != NULL) { 1170 ads->ad->on_io_failure(ads->ad->opaque, ads->ad, errno); 1171 } 1172 return; 1173 } 1174 } else if (sent == 0) { 1175 /* Disconnect condition. */ 1176 _android_event_socket_cancel_send(adsevent, ATR_DISCONNECT); 1177 if (ads->ad->on_io_failure != NULL) { 1178 ads->ad->on_io_failure(ads->ad->opaque, ads->ad, errno); 1179 } 1180 return; 1181 } else if (sent == to_send->data_remaining) { 1182 /* All data is sent. */ 1183 errno = 0; 1184 adsevent->send_pending = to_send->next; 1185 _async_send_buffer_complete(to_send, ATR_SUCCESS); 1186 } else { 1187 /* Chunk is sent. */ 1188 to_send->data_remaining -= sent; 1189 return; 1190 } 1191 } 1192 loopIo_dontWantWrite(adsevent->io); 1193 } 1194 } 1195 1196 static void 1197 _on_event_socket_connected(AndroidEventSocket* adsevent, int failure) 1198 { 1199 int res; 1200 AndroidDevSocket* ads = &adsevent->dev_socket; 1201 1202 if (failure) { 1203 _android_event_socket_disconnect(adsevent); 1204 if (adsevent->on_connected != NULL) { 1205 adsevent->on_connected(ads->opaque, ads, failure); 1206 } 1207 return; 1208 } 1209 1210 /* Complete event socket connection by identifying it as "event" socket with 1211 * the application. */ 1212 ads->socket_status = ADS_CONNECTED; 1213 res = _android_dev_socket_register(ads); 1214 1215 if (res) { 1216 const int save_error = errno; 1217 _android_event_socket_disconnect(adsevent); 1218 errno = save_error; 1219 } 1220 1221 /* Notify callback about connection completion. */ 1222 if (adsevent->on_connected != NULL) { 1223 if (res) { 1224 adsevent->on_connected(ads->opaque, ads, errno); 1225 } else { 1226 adsevent->on_connected(ads->opaque, ads, 0); 1227 } 1228 } 1229 } 1230 1231 static void 1232 _on_event_received(AndroidEventSocket* adsevent) 1233 { 1234 if (adsevent->on_event != NULL) { 1235 AndroidDevice* ad = adsevent->dev_socket.ad; 1236 adsevent->on_event(ad->opaque, ad, (char*)adsevent->alr.buffer, 1237 adsevent->alr.pos); 1238 } 1239 } 1240 1241 /******************************************************************************** 1242 * Android device connection 1243 *******************************************************************************/ 1244 1245 /* Callback that is invoked when event socket is connected and registered as part 1246 * of the _android_device_connect_async API. 1247 * Param: 1248 * opaque - Opaque pointer associated with AndroidDevice instance. 1249 * ads - Common socket descriptor for the event socket. 1250 * failure - If zero connection has succeeded, otherwise contains 'errno'-reason 1251 * for connection failure. 1252 */ 1253 static void 1254 _on_android_device_connected_async(void* opaque, 1255 AndroidDevSocket* ads, 1256 int failure) 1257 { 1258 int res; 1259 AndroidDevice* ad = ads->ad; 1260 1261 if (failure) { 1262 /* Depending on the failure code we will either retry, or bail out. */ 1263 switch (failure) { 1264 case EPIPE: 1265 case EAGAIN: 1266 case EINPROGRESS: 1267 case EALREADY: 1268 case EHOSTUNREACH: 1269 case EHOSTDOWN: 1270 case ECONNREFUSED: 1271 case ESHUTDOWN: 1272 case ENOTCONN: 1273 case ECONNRESET: 1274 case ECONNABORTED: 1275 case ENETRESET: 1276 case ENETUNREACH: 1277 case ENETDOWN: 1278 case EBUSY: 1279 #if !defined(_DARWIN_C_SOURCE) && !defined(_WIN32) 1280 case ERESTART: 1281 case ECOMM: 1282 case ENONET: 1283 #endif /* !_DARWIN_C_SOURCE && !_WIN32 */ 1284 /* Device is not available / reachable at the moment. 1285 * Retry connection later. */ 1286 loopTimer_startRelative(ad->timer, ADS_RETRY_CONNECTION_TIMEOUT); 1287 return; 1288 default: 1289 D("Failed to asynchronously connect channel '%s':%d %s", 1290 _ads_id_str(ads), _ads_port(ads), strerror(errno)); 1291 if (ad->on_connected != NULL) { 1292 ad->on_connected(ad->opaque, ad, failure); 1293 } 1294 break; 1295 } 1296 return; 1297 } 1298 1299 /* Event socket is connected. Connect the query socket now. Give it 5 1300 * seconds to connect. */ 1301 _ads_set_deadline(&ad->query_socket.dev_socket, 5000); 1302 res = _android_query_socket_connect(&ad->query_socket); 1303 if (res == 0) { 1304 /* Query socket is connected. */ 1305 if (ad->on_connected != NULL) { 1306 ad->on_connected(ad->opaque, ad, 0); 1307 } 1308 } else { 1309 /* If connection completion has failed - disconnect the sockets. */ 1310 _android_event_socket_disconnect(&ad->event_socket); 1311 _android_query_socket_disconnect(&ad->query_socket); 1312 1313 if (ad->on_connected != NULL) { 1314 ad->on_connected(ad->opaque, ad, errno); 1315 } 1316 } 1317 } 1318 1319 static void 1320 _on_timer(void* opaque) 1321 { 1322 /* Retry the connection. */ 1323 AndroidDevice* ad = (AndroidDevice*)opaque; 1324 android_device_connect_async(ad, ad->on_connected); 1325 } 1326 1327 /* Destroys and frees the descriptor. */ 1328 static void 1329 _android_device_free(AndroidDevice* ad) 1330 { 1331 if (ad != NULL) { 1332 _android_event_socket_destroy(&ad->event_socket); 1333 _android_query_socket_destroy(&ad->query_socket); 1334 1335 /* Delete asynchronous I/O looper. */ 1336 if (ad->looper != NULL ) { 1337 loopTimer_done(ad->timer); 1338 looper_free(ad->looper); 1339 } 1340 1341 /* Delete synchronous I/O looper. */ 1342 if (ad->io_looper != NULL) { 1343 iolooper_reset(ad->io_looper); 1344 iolooper_free(ad->io_looper); 1345 } 1346 1347 AFREE(ad); 1348 } 1349 } 1350 1351 /******************************************************************************** 1352 * Android device API 1353 *******************************************************************************/ 1354 1355 AndroidDevice* 1356 android_device_init(void* opaque, int port, io_failure_cb on_io_failure) 1357 { 1358 int res; 1359 AndroidDevice* ad; 1360 1361 ANEW0(ad); 1362 1363 ad->opaque = opaque; 1364 ad->on_io_failure = on_io_failure; 1365 1366 /* Create I/O looper for synchronous I/O on the device. */ 1367 ad->io_looper = iolooper_new(); 1368 if (ad->io_looper == NULL) { 1369 E("Unable to create synchronous I/O looper for android device."); 1370 _android_device_free(ad); 1371 return NULL; 1372 } 1373 1374 /* Create a looper for asynchronous I/O on the device. */ 1375 ad->looper = looper_newCore(); 1376 if (ad->looper != NULL) { 1377 /* Create a timer that will be used for connection retries. */ 1378 loopTimer_init(ad->timer, ad->looper, _on_timer, ad); 1379 } else { 1380 E("Unable to create asynchronous I/O looper for android device."); 1381 _android_device_free(ad); 1382 return NULL; 1383 } 1384 1385 /* Init query socket. */ 1386 res = _android_query_socket_init(&ad->query_socket, opaque, ad, port); 1387 if (res) { 1388 _android_device_free(ad); 1389 return NULL; 1390 } 1391 1392 /* Init event socket. */ 1393 res = _android_event_socket_init(&ad->event_socket, opaque, ad, port); 1394 if (res) { 1395 _android_device_free(ad); 1396 return NULL; 1397 } 1398 1399 return ad; 1400 } 1401 1402 void 1403 android_device_destroy(AndroidDevice* ad) 1404 { 1405 if (ad != NULL) { 1406 _android_device_free(ad); 1407 } 1408 } 1409 1410 int 1411 android_device_connect_sync(AndroidDevice* ad, int to) 1412 { 1413 int res; 1414 1415 /* Setup deadline for the connections. */ 1416 _ads_set_deadline(&ad->query_socket.dev_socket, to); 1417 ad->event_socket.dev_socket.deadline = ad->query_socket.dev_socket.deadline; 1418 1419 /* Connect the query socket first. */ 1420 res = _android_query_socket_connect(&ad->query_socket); 1421 if (!res) { 1422 /* Connect to the event socket next. */ 1423 res = _android_event_socket_connect_sync(&ad->event_socket); 1424 } 1425 1426 return res; 1427 } 1428 1429 int 1430 android_device_connect_async(AndroidDevice* ad, device_connected_cb on_connected) 1431 { 1432 /* No deadline for async connections. */ 1433 ad->query_socket.dev_socket.deadline = DURATION_INFINITE; 1434 ad->event_socket.dev_socket.deadline = DURATION_INFINITE; 1435 1436 /* Connect to the event socket first, and delegate query socket connection 1437 * into callback invoked when event socket is connected. NOTE: In case of 1438 * failure 'on_connected' callback has already been called from 1439 * _on_android_device_connected_async routine. */ 1440 ad->on_connected = on_connected; 1441 return _android_event_socket_connect_async(&ad->event_socket, 1442 _on_android_device_connected_async); 1443 } 1444 1445 void 1446 android_device_disconnect(AndroidDevice* ad) 1447 { 1448 _android_event_socket_disconnect(&ad->event_socket); 1449 _android_query_socket_disconnect(&ad->query_socket); 1450 } 1451 1452 int 1453 android_device_query(AndroidDevice* ad, 1454 const char* query, 1455 char* buff, 1456 size_t buffsize, 1457 int to) 1458 { 1459 int res; 1460 1461 /* Setup deadline for the query. */ 1462 _ads_set_deadline(&ad->query_socket.dev_socket, to); 1463 1464 /* Send the query. */ 1465 res = _android_dev_socket_send(&ad->query_socket.dev_socket, query, 1466 strlen(query) + 1); 1467 if (res > 0) { 1468 /* Receive the response. */ 1469 res = _android_dev_socket_read_response(&ad->query_socket.dev_socket, 1470 buff, buffsize); 1471 return (res >= 0) ? 0 : -1; 1472 } 1473 1474 return -1; 1475 } 1476 1477 int 1478 android_device_start_query(AndroidDevice* ad, const char* query, int to) 1479 { 1480 int res; 1481 1482 /* Setup deadline for the query. */ 1483 _ads_set_deadline(&ad->query_socket.dev_socket, to); 1484 1485 /* Send the query header. */ 1486 res = _android_dev_socket_send(&ad->query_socket.dev_socket, query, 1487 strlen(query) + 1); 1488 return (res > 0) ? 0 : -1; 1489 } 1490 1491 int 1492 android_device_send_query_data(AndroidDevice* ad, const void* data, int size) 1493 { 1494 return _android_dev_socket_send(&ad->query_socket.dev_socket, data, size); 1495 } 1496 1497 int 1498 android_device_complete_query(AndroidDevice* ad, char* buff, size_t buffsize) 1499 { 1500 /* Receive the response to the query. */ 1501 const int res = _android_dev_socket_read_response(&ad->query_socket.dev_socket, 1502 buff, buffsize); 1503 return (res >= 0) ? 0 : -1; 1504 } 1505 1506 int 1507 android_device_listen(AndroidDevice* ad, 1508 char* buff, 1509 int buffsize, 1510 event_cb on_event) 1511 { 1512 return _android_event_socket_listen(&ad->event_socket, buff, buffsize, 1513 on_event); 1514 } 1515 1516 int 1517 android_device_send_async(AndroidDevice* ad, 1518 void* data, 1519 int size, 1520 int free_on_close, 1521 async_send_cb cb, 1522 void* opaque) 1523 { 1524 return _android_event_socket_send(&ad->event_socket, data, size, 1525 free_on_close, cb, opaque); 1526 } 1527