• 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 /*
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*
_async_send_buffer_create(void * data,int size,int free_on_close,async_send_cb cb,void * opaque)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
_async_send_buffer_complete(AsyncSendBuffer * desc,ATResult res)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*
_ads_id_str(AndroidDevSocket * ads)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
_ads_port(AndroidDevSocket * ads)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*
_ads_io_looper(AndroidDevSocket * ads)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
_ads_set_deadline(AndroidDevSocket * ads,int to)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
_android_dev_socket_init(AndroidDevSocket * ads,void * opaque,AndroidDevice * ad,int port,ADSType type)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
_android_dev_socket_destroy(AndroidDevSocket * ads)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
_android_dev_socket_connect(AndroidDevSocket * ads,on_socked_fd_created cb,void * opaque)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
_android_dev_socket_register(AndroidDevSocket * ads)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
_android_dev_socket_disconnect(AndroidDevSocket * ads)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
_android_dev_socket_send(AndroidDevSocket * ads,const char * buff,int to_send)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
_android_dev_socket_recv(AndroidDevSocket * ads,char * buf,int bufsize)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
_android_dev_socket_read_string(AndroidDevSocket * ads,char * str,int strsize)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
_android_dev_socket_read_response(AndroidDevSocket * ads,char * data,int datasize)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
_android_query_socket_init(AndroidQuerySocket * adsquery,void * opaque,AndroidDevice * ad,int port)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
_android_query_socket_destroy(AndroidQuerySocket * adsquery)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
_android_query_socket_connect(AndroidQuerySocket * adsquery)810 _android_query_socket_connect(AndroidQuerySocket* adsquery)
811 {
812     return _android_dev_socket_connect(&adsquery->dev_socket, NULL, NULL);
813 }
814 
815 static void
_android_query_socket_disconnect(AndroidQuerySocket * adsquery)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*
_aes_looper(AndroidEventSocket * adsevent)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
_android_event_socket_init(AndroidEventSocket * adsevent,void * opaque,AndroidDevice * ad,int port)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
_android_event_socket_destroy(AndroidEventSocket * adsevent)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
_on_event_fd_created(AndroidDevSocket * ads,void * opaque)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
_android_event_socket_connect_sync(AndroidEventSocket * adsevent)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
_android_event_socket_connect_async(AndroidEventSocket * adsevent,ads_socket_connected_cb cb)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
_android_event_socket_disconnect(AndroidEventSocket * adsevent)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
_android_event_socket_listen(AndroidEventSocket * adsevent,char * str,int strsize,event_cb cb)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
_android_event_socket_send(AndroidEventSocket * adsevent,void * data,int size,int free_on_close,async_send_cb cb,void * opaque)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
_android_event_socket_cancel_send(AndroidEventSocket * adsevent,ATResult reason)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
_on_event_socket_io(void * opaque,int fd,unsigned events)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
_on_event_socket_connected(AndroidEventSocket * adsevent,int failure)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
_on_event_received(AndroidEventSocket * adsevent)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
_on_android_device_connected_async(void * opaque,AndroidDevSocket * ads,int failure)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
_on_timer(void * opaque)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
_android_device_free(AndroidDevice * ad)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*
android_device_init(void * opaque,int port,io_failure_cb on_io_failure)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
android_device_destroy(AndroidDevice * ad)1403 android_device_destroy(AndroidDevice* ad)
1404 {
1405     if (ad != NULL) {
1406         _android_device_free(ad);
1407     }
1408 }
1409 
1410 int
android_device_connect_sync(AndroidDevice * ad,int to)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
android_device_connect_async(AndroidDevice * ad,device_connected_cb on_connected)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
android_device_disconnect(AndroidDevice * ad)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
android_device_query(AndroidDevice * ad,const char * query,char * buff,size_t buffsize,int to)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
android_device_start_query(AndroidDevice * ad,const char * query,int to)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
android_device_send_query_data(AndroidDevice * ad,const void * data,int size)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
android_device_complete_query(AndroidDevice * ad,char * buff,size_t buffsize)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
android_device_listen(AndroidDevice * ad,char * buff,int buffsize,event_cb on_event)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
android_device_send_async(AndroidDevice * ad,void * data,int size,int free_on_close,async_send_cb cb,void * opaque)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