aboutsummaryrefslogtreecommitdiffstats
path: root/android/sdk-controller-socket.h
blob: e58a4e21ccc5d0bf38f4ecd94a5807a201f03fa0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_SDKCONTROL_SOCKET_H_
#define ANDROID_SDKCONTROL_SOCKET_H_

#include "android/async-socket.h"
#include "android/async-utils.h"

/*
 * Contains declaration of an API that encapsulates communication protocol with
 * SdkController running on an Android device.
 *
 * SdkController is used to provide:
 *
 * - Realistic sensor emulation.
 * - Multi-touch emulation.
 * - Open for other types of emulation.
 *
 * The idea behind this type of emulation is such that there is an actual
 * Android device that is connected via USB to the host running the emulator.
 * On the device there is an SdkController service running that enables
 * communication between an Android application that gathers information required
 * by the emulator, and transmits that info to the emulator.
 *
 * SdkController service on the device, and SDKCtlSocket API implemented here
 * implement the exchange protocol between an Android application, and emulation
 * engine running inside the emulator.
 *
 * In turn, the exchange protocol is implemented on top of asynchronous socket
 * communication (abstracted in AsyncSocket protocol implemented in
 * android/async-socket.*). It means that connection, and all data transfer
 * (both, in, and out) are completely asynchronous, and results of each operation
 * are reported through callbacks.
 *
 * Essentially, this entire API implements two types of protocols:
 *
 * - Connection protocol.
 * - Data exchange protocol.
 *
 * 1. Connection protocol.
 *
 * Connecting to SdkController service on the attached device can be broken down
 * into two phases:
 * - Connecting to a TCP socket.
 * - Sending a "handshake" query to the SdkController.
 *
 * 1.1. Connecting to the socket.
 *
 * TCP socket connection with SdkController is enabled by using adb port
 * forwarding. SdkController is always listening to a local abstract socket named
 * 'android.sdk.controller', so to enable connecting to it from the host, run
 *
 *   adb forward tcp:<port> localabstract: android.sdk.controller
 *
 * After that TCP socket for the requested port can be used to connect to
 * SdkController, and connecting to it is no different than connecting to any
 * socket server. Except for one thing: adb port forwarding is implemented in
 * such a way, that socket_connect will always succeed, even if there is no
 * server listening to that port on the other side of connection. Moreover,
 * even socked_send will succeed in this case, so the only way to ensure that
 * SdkController in deed is listening is to exchange a handshake with it:
 * Fortunatelly, an attempt to read from forwarded TCP port on condition that
 * there is no listener on the oher side will fail.
 *
 * 1.2. Handshake query.
 *
 * Handshake query is a special type of query that SDKCtlSocket sends to the
 * SdkController upon successful socket connection. This query served two
 * purposes:
 * - Informs the SdkController about host endianness. This information is
 *   important, because SdkController needs it in order to format its messages
 *   with proper endianness.
 * - Ensures that SdkController is in deed listening on the other side of the
 *   connected socket.
 *
 * Connection with SdkController is considered to be successfuly established when
 * SdkController responds to the handshake query, thus, completing the connection.
 *
 * 2. Data exchange protocol.
 *
 * As it was mentioned above, all data transfer in this API is completely
 * asynchronous, and result of each data transfer is reported via callbacks.
 * This also complicates destruction of data involved in exchange, since in an
 * asynchronous environment it's hard to control the lifespan of an object, its
 * owner, and who and when is responsible to free resources allocated for the
 * transfer. To address this issue, all the descriptors that this API operates
 * with are referenced on use / released after use, and get freed when reference
 * counter for them drops to zero, indicating that there is no component that is
 * interested in that particular descriptor.
 *
 * There are three types of data in the exchange protocol:
 * - A message - the simplest type of data that doesn't require any replies.
 * - A query - A message that require a reply, and
 * - A query reply - A message that delivers query reply.
 */

/* Default TCP port to use for connection with SDK controller. */
#define SDKCTL_DEFAULT_TCP_PORT     1970

/* Declares SDK controller socket descriptor. */
typedef struct SDKCtlSocket SDKCtlSocket;

/* Declares SDK controller message descriptor. */
typedef struct SDKCtlMessage SDKCtlMessage;

/* Declares SDK controller query descriptor. */
typedef struct SDKCtlQuery SDKCtlQuery;

/* Declares SDK controller direct packet descriptor.
 * Direct packet (unlike message, or query packets) doesn't contain data buffer,
 * but rather references message, or query data allocated by the client.
 */
typedef struct SDKCtlDirectPacket SDKCtlDirectPacket;

/* Defines client's callback set to monitor SDK controller socket connection.
 *
 * SDKCtlSocket will invoke this callback when connection to TCP port is
 * established, but before handshake query is processed. The client should use
 * on_sdkctl_handshake_cb to receive notification about an operational connection
 * with SdkController.
 *
 * The main purpose of this callback for the client is to monitor connection
 * state: in addition to TCP port connection, this callback will be invoked when
 * connection with the port is lost.
 *
 * Param:
 *  client_opaque - An opaque pointer associated with the client.
 *  sdkctl - Initialized SDKCtlSocket instance.
 *  status - Socket connection status.  Can be one of these:
 *    - ASIO_STATE_SUCCEEDED : Socket is connected to the port.
 *    - ASIO_STATE_FAILED    : Connection attempt has failed, or connection with
 *                             the port is lost.
 * Return:
 *  One of the AsyncIOAction values.
 */
typedef AsyncIOAction (*on_sdkctl_socket_connection_cb)(void* client_opaque,
                                                        SDKCtlSocket* sdkctl,
                                                        AsyncIOState status);

/* Enumerates port connection statuses passed to port connection callback.
 */
typedef enum SdkCtlPortStatus {
    /* Service-side port has connected to the socket. */
    SDKCTL_PORT_DISCONNECTED,
    /* Service-side port has disconnected from the socket. */
    SDKCTL_PORT_CONNECTED,
    /* Service-side port has enabled emulation */
    SDKCTL_PORT_ENABLED,
    /* Service-side port has disabled emulation */
    SDKCTL_PORT_DISABLED,
    /* Handshake request has succeeded, and service-side port is connected. */
    SDKCTL_HANDSHAKE_CONNECTED,
    /* Handshake request has succeeded, but service-side port is not connected. */
    SDKCTL_HANDSHAKE_NO_PORT,
    /* Handshake request has failed due to port duplication. */
    SDKCTL_HANDSHAKE_DUP,
    /* Handshake request has failed on an unknown query. */
    SDKCTL_HANDSHAKE_UNKNOWN_QUERY,
    /* Handshake request has failed on an unknown response. */
    SDKCTL_HANDSHAKE_UNKNOWN_RESPONSE,
} SdkCtlPortStatus;

/* Defines client's callback set to receive port connection status.
 *
 * Port connection is different than socket connection, and indicates whether
 * or not a service-side port that provides requested emulation functionality is
 * hooked up with the connected socket. For instance, multi-touch port may be
 * inactive at the time when socket is connected. So, there is a successful
 * socket connection, but there is no service at the device end that provides
 * multi-touch functionality. So, for multi-touch example, this callback will be
 * invoked when multi-touch port at the device end becomes active, and hooks up
 * with the socket that was connected before.
 *
 * Param:
 *  client_opaque - An opaque pointer associated with the client.
 *  sdkctl - Initialized SDKCtlSocket instance.
 *  status - Port connection status.
 */
typedef void (*on_sdkctl_port_connection_cb)(void* client_opaque,
                                             SDKCtlSocket* sdkctl,
                                             SdkCtlPortStatus status);

/* Defines a message notification callback.
 * Param:
 *  client_opaque - An opaque pointer associated with the client.
 *  sdkctl - Initialized SDKCtlSocket instance.
 *  message - Descriptor for received message. Note that message descriptor will
 *      be released upon exit from this callback (thus, could be freed along
 *      with message data). If the client is interested in working with that
 *      message after the callback returns, it should reference the message
 *      descriptor in this callback.
 *  msg_type - Message type.
 *  msg_data, msg_size - Message data.
 */
typedef void (*on_sdkctl_message_cb)(void* client_opaque,
                                     SDKCtlSocket* sdkctl,
                                     SDKCtlMessage* message,
                                     int msg_type,
                                     void* msg_data,
                                     int msg_size);

/* Defines query completion callback.
 * Param:
 *  query_opaque - An opaque pointer associated with the query by the client.
 *  query - Query descriptor.  Note that query descriptor will be released upon
 *      exit from this callback (thus, could be freed along with query data). If
 *      the client is interested in working with that query after the callback
 *      returns, it should reference the query descriptor in this callback.
 *  status - Query status. Can be one of these:
 *    - ASIO_STATE_CONTINUES : Query data has been transmitted to the service,
 *                             and query is now waiting for response.
 *    - ASIO_STATE_SUCCEEDED : Query has been successfully completed.
 *    - ASIO_STATE_FAILED    : Query has failed on an I/O.
 *    - ASIO_STATE_TIMED_OUT : Deadline set for the query has expired.
 *    - ASIO_STATE_CANCELLED : Query has been cancelled due to socket
 *                             disconnection.
 * Return:
 *  One of the AsyncIOAction values.
 */
typedef AsyncIOAction (*on_sdkctl_query_cb)(void* query_opaque,
                                            SDKCtlQuery* query,
                                            AsyncIOState status);

/* Defines direct packet completion callback.
 * Param:
 *  opaque - An opaque pointer associated with the direct packet by the client.
 *  packet - Packet descriptor.  Note that packet descriptor will be released
 *      upon exit from this callback (thus, could be freed). If the client is
 *      interested in working with that packet after the callback returns, it
 *      should reference the packet descriptor in this callback.
 *  status - Packet status. Can be one of these:
 *    - ASIO_STATE_SUCCEEDED : Packet has been successfully sent.
 *    - ASIO_STATE_FAILED    : Packet has failed on an I/O.
 *    - ASIO_STATE_CANCELLED : Packet has been cancelled due to socket
 *                             disconnection.
 * Return:
 *  One of the AsyncIOAction values.
 */
typedef AsyncIOAction (*on_sdkctl_direct_cb)(void* opaque,
                                             SDKCtlDirectPacket* packet,
                                             AsyncIOState status);

/********************************************************************************
 *                        SDKCtlDirectPacket API
 ********************************************************************************/

/* Creates new SDKCtlDirectPacket descriptor.
 * Param:
 *  sdkctl - Initialized SDKCtlSocket instance to create a direct packet for.
 * Return:
 *  Referenced SDKCtlDirectPacket instance.
 */
extern SDKCtlDirectPacket* sdkctl_direct_packet_new(SDKCtlSocket* sdkctl);

/* References SDKCtlDirectPacket object.
 * Param:
 *  packet - Initialized SDKCtlDirectPacket instance.
 * Return:
 *  Number of outstanding references to the object.
 */
extern int sdkctl_direct_packet_reference(SDKCtlDirectPacket* packet);

/* Releases SDKCtlDirectPacket object.
 * Note that upon exiting from this routine the object might be destroyed, even
 * if this routine returns value other than zero.
 * Param:
 *  packet - Initialized SDKCtlDirectPacket instance.
 * Return:
 *  Number of outstanding references to the object.
 */
extern int sdkctl_direct_packet_release(SDKCtlDirectPacket* packet);

/* Sends direct packet.
 * Param:
 *  packet - Packet descriptor for the direct packet to send.
 *  data - Data to send with the packet. Must be fully initialized message, or
 *      query header.
 *  cb, cb_opaque - Callback to invoke on packet transmission events.
 */
extern void sdkctl_direct_packet_send(SDKCtlDirectPacket* packet,
                                      void* data,
                                      on_sdkctl_direct_cb cb,
                                      void* cb_opaque);

/********************************************************************************
 *                         SDKCtlMessage API
 ********************************************************************************/

/* References SDKCtlMessage object.
 * Param:
 *  msg - Initialized SDKCtlMessage instance.
 * Return:
 *  Number of outstanding references to the object.
 */
extern int sdkctl_message_reference(SDKCtlMessage* msg);

/* Releases SDKCtlMessage object.
 * Note that upon exiting from this routine the object might be destroyed, even
 * if this routine returns value other than zero.
 * Param:
 *  msg - Initialized SDKCtlMessage instance.
 * Return:
 *  Number of outstanding references to the object.
 */
extern int sdkctl_message_release(SDKCtlMessage* msg);

/* Builds and sends a message to the device.
 * Param:
 *  sdkctl - SDKCtlSocket instance for the message.
 *  msg_type - Defines message type.
 *  data - Message data. Can be NULL if there is no data associated with the
 *      message.
 *  size - Byte size of the data buffer.
 * Return:
 *  Referenced SDKCtlQuery descriptor.
 */
extern SDKCtlMessage* sdkctl_message_send(SDKCtlSocket* sdkctl,
                                          int msg_type,
                                          const void* data,
                                          uint32_t size);

/* Gets message header size */
extern int sdkctl_message_get_header_size(void);

/* Initializes message header.
 * Param:
 *  msg - Beginning of the message packet.
 *  msg_type - Message type.
 *  msg_size - Message data size.
 */
extern void sdkctl_init_message_header(void* msg, int msg_type, int msg_size);

/********************************************************************************
 *                          SDKCtlQuery API
 ********************************************************************************/

/* Creates, and partially initializes query descriptor.
 * Note that returned descriptor is referenced, and it must be eventually
 * released with a call to sdkctl_query_release.
 * Param:
 *  sdkctl - SDKCtlSocket instance for the query.
 *  query_type - Defines query type.
 *  in_data_size Size of the query's input buffer (data to be sent with this
 *      query). Note that buffer for query data will be allocated along with the
 *      query descriptor. Use sdkctl_query_get_buffer_in to get address of data
 *      buffer for this query.
 * Return:
 *  Referenced SDKCtlQuery descriptor.
 */
extern SDKCtlQuery* sdkctl_query_new(SDKCtlSocket* sdkctl,
                                     int query_type,
                                     uint32_t in_data_size);

/* Creates, and fully initializes query descriptor.
 * Note that returned descriptor is referenced, and it must be eventually
 * released with a call to sdkctl_query_release.
 * Param:
 *  sdkctl - SDKCtlSocket instance for the query.
 *  query_type - Defines query type.
 *  in_data_size Size of the query's input buffer (data to be sent with this
 *      query). Note that buffer for query data will be allocated along with the
 *      query descriptor. Use sdkctl_query_get_buffer_in to get address of data
 *      buffer for this query.
 *  in_data - Data to initialize query's input buffer with.
 *  response_buffer - Contains address of the buffer addressing preallocated
 *      response buffer on the way in, and address of the buffer containing query
 *      response on query completion. If this parameter is NULL, the API will
 *      allocate its own query response buffer, which is going to be freed after
 *      query completion.
 *  response_size - Contains size of preallocated response buffer on the way in,
 *      and size of the received response on query completion. Can be NULL.
 *  query_cb - A callback to monitor query state.
 *  query_opaque - An opaque pointer associated with the query.
 * Return:
 *  Referenced SDKCtlQuery descriptor.
 */
extern SDKCtlQuery* sdkctl_query_new_ex(SDKCtlSocket* sdkctl,
                                        int query_type,
                                        uint32_t in_data_size,
                                        const void* in_data,
                                        void** response_buffer,
                                        uint32_t* response_size,
                                        on_sdkctl_query_cb query_cb,
                                        void* query_opaque);

/* Sends query to SDK controller.
 * Param:
 *  query - Query to send. Note that this must be a fully initialized query
 *      descriptor.
 *  to - Milliseconds to allow for the query to complete. Negative value means
 *  "forever".
 */
extern void sdkctl_query_send(SDKCtlQuery* query, int to);

/* Creates, fully initializes query descriptor, and sends the query to SDK
 * controller.
 * Note that returned descriptor is referenced, and it must be eventually
 * released with a call to sdkctl_query_release.
 * Param:
 *  sdkctl - SDKCtlSocket instance for the query.
 *  query_type - Defines query type.
 *  in_data_size Size of the query's input buffer (data to be sent with this
 *      query). Note that buffer for query data will be allocated along with the
 *      query descriptor. Use sdkctl_query_get_buffer_in to get address of data
 *      buffer for this query.
 *  in_data - Data to initialize query's input buffer with.
 *  response_buffer - Contains address of the buffer addressing preallocated
 *      response buffer on the way in, and address of the buffer containing query
 *      response on query completion. If this parameter is NULL, the API will
 *      allocate its own query response buffer, which is going to be freed after
 *      query completion.
 *  response_size - Contains size of preallocated response buffer on the way in,
 *      and size of the received response on query completion. Can be NULL.
 *  query_cb - A callback to monitor query state.
 *  query_opaque - An opaque pointer associated with the query.
 *  to - Milliseconds to allow for the query to complete. Negative value means
 *  "forever".
 * Return:
 *  Referenced SDKCtlQuery descriptor for the query that has been sent.
 */
extern SDKCtlQuery* sdkctl_query_build_and_send(SDKCtlSocket* sdkctl,
                                                int query_type,
                                                uint32_t in_data_size,
                                                const void* in_data,
                                                void** response_buffer,
                                                uint32_t* response_size,
                                                on_sdkctl_query_cb query_cb,
                                                void* query_opaque,
                                                int to);

/* References SDKCtlQuery object.
 * Param:
 *  query - Initialized SDKCtlQuery instance.
 * Return:
 *  Number of outstanding references to the object.
 */
extern int sdkctl_query_reference(SDKCtlQuery* query);

/* Releases SDKCtlQuery object.
 * Note that upon exit from this routine the object might be destroyed, even if
 * this routine returns value other than zero.
 * Param:
 *  query - Initialized SDKCtlQuery instance.
 * Return:
 *  Number of outstanding references to the object.
 */
extern int sdkctl_query_release(SDKCtlQuery* query);

/* Gets address of query's input data buffer (data to be send).
 * Param:
 *  query - Query to get data buffer for.
 * Return:
 *  Address of query's input data buffer.
 */
extern void* sdkctl_query_get_buffer_in(SDKCtlQuery* query);

/* Gets address of query's output data buffer (response data).
 * Param:
 *  query - Query to get data buffer for.
 * Return:
 *  Address of query's output data buffer.
 */
extern void* sdkctl_query_get_buffer_out(SDKCtlQuery* query);

/********************************************************************************
 *                          SDKCtlSocket API
 ********************************************************************************/

/* Creates an SDK controller socket descriptor.
 * Param:
 *  reconnect_to - Timeout before trying to reconnect, or retry connection
 *      attempts after disconnection, or on connection failures.
 *  service_name - Name of the SdkController service for this socket (such as
 *      'sensors', 'milti-touch', etc.)
 *  on_socket_connection - A callback to invoke on socket connection events.
 *  on_port_connection - A callback to invoke on port connection events.
 *  on_message - A callback to invoke when a message is received from the SDK
 *      controller.
 *  opaque - An opaque pointer to associate with the socket.
 * Return:
 *  Initialized SDKCtlSocket instance on success, or NULL on failure.
 */
extern SDKCtlSocket* sdkctl_socket_new(int reconnect_to,
                                       const char* service_name,
                                       on_sdkctl_socket_connection_cb on_socket_connection,
                                       on_sdkctl_port_connection_cb on_port_connection,
                                       on_sdkctl_message_cb on_message,
                                       void* opaque);

/* Improves throughput by recycling memory allocated for buffers transferred via
 * this API.
 *
 * In many cases data exchanged between SDK controller sides are small, and,
 * although may come quite often, are coming in a sequential manner. For instance,
 * sensor service on the device may send us sensor updates every 20ms, one after
 * another. For such data traffic it makes perfect sense to recycle memory
 * allocated for the previous sensor update, rather than to free it just to
 * reallocate same buffer in 20ms. This routine sets properties of the recycler
 * for the given SDK controller connection. Recycling includes memory allocated
 * for all types of data transferred in this API: packets, and queries.
 * Param:
 *  sdkctl - Initialized SDKCtlSocket instance.
 *  data_size - Size of buffer to allocate for each data block.
 *  max_recycled_num - Maximum number of allocated buffers to keep in the
 *      recycler.
 */
extern void sdkctl_init_recycler(SDKCtlSocket* sdkctl,
                                 uint32_t data_size,
                                 int max_recycled_num);

/* References SDKCtlSocket object.
 * Param:
 *  sdkctl - Initialized SDKCtlSocket instance.
 * Return:
 *  Number of outstanding references to the object.
 */
extern int sdkctl_socket_reference(SDKCtlSocket* sdkctl);

/* Releases SDKCtlSocket object.
 * Note that upon exit from this routine the object might be destroyed, even if
 * this routine returns value other than zero.
 * Param:
 *  sdkctl - Initialized SDKCtlSocket instance.
 * Return:
 *  Number of outstanding references to the object.
 */
extern int sdkctl_socket_release(SDKCtlSocket* sdkctl);

/* Asynchronously connects to SDK controller.
 * Param:
 *  sdkctl - Initialized SDKCtlSocket instance.
 *  port - TCP port to connect the socket to.
 *  retry_to - Number of milliseconds to wait before retrying a failed
 *      connection attempt.
 */
extern void sdkctl_socket_connect(SDKCtlSocket* sdkctl, int port, int retry_to);

/* Asynchronously reconnects to SDK controller.
 * Param:
 *  sdkctl - Initialized SDKCtlSocket instance.
 *  port - TCP port to reconnect the socket to.
 *  retry_to - Number of milliseconds to wait before reconnecting. Same timeout
 *      will be used for retrying a failed connection attempt.
 */
extern void sdkctl_socket_reconnect(SDKCtlSocket* sdkctl, int port, int retry_to);

/* Disconnects from SDK controller.
 * Param:
 *  sdkctl - Initialized SDKCtlSocket instance.
 */
extern void sdkctl_socket_disconnect(SDKCtlSocket* sdkctl);

/* Checks if SDK controller socket is connected.
 * Param:
 *  sdkctl - Initialized SDKCtlSocket instance.
 * Return:
 *  Boolean: 1 if socket is connected, 0 if socket is not connected.
 */
extern int sdkctl_socket_is_connected(SDKCtlSocket* sdkctl);

/* Checks if SDK controller port is ready for emulation.
 * Param:
 *  sdkctl - Initialized SDKCtlSocket instance.
 * Return:
 *  Boolean: 1 if port is ready, 0 if port is not ready.
 */
extern int sdkctl_socket_is_port_ready(SDKCtlSocket* sdkctl);

/* Gets status of the SDK controller port for this socket.
 * Param:
 *  sdkctl - Initialized SDKCtlSocket instance.
 * Return:
 *  Status of the SDK controller port for this socket.
 */
extern SdkCtlPortStatus sdkctl_socket_get_port_status(SDKCtlSocket* sdkctl);

/* Checks if handshake was successful.
 * Param:
 *  sdkctl - Initialized SDKCtlSocket instance.
 * Return:
 *  Boolean: 1 if handshake was successful, 0 if handshake was not successful.
 */
extern int sdkctl_socket_is_handshake_ok(SDKCtlSocket* sdkctl);

#endif  /* ANDROID_SDKCONTROL_SOCKET_H_ */