• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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 #ifndef ANDROID_SDKCONTROL_SOCKET_H_
18 #define ANDROID_SDKCONTROL_SOCKET_H_
19 
20 #include "android/async-socket.h"
21 #include "android/async-utils.h"
22 
23 /*
24  * Contains declaration of an API that encapsulates communication protocol with
25  * SdkController running on an Android device.
26  *
27  * SdkController is used to provide:
28  *
29  * - Realistic sensor emulation.
30  * - Multi-touch emulation.
31  * - Open for other types of emulation.
32  *
33  * The idea behind this type of emulation is such that there is an actual
34  * Android device that is connected via USB to the host running the emulator.
35  * On the device there is an SdkController service running that enables
36  * communication between an Android application that gathers information required
37  * by the emulator, and transmits that info to the emulator.
38  *
39  * SdkController service on the device, and SDKCtlSocket API implemented here
40  * implement the exchange protocol between an Android application, and emulation
41  * engine running inside the emulator.
42  *
43  * In turn, the exchange protocol is implemented on top of asynchronous socket
44  * communication (abstracted in AsyncSocket protocol implemented in
45  * android/async-socket.*). It means that connection, and all data transfer
46  * (both, in, and out) are completely asynchronous, and results of each operation
47  * are reported through callbacks.
48  *
49  * Essentially, this entire API implements two types of protocols:
50  *
51  * - Connection protocol.
52  * - Data exchange protocol.
53  *
54  * 1. Connection protocol.
55  *
56  * Connecting to SdkController service on the attached device can be broken down
57  * into two phases:
58  * - Connecting to a TCP socket.
59  * - Sending a "handshake" query to the SdkController.
60  *
61  * 1.1. Connecting to the socket.
62  *
63  * TCP socket connection with SdkController is enabled by using adb port
64  * forwarding. SdkController is always listening to a local abstract socket named
65  * 'android.sdk.controller', so to enable connecting to it from the host, run
66  *
67  *   adb forward tcp:<port> localabstract: android.sdk.controller
68  *
69  * After that TCP socket for the requested port can be used to connect to
70  * SdkController, and connecting to it is no different than connecting to any
71  * socket server. Except for one thing: adb port forwarding is implemented in
72  * such a way, that socket_connect will always succeed, even if there is no
73  * server listening to that port on the other side of connection. Moreover,
74  * even socked_send will succeed in this case, so the only way to ensure that
75  * SdkController in deed is listening is to exchange a handshake with it:
76  * Fortunatelly, an attempt to read from forwarded TCP port on condition that
77  * there is no listener on the oher side will fail.
78  *
79  * 1.2. Handshake query.
80  *
81  * Handshake query is a special type of query that SDKCtlSocket sends to the
82  * SdkController upon successful socket connection. This query served two
83  * purposes:
84  * - Informs the SdkController about host endianness. This information is
85  *   important, because SdkController needs it in order to format its messages
86  *   with proper endianness.
87  * - Ensures that SdkController is in deed listening on the other side of the
88  *   connected socket.
89  *
90  * Connection with SdkController is considered to be successfuly established when
91  * SdkController responds to the handshake query, thus, completing the connection.
92  *
93  * 2. Data exchange protocol.
94  *
95  * As it was mentioned above, all data transfer in this API is completely
96  * asynchronous, and result of each data transfer is reported via callbacks.
97  * This also complicates destruction of data involved in exchange, since in an
98  * asynchronous environment it's hard to control the lifespan of an object, its
99  * owner, and who and when is responsible to free resources allocated for the
100  * transfer. To address this issue, all the descriptors that this API operates
101  * with are referenced on use / released after use, and get freed when reference
102  * counter for them drops to zero, indicating that there is no component that is
103  * interested in that particular descriptor.
104  *
105  * There are three types of data in the exchange protocol:
106  * - A message - the simplest type of data that doesn't require any replies.
107  * - A query - A message that require a reply, and
108  * - A query reply - A message that delivers query reply.
109  */
110 
111 /* Default TCP port to use for connection with SDK controller. */
112 #define SDKCTL_DEFAULT_TCP_PORT     1970
113 
114 /* Declares SDK controller socket descriptor. */
115 typedef struct SDKCtlSocket SDKCtlSocket;
116 
117 /* Declares SDK controller message descriptor. */
118 typedef struct SDKCtlMessage SDKCtlMessage;
119 
120 /* Declares SDK controller query descriptor. */
121 typedef struct SDKCtlQuery SDKCtlQuery;
122 
123 /* Declares SDK controller direct packet descriptor.
124  * Direct packet (unlike message, or query packets) doesn't contain data buffer,
125  * but rather references message, or query data allocated by the client.
126  */
127 typedef struct SDKCtlDirectPacket SDKCtlDirectPacket;
128 
129 /* Defines client's callback set to monitor SDK controller socket connection.
130  *
131  * SDKCtlSocket will invoke this callback when connection to TCP port is
132  * established, but before handshake query is processed. The client should use
133  * on_sdkctl_handshake_cb to receive notification about an operational connection
134  * with SdkController.
135  *
136  * The main purpose of this callback for the client is to monitor connection
137  * state: in addition to TCP port connection, this callback will be invoked when
138  * connection with the port is lost.
139  *
140  * Param:
141  *  client_opaque - An opaque pointer associated with the client.
142  *  sdkctl - Initialized SDKCtlSocket instance.
143  *  status - Socket connection status.  Can be one of these:
144  *    - ASIO_STATE_SUCCEEDED : Socket is connected to the port.
145  *    - ASIO_STATE_FAILED    : Connection attempt has failed, or connection with
146  *                             the port is lost.
147  * Return:
148  *  One of the AsyncIOAction values.
149  */
150 typedef AsyncIOAction (*on_sdkctl_socket_connection_cb)(void* client_opaque,
151                                                         SDKCtlSocket* sdkctl,
152                                                         AsyncIOState status);
153 
154 /* Enumerates port connection statuses passed to port connection callback.
155  */
156 typedef enum SdkCtlPortStatus {
157     /* Service-side port has connected to the socket. */
158     SDKCTL_PORT_DISCONNECTED,
159     /* Service-side port has disconnected from the socket. */
160     SDKCTL_PORT_CONNECTED,
161     /* Service-side port has enabled emulation */
162     SDKCTL_PORT_ENABLED,
163     /* Service-side port has disabled emulation */
164     SDKCTL_PORT_DISABLED,
165     /* Handshake request has succeeded, and service-side port is connected. */
166     SDKCTL_HANDSHAKE_CONNECTED,
167     /* Handshake request has succeeded, but service-side port is not connected. */
168     SDKCTL_HANDSHAKE_NO_PORT,
169     /* Handshake request has failed due to port duplication. */
170     SDKCTL_HANDSHAKE_DUP,
171     /* Handshake request has failed on an unknown query. */
172     SDKCTL_HANDSHAKE_UNKNOWN_QUERY,
173     /* Handshake request has failed on an unknown response. */
174     SDKCTL_HANDSHAKE_UNKNOWN_RESPONSE,
175 } SdkCtlPortStatus;
176 
177 /* Defines client's callback set to receive port connection status.
178  *
179  * Port connection is different than socket connection, and indicates whether
180  * or not a service-side port that provides requested emulation functionality is
181  * hooked up with the connected socket. For instance, multi-touch port may be
182  * inactive at the time when socket is connected. So, there is a successful
183  * socket connection, but there is no service at the device end that provides
184  * multi-touch functionality. So, for multi-touch example, this callback will be
185  * invoked when multi-touch port at the device end becomes active, and hooks up
186  * with the socket that was connected before.
187  *
188  * Param:
189  *  client_opaque - An opaque pointer associated with the client.
190  *  sdkctl - Initialized SDKCtlSocket instance.
191  *  status - Port connection status.
192  */
193 typedef void (*on_sdkctl_port_connection_cb)(void* client_opaque,
194                                              SDKCtlSocket* sdkctl,
195                                              SdkCtlPortStatus status);
196 
197 /* Defines a message notification callback.
198  * Param:
199  *  client_opaque - An opaque pointer associated with the client.
200  *  sdkctl - Initialized SDKCtlSocket instance.
201  *  message - Descriptor for received message. Note that message descriptor will
202  *      be released upon exit from this callback (thus, could be freed along
203  *      with message data). If the client is interested in working with that
204  *      message after the callback returns, it should reference the message
205  *      descriptor in this callback.
206  *  msg_type - Message type.
207  *  msg_data, msg_size - Message data.
208  */
209 typedef void (*on_sdkctl_message_cb)(void* client_opaque,
210                                      SDKCtlSocket* sdkctl,
211                                      SDKCtlMessage* message,
212                                      int msg_type,
213                                      void* msg_data,
214                                      int msg_size);
215 
216 /* Defines query completion callback.
217  * Param:
218  *  query_opaque - An opaque pointer associated with the query by the client.
219  *  query - Query descriptor.  Note that query descriptor will be released upon
220  *      exit from this callback (thus, could be freed along with query data). If
221  *      the client is interested in working with that query after the callback
222  *      returns, it should reference the query descriptor in this callback.
223  *  status - Query status. Can be one of these:
224  *    - ASIO_STATE_CONTINUES : Query data has been transmitted to the service,
225  *                             and query is now waiting for response.
226  *    - ASIO_STATE_SUCCEEDED : Query has been successfully completed.
227  *    - ASIO_STATE_FAILED    : Query has failed on an I/O.
228  *    - ASIO_STATE_TIMED_OUT : Deadline set for the query has expired.
229  *    - ASIO_STATE_CANCELLED : Query has been cancelled due to socket
230  *                             disconnection.
231  * Return:
232  *  One of the AsyncIOAction values.
233  */
234 typedef AsyncIOAction (*on_sdkctl_query_cb)(void* query_opaque,
235                                             SDKCtlQuery* query,
236                                             AsyncIOState status);
237 
238 /* Defines direct packet completion callback.
239  * Param:
240  *  opaque - An opaque pointer associated with the direct packet by the client.
241  *  packet - Packet descriptor.  Note that packet descriptor will be released
242  *      upon exit from this callback (thus, could be freed). If the client is
243  *      interested in working with that packet after the callback returns, it
244  *      should reference the packet descriptor in this callback.
245  *  status - Packet status. Can be one of these:
246  *    - ASIO_STATE_SUCCEEDED : Packet has been successfully sent.
247  *    - ASIO_STATE_FAILED    : Packet has failed on an I/O.
248  *    - ASIO_STATE_CANCELLED : Packet has been cancelled due to socket
249  *                             disconnection.
250  * Return:
251  *  One of the AsyncIOAction values.
252  */
253 typedef AsyncIOAction (*on_sdkctl_direct_cb)(void* opaque,
254                                              SDKCtlDirectPacket* packet,
255                                              AsyncIOState status);
256 
257 /********************************************************************************
258  *                        SDKCtlDirectPacket API
259  ********************************************************************************/
260 
261 /* Creates new SDKCtlDirectPacket descriptor.
262  * Param:
263  *  sdkctl - Initialized SDKCtlSocket instance to create a direct packet for.
264  * Return:
265  *  Referenced SDKCtlDirectPacket instance.
266  */
267 extern SDKCtlDirectPacket* sdkctl_direct_packet_new(SDKCtlSocket* sdkctl);
268 
269 /* References SDKCtlDirectPacket object.
270  * Param:
271  *  packet - Initialized SDKCtlDirectPacket instance.
272  * Return:
273  *  Number of outstanding references to the object.
274  */
275 extern int sdkctl_direct_packet_reference(SDKCtlDirectPacket* packet);
276 
277 /* Releases SDKCtlDirectPacket object.
278  * Note that upon exiting from this routine the object might be destroyed, even
279  * if this routine returns value other than zero.
280  * Param:
281  *  packet - Initialized SDKCtlDirectPacket instance.
282  * Return:
283  *  Number of outstanding references to the object.
284  */
285 extern int sdkctl_direct_packet_release(SDKCtlDirectPacket* packet);
286 
287 /* Sends direct packet.
288  * Param:
289  *  packet - Packet descriptor for the direct packet to send.
290  *  data - Data to send with the packet. Must be fully initialized message, or
291  *      query header.
292  *  cb, cb_opaque - Callback to invoke on packet transmission events.
293  */
294 extern void sdkctl_direct_packet_send(SDKCtlDirectPacket* packet,
295                                       void* data,
296                                       on_sdkctl_direct_cb cb,
297                                       void* cb_opaque);
298 
299 /********************************************************************************
300  *                         SDKCtlMessage API
301  ********************************************************************************/
302 
303 /* References SDKCtlMessage object.
304  * Param:
305  *  msg - Initialized SDKCtlMessage instance.
306  * Return:
307  *  Number of outstanding references to the object.
308  */
309 extern int sdkctl_message_reference(SDKCtlMessage* msg);
310 
311 /* Releases SDKCtlMessage object.
312  * Note that upon exiting from this routine the object might be destroyed, even
313  * if this routine returns value other than zero.
314  * Param:
315  *  msg - Initialized SDKCtlMessage instance.
316  * Return:
317  *  Number of outstanding references to the object.
318  */
319 extern int sdkctl_message_release(SDKCtlMessage* msg);
320 
321 /* Builds and sends a message to the device.
322  * Param:
323  *  sdkctl - SDKCtlSocket instance for the message.
324  *  msg_type - Defines message type.
325  *  data - Message data. Can be NULL if there is no data associated with the
326  *      message.
327  *  size - Byte size of the data buffer.
328  * Return:
329  *  Referenced SDKCtlQuery descriptor.
330  */
331 extern SDKCtlMessage* sdkctl_message_send(SDKCtlSocket* sdkctl,
332                                           int msg_type,
333                                           const void* data,
334                                           uint32_t size);
335 
336 /* Gets message header size */
337 extern int sdkctl_message_get_header_size(void);
338 
339 /* Initializes message header.
340  * Param:
341  *  msg - Beginning of the message packet.
342  *  msg_type - Message type.
343  *  msg_size - Message data size.
344  */
345 extern void sdkctl_init_message_header(void* msg, int msg_type, int msg_size);
346 
347 /********************************************************************************
348  *                          SDKCtlQuery API
349  ********************************************************************************/
350 
351 /* Creates, and partially initializes query descriptor.
352  * Note that returned descriptor is referenced, and it must be eventually
353  * released with a call to sdkctl_query_release.
354  * Param:
355  *  sdkctl - SDKCtlSocket instance for the query.
356  *  query_type - Defines query type.
357  *  in_data_size Size of the query's input buffer (data to be sent with this
358  *      query). Note that buffer for query data will be allocated along with the
359  *      query descriptor. Use sdkctl_query_get_buffer_in to get address of data
360  *      buffer for this query.
361  * Return:
362  *  Referenced SDKCtlQuery descriptor.
363  */
364 extern SDKCtlQuery* sdkctl_query_new(SDKCtlSocket* sdkctl,
365                                      int query_type,
366                                      uint32_t in_data_size);
367 
368 /* Creates, and fully initializes query descriptor.
369  * Note that returned descriptor is referenced, and it must be eventually
370  * released with a call to sdkctl_query_release.
371  * Param:
372  *  sdkctl - SDKCtlSocket instance for the query.
373  *  query_type - Defines query type.
374  *  in_data_size Size of the query's input buffer (data to be sent with this
375  *      query). Note that buffer for query data will be allocated along with the
376  *      query descriptor. Use sdkctl_query_get_buffer_in to get address of data
377  *      buffer for this query.
378  *  in_data - Data to initialize query's input buffer with.
379  *  response_buffer - Contains address of the buffer addressing preallocated
380  *      response buffer on the way in, and address of the buffer containing query
381  *      response on query completion. If this parameter is NULL, the API will
382  *      allocate its own query response buffer, which is going to be freed after
383  *      query completion.
384  *  response_size - Contains size of preallocated response buffer on the way in,
385  *      and size of the received response on query completion. Can be NULL.
386  *  query_cb - A callback to monitor query state.
387  *  query_opaque - An opaque pointer associated with the query.
388  * Return:
389  *  Referenced SDKCtlQuery descriptor.
390  */
391 extern SDKCtlQuery* sdkctl_query_new_ex(SDKCtlSocket* sdkctl,
392                                         int query_type,
393                                         uint32_t in_data_size,
394                                         const void* in_data,
395                                         void** response_buffer,
396                                         uint32_t* response_size,
397                                         on_sdkctl_query_cb query_cb,
398                                         void* query_opaque);
399 
400 /* Sends query to SDK controller.
401  * Param:
402  *  query - Query to send. Note that this must be a fully initialized query
403  *      descriptor.
404  *  to - Milliseconds to allow for the query to complete. Negative value means
405  *  "forever".
406  */
407 extern void sdkctl_query_send(SDKCtlQuery* query, int to);
408 
409 /* Creates, fully initializes query descriptor, and sends the query to SDK
410  * controller.
411  * Note that returned descriptor is referenced, and it must be eventually
412  * released with a call to sdkctl_query_release.
413  * Param:
414  *  sdkctl - SDKCtlSocket instance for the query.
415  *  query_type - Defines query type.
416  *  in_data_size Size of the query's input buffer (data to be sent with this
417  *      query). Note that buffer for query data will be allocated along with the
418  *      query descriptor. Use sdkctl_query_get_buffer_in to get address of data
419  *      buffer for this query.
420  *  in_data - Data to initialize query's input buffer with.
421  *  response_buffer - Contains address of the buffer addressing preallocated
422  *      response buffer on the way in, and address of the buffer containing query
423  *      response on query completion. If this parameter is NULL, the API will
424  *      allocate its own query response buffer, which is going to be freed after
425  *      query completion.
426  *  response_size - Contains size of preallocated response buffer on the way in,
427  *      and size of the received response on query completion. Can be NULL.
428  *  query_cb - A callback to monitor query state.
429  *  query_opaque - An opaque pointer associated with the query.
430  *  to - Milliseconds to allow for the query to complete. Negative value means
431  *  "forever".
432  * Return:
433  *  Referenced SDKCtlQuery descriptor for the query that has been sent.
434  */
435 extern SDKCtlQuery* sdkctl_query_build_and_send(SDKCtlSocket* sdkctl,
436                                                 int query_type,
437                                                 uint32_t in_data_size,
438                                                 const void* in_data,
439                                                 void** response_buffer,
440                                                 uint32_t* response_size,
441                                                 on_sdkctl_query_cb query_cb,
442                                                 void* query_opaque,
443                                                 int to);
444 
445 /* References SDKCtlQuery object.
446  * Param:
447  *  query - Initialized SDKCtlQuery instance.
448  * Return:
449  *  Number of outstanding references to the object.
450  */
451 extern int sdkctl_query_reference(SDKCtlQuery* query);
452 
453 /* Releases SDKCtlQuery object.
454  * Note that upon exit from this routine the object might be destroyed, even if
455  * this routine returns value other than zero.
456  * Param:
457  *  query - Initialized SDKCtlQuery instance.
458  * Return:
459  *  Number of outstanding references to the object.
460  */
461 extern int sdkctl_query_release(SDKCtlQuery* query);
462 
463 /* Gets address of query's input data buffer (data to be send).
464  * Param:
465  *  query - Query to get data buffer for.
466  * Return:
467  *  Address of query's input data buffer.
468  */
469 extern void* sdkctl_query_get_buffer_in(SDKCtlQuery* query);
470 
471 /* Gets address of query's output data buffer (response data).
472  * Param:
473  *  query - Query to get data buffer for.
474  * Return:
475  *  Address of query's output data buffer.
476  */
477 extern void* sdkctl_query_get_buffer_out(SDKCtlQuery* query);
478 
479 /********************************************************************************
480  *                          SDKCtlSocket API
481  ********************************************************************************/
482 
483 /* Creates an SDK controller socket descriptor.
484  * Param:
485  *  reconnect_to - Timeout before trying to reconnect, or retry connection
486  *      attempts after disconnection, or on connection failures.
487  *  service_name - Name of the SdkController service for this socket (such as
488  *      'sensors', 'milti-touch', etc.)
489  *  on_socket_connection - A callback to invoke on socket connection events.
490  *  on_port_connection - A callback to invoke on port connection events.
491  *  on_message - A callback to invoke when a message is received from the SDK
492  *      controller.
493  *  opaque - An opaque pointer to associate with the socket.
494  * Return:
495  *  Initialized SDKCtlSocket instance on success, or NULL on failure.
496  */
497 extern SDKCtlSocket* sdkctl_socket_new(int reconnect_to,
498                                        const char* service_name,
499                                        on_sdkctl_socket_connection_cb on_socket_connection,
500                                        on_sdkctl_port_connection_cb on_port_connection,
501                                        on_sdkctl_message_cb on_message,
502                                        void* opaque);
503 
504 /* Improves throughput by recycling memory allocated for buffers transferred via
505  * this API.
506  *
507  * In many cases data exchanged between SDK controller sides are small, and,
508  * although may come quite often, are coming in a sequential manner. For instance,
509  * sensor service on the device may send us sensor updates every 20ms, one after
510  * another. For such data traffic it makes perfect sense to recycle memory
511  * allocated for the previous sensor update, rather than to free it just to
512  * reallocate same buffer in 20ms. This routine sets properties of the recycler
513  * for the given SDK controller connection. Recycling includes memory allocated
514  * for all types of data transferred in this API: packets, and queries.
515  * Param:
516  *  sdkctl - Initialized SDKCtlSocket instance.
517  *  data_size - Size of buffer to allocate for each data block.
518  *  max_recycled_num - Maximum number of allocated buffers to keep in the
519  *      recycler.
520  */
521 extern void sdkctl_init_recycler(SDKCtlSocket* sdkctl,
522                                  uint32_t data_size,
523                                  int max_recycled_num);
524 
525 /* References SDKCtlSocket object.
526  * Param:
527  *  sdkctl - Initialized SDKCtlSocket instance.
528  * Return:
529  *  Number of outstanding references to the object.
530  */
531 extern int sdkctl_socket_reference(SDKCtlSocket* sdkctl);
532 
533 /* Releases SDKCtlSocket object.
534  * Note that upon exit from this routine the object might be destroyed, even if
535  * this routine returns value other than zero.
536  * Param:
537  *  sdkctl - Initialized SDKCtlSocket instance.
538  * Return:
539  *  Number of outstanding references to the object.
540  */
541 extern int sdkctl_socket_release(SDKCtlSocket* sdkctl);
542 
543 /* Asynchronously connects to SDK controller.
544  * Param:
545  *  sdkctl - Initialized SDKCtlSocket instance.
546  *  port - TCP port to connect the socket to.
547  *  retry_to - Number of milliseconds to wait before retrying a failed
548  *      connection attempt.
549  */
550 extern void sdkctl_socket_connect(SDKCtlSocket* sdkctl, int port, int retry_to);
551 
552 /* Asynchronously reconnects to SDK controller.
553  * Param:
554  *  sdkctl - Initialized SDKCtlSocket instance.
555  *  port - TCP port to reconnect the socket to.
556  *  retry_to - Number of milliseconds to wait before reconnecting. Same timeout
557  *      will be used for retrying a failed connection attempt.
558  */
559 extern void sdkctl_socket_reconnect(SDKCtlSocket* sdkctl, int port, int retry_to);
560 
561 /* Disconnects from SDK controller.
562  * Param:
563  *  sdkctl - Initialized SDKCtlSocket instance.
564  */
565 extern void sdkctl_socket_disconnect(SDKCtlSocket* sdkctl);
566 
567 /* Checks if SDK controller socket is connected.
568  * Param:
569  *  sdkctl - Initialized SDKCtlSocket instance.
570  * Return:
571  *  Boolean: 1 if socket is connected, 0 if socket is not connected.
572  */
573 extern int sdkctl_socket_is_connected(SDKCtlSocket* sdkctl);
574 
575 /* Checks if SDK controller port is ready for emulation.
576  * Param:
577  *  sdkctl - Initialized SDKCtlSocket instance.
578  * Return:
579  *  Boolean: 1 if port is ready, 0 if port is not ready.
580  */
581 extern int sdkctl_socket_is_port_ready(SDKCtlSocket* sdkctl);
582 
583 /* Gets status of the SDK controller port for this socket.
584  * Param:
585  *  sdkctl - Initialized SDKCtlSocket instance.
586  * Return:
587  *  Status of the SDK controller port for this socket.
588  */
589 extern SdkCtlPortStatus sdkctl_socket_get_port_status(SDKCtlSocket* sdkctl);
590 
591 /* Checks if handshake was successful.
592  * Param:
593  *  sdkctl - Initialized SDKCtlSocket instance.
594  * Return:
595  *  Boolean: 1 if handshake was successful, 0 if handshake was not successful.
596  */
597 extern int sdkctl_socket_is_handshake_ok(SDKCtlSocket* sdkctl);
598 
599 #endif  /* ANDROID_SDKCONTROL_SOCKET_H_ */
600