Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 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" |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 21 | #include "android/async-utils.h" |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 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: |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 106 | * - A message - the simplest type of data that doesn't require any replies. |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 107 | * - A query - A message that require a reply, and |
| 108 | * - A query reply - A message that delivers query reply. |
| 109 | */ |
| 110 | |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 111 | /* Default TCP port to use for connection with SDK controller. */ |
| 112 | #define SDKCTL_DEFAULT_TCP_PORT 1970 |
| 113 | |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 114 | /* Declares SDK controller socket descriptor. */ |
| 115 | typedef struct SDKCtlSocket SDKCtlSocket; |
| 116 | |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 117 | /* Declares SDK controller message descriptor. */ |
| 118 | typedef struct SDKCtlMessage SDKCtlMessage; |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 119 | |
| 120 | /* Declares SDK controller query descriptor. */ |
| 121 | typedef struct SDKCtlQuery SDKCtlQuery; |
| 122 | |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 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 | |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 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 | */ |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 150 | typedef AsyncIOAction (*on_sdkctl_socket_connection_cb)(void* client_opaque, |
| 151 | SDKCtlSocket* sdkctl, |
| 152 | AsyncIOState status); |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 153 | |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 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. |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 178 | * |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 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. |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 187 | * |
| 188 | * Param: |
| 189 | * client_opaque - An opaque pointer associated with the client. |
| 190 | * sdkctl - Initialized SDKCtlSocket instance. |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 191 | * status - Port connection status. |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 192 | */ |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 193 | typedef void (*on_sdkctl_port_connection_cb)(void* client_opaque, |
| 194 | SDKCtlSocket* sdkctl, |
| 195 | SdkCtlPortStatus status); |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 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, |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 211 | SDKCtlMessage* message, |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 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 | |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 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 | |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 257 | /******************************************************************************** |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 258 | * SDKCtlDirectPacket API |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 259 | ********************************************************************************/ |
| 260 | |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 261 | /* Creates new SDKCtlDirectPacket descriptor. |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 262 | * Param: |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 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. |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 272 | * Return: |
| 273 | * Number of outstanding references to the object. |
| 274 | */ |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 275 | extern int sdkctl_direct_packet_reference(SDKCtlDirectPacket* packet); |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 276 | |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 277 | /* Releases SDKCtlDirectPacket object. |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 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: |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 281 | * packet - Initialized SDKCtlDirectPacket instance. |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 282 | * Return: |
| 283 | * Number of outstanding references to the object. |
| 284 | */ |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 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); |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 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 | |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 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 | |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 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.) |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 489 | * on_socket_connection - A callback to invoke on socket connection events. |
| 490 | * on_port_connection - A callback to invoke on port connection events. |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 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, |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 499 | on_sdkctl_socket_connection_cb on_socket_connection, |
| 500 | on_sdkctl_port_connection_cb on_port_connection, |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 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 | |
Vladimir Chtchetkine | 7136b05 | 2012-04-10 13:39:24 -0700 | [diff] [blame] | 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 | |
Vladimir Chtchetkine | c8aa2c5 | 2012-04-05 16:22:55 -0700 | [diff] [blame] | 599 | #endif /* ANDROID_SDKCONTROL_SOCKET_H_ */ |