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 #include "android/sdk-controller-socket.h"
18 #include "android/sensors-port.h"
19 #include "android/hw-sensors.h"
20 #include "android/utils/debug.h"
21
22 #define E(...) derror(__VA_ARGS__)
23 #define W(...) dwarning(__VA_ARGS__)
24 #define D(...) VERBOSE_PRINT(sensors_port,__VA_ARGS__)
25 #define D_ACTIVE VERBOSE_CHECK(sensors_port)
26
27 #define TRACE_ON 1
28
29 #if TRACE_ON
30 #define T(...) VERBOSE_PRINT(sensors_port,__VA_ARGS__)
31 #else
32 #define T(...)
33 #endif
34
35 /* Timeout (millisec) to use when communicating with SDK controller. */
36 #define SDKCTL_SENSORS_TIMEOUT 3000
37
38 /*
39 * Queries sent to sensors port of the SDK controller.
40 */
41
42 /* Queries the port for list of available sensors. */
43 #define SDKCTL_SENSORS_QUERY_LIST 1
44
45 /*
46 * Messages sent between the emuator, and sensors port of the SDK controller.
47 */
48
49 /* Starts sensor emulation. */
50 #define SDKCTL_SENSORS_START 1
51 /* Stops sensor emulation. */
52 #define SENSOR_SENSORS_STOP 2
53 /* Enables emulation for a sensor. */
54 #define SDKCTL_SENSORS_ENABLE 3
55 /* Disables emulation for a sensor. */
56 #define SDKCTL_SENSORS_DISABLE 4
57 /* This message delivers sensor values. */
58 #define SDKCTL_SENSORS_SENSOR_EVENT 5
59
60
61 /* Describes a sensor on the device.
62 * When SDK controller sensors port replies to a "list" query, it replies with
63 * a flat buffer containing entries of this type following each other. End of
64 * each entry is a zero-terminator for its 'sensor_name' field. The end of the
65 * entire list is marked with an entry, containing -1 at its 'sensor_id' field.
66 */
67 typedef struct SensorEntry {
68 /* Identifies sensor on the device. Value -1 indicates list terminator,
69 * rather than a valid sensor descriptor. */
70 int sensor_id;
71 /* Beginning of zero-terminated sensor name. */
72 char sensor_name[1];
73 } SensorEntry;
74
75 /* Describes a sensor in the array of emulated sensors. */
76 typedef struct SensorDescriptor {
77 /* Identifies sensor on the device. */
78 int sensor_id;
79 /* Identifies sensor in emulator. */
80 int emulator_id;
81 /* Sensor name. */
82 char* sensor_name;
83 } SensorDescriptor;
84
85 /* Sensor event message descriptor.
86 * Entries of this type are sent along with SDKCTL_SENSORS_SENSOR_EVENT message
87 */
88 typedef struct SensorEvent {
89 /* Identifies a device sensor for which values have been delivered. */
90 int sensor_id;
91 /* Sensor values. */
92 float fvalues[3];
93 } SensorEvent;
94
95 /* Sensors port descriptor. */
96 struct AndroidSensorsPort {
97 /* Caller identifier. */
98 void* opaque;
99 /* Communication socket. */
100 SDKCtlSocket* sdkctl;
101 /* Lists sensors available for emulation. */
102 SensorDescriptor** sensors;
103 /* Number of sensors in 'sensors' list. */
104 int sensors_count;
105 };
106
107 /********************************************************************************
108 * Sensors port internals
109 *******************************************************************************/
110
111 /* Checks if sensor descriptor is the terminator.
112 * Return:
113 * Boolean, 1 if it is a terminator, 0 if it is not.
114 */
115 static int
_sensor_entry_is_terminator(const SensorEntry * entry)116 _sensor_entry_is_terminator(const SensorEntry* entry)
117 {
118 return entry == NULL || entry->sensor_id == -1;
119 }
120
121 /* Gets next sensor descriptor.
122 * Return:
123 * Next sensor desciptor, or NULL if there are no more descriptors in the list.
124 */
125 static const SensorEntry*
_sensor_entry_next(const SensorEntry * entry)126 _sensor_entry_next(const SensorEntry* entry)
127 {
128 if (!_sensor_entry_is_terminator(entry)) {
129 /* Next descriptor begins right after zero-terminator for the sensor_name
130 * field of this descriptor. */
131 entry = (const SensorEntry*)(entry->sensor_name + strlen(entry->sensor_name) + 1);
132 if (!_sensor_entry_is_terminator(entry)) {
133 return entry;
134 }
135 }
136 return NULL;
137 }
138
139 /* Gets number of entries in the list. */
140 static int
_sensor_entry_list_size(const SensorEntry * entry)141 _sensor_entry_list_size(const SensorEntry* entry) {
142 int ret = 0;
143 while (!_sensor_entry_is_terminator(entry)) {
144 ret++;
145 entry = _sensor_entry_next(entry);
146 }
147 return ret;
148 }
149
150 /* Discards sensors saved in AndroidSensorsPort's array. */
151 static void
_sensors_port_discard_sensors(AndroidSensorsPort * asp)152 _sensors_port_discard_sensors(AndroidSensorsPort* asp)
153 {
154 if (asp->sensors != NULL) {
155 int n;
156 for (n = 0; n < asp->sensors_count; n++) {
157 if (asp->sensors[n] != NULL) {
158 free(asp->sensors[n]->sensor_name);
159 AFREE(asp->sensors[n]);
160 }
161 }
162 free(asp->sensors);
163 asp->sensors = NULL;
164 }
165 asp->sensors_count = 0;
166 }
167
168
169 /* Destroys and frees the descriptor. */
170 static void
_sensors_port_free(AndroidSensorsPort * asp)171 _sensors_port_free(AndroidSensorsPort* asp)
172 {
173 if (asp != NULL) {
174 _sensors_port_discard_sensors(asp);
175 if (asp->sdkctl != NULL) {
176 sdkctl_socket_release(asp->sdkctl);
177 }
178 AFREE(asp);
179 }
180 }
181
182 /* Parses flat sensor list, and saves its entries into 'sensors' array filed of
183 * the AndroidSensorsPort descriptor. */
184 static void
_sensors_port_save_sensors(AndroidSensorsPort * asp,const SensorEntry * list)185 _sensors_port_save_sensors(AndroidSensorsPort* asp, const SensorEntry* list)
186 {
187 const int count = _sensor_entry_list_size(list);
188 if (count != 0) {
189 int n;
190 /* Allocate array for sensor descriptors. */
191 asp->sensors = malloc(sizeof(SensorDescriptor*) * count);
192
193 /* Iterate through the flat sensor list, filling up array of emulated
194 * sensors. */
195 const SensorEntry* entry = _sensor_entry_is_terminator(list) ? NULL : list;
196 for (n = 0; n < count && entry != NULL; n++) {
197 /* Get emulator-side ID for the sensor. < 0 value indicates that
198 * sensor is not supported by the emulator. */
199 const int emulator_id =
200 android_sensors_get_id_from_name((char*)entry->sensor_name);
201 if (emulator_id >= 0) {
202 SensorDescriptor* desc;
203 ANEW0(desc);
204 desc->emulator_id = emulator_id;
205 desc->sensor_id = entry->sensor_id;
206 desc->sensor_name = ASTRDUP(entry->sensor_name);
207
208 asp->sensors[asp->sensors_count++] = desc;
209 D("Sensors: Emulated sensor '%s': Device id = %d, Emulator id = %d",
210 desc->sensor_name, desc->sensor_id, desc->emulator_id);
211 } else {
212 D("Sensors: Sensor '%s' is not support by emulator",
213 entry->sensor_name);
214 }
215 entry = _sensor_entry_next(entry);
216 }
217 D("Sensors: Emulating %d sensors", asp->sensors_count);
218 }
219 }
220
221 /* Finds sensor descriptor for an SDK controller-side ID. */
222 static const SensorDescriptor*
_sensor_from_sdkctl_id(AndroidSensorsPort * asp,int id)223 _sensor_from_sdkctl_id(AndroidSensorsPort* asp, int id)
224 {
225 int n;
226 for (n = 0; n < asp->sensors_count; n++) {
227 if (asp->sensors[n]->sensor_id == id) {
228 return asp->sensors[n];
229 }
230 }
231 return NULL;
232 }
233
234 /* Initiates sensor emulation.
235 * Param:
236 * asp - Android sensors port instance returned from sensors_port_create.
237 * Return:
238 * Zero on success, failure otherwise.
239 */
240 static void
_sensors_port_start(AndroidSensorsPort * asp)241 _sensors_port_start(AndroidSensorsPort* asp)
242 {
243 int n;
244
245 if (!sdkctl_socket_is_port_ready(asp->sdkctl)) {
246 /* SDK controller side is not ready for emulation. Retreat... */
247 D("Sensors: SDK controller side is not ready for emulation.");
248 return;
249 }
250
251 /* Disable all sensors, and reenable only those that are emulated by
252 * hardware. */
253 sensors_port_disable_sensor(asp, "all");
254
255 /* Walk throuh the list of enabled sensors enabling them on the device. */
256 for (n = 0; n < asp->sensors_count; n++) {
257 if (android_sensors_get_sensor_status(asp->sensors[n]->emulator_id) == 1) {
258 /* Reenable emulation for this sensor. */
259 sensors_port_enable_sensor(asp, asp->sensors[n]->sensor_name);
260 D("Sensors: Sensor '%s' is enabled on SDK controller.",
261 asp->sensors[n]->sensor_name);
262 }
263 }
264
265 /* Start the emulation. */
266 SDKCtlMessage* const msg =
267 sdkctl_message_send(asp->sdkctl, SDKCTL_SENSORS_START, NULL, 0);
268 sdkctl_message_release(msg);
269
270 D("Sensors: Emulation has been started.");
271 }
272
273 /********************************************************************************
274 * Sensors port callbacks
275 *******************************************************************************/
276
277 /* Completion for the "list" query. */
278 static AsyncIOAction
_on_sensor_list_query(void * query_opaque,SDKCtlQuery * query,AsyncIOState status)279 _on_sensor_list_query(void* query_opaque,
280 SDKCtlQuery* query,
281 AsyncIOState status)
282 {
283 AndroidSensorsPort* const asp = (AndroidSensorsPort*)(query_opaque);
284 if (status != ASIO_STATE_SUCCEEDED) {
285 /* We don't really care about failures at this point. They will
286 * eventually surface up in another place. */
287 return ASIO_ACTION_DONE;
288 }
289
290 /* Parse query response which is a flat list of SensorEntry entries. */
291 const SensorEntry* const list =
292 (const SensorEntry*)sdkctl_query_get_buffer_out(query);
293 D("Sensors: Sensor list received with %d sensors.",
294 _sensor_entry_list_size(list));
295 _sensors_port_save_sensors(asp, list);
296
297 /* At this point we are ready to statr sensor emulation. */
298 _sensors_port_start(asp);
299
300 return ASIO_ACTION_DONE;
301 }
302
303 /* A callback that is invoked on sensor events.
304 * Param:
305 * asp - AndroidSensorsPort instance.
306 * event - Sensor event.
307 */
308 static void
_on_sensor_event(AndroidSensorsPort * asp,const SensorEvent * event)309 _on_sensor_event(AndroidSensorsPort* asp, const SensorEvent* event)
310 {
311 /* Find corresponding server descriptor. */
312 const SensorDescriptor* const desc =
313 _sensor_from_sdkctl_id(asp, event->sensor_id);
314 if (desc != NULL) {
315 T("Sensors: %s -> %f, %f, %f", desc->sensor_name,
316 event->fvalues[0], event->fvalues[1],
317 event->fvalues[2]);
318 /* Fire up sensor change in the guest. */
319 android_sensors_set(desc->emulator_id, event->fvalues[0],
320 event->fvalues[1], event->fvalues[2]);
321 } else {
322 W("Sensors: No descriptor for sensor %d", event->sensor_id);
323 }
324 }
325
326 /* A callback that is invoked on SDK controller socket connection events. */
327 static AsyncIOAction
_on_sensors_socket_connection(void * client_opaque,SDKCtlSocket * sdkctl,AsyncIOState status)328 _on_sensors_socket_connection(void* client_opaque,
329 SDKCtlSocket* sdkctl,
330 AsyncIOState status)
331 {
332 AndroidSensorsPort* const asp = (AndroidSensorsPort*)client_opaque;
333 if (status == ASIO_STATE_FAILED) {
334 /* Disconnection could mean that user is swapping devices. New device may
335 * have different set of sensors, so we need to re-query sensor list on
336 * reconnection. */
337 _sensors_port_discard_sensors(asp);
338
339 /* Reconnect (after timeout delay) on failures */
340 if (sdkctl_socket_is_handshake_ok(sdkctl)) {
341 sdkctl_socket_reconnect(sdkctl, SDKCTL_DEFAULT_TCP_PORT,
342 SDKCTL_SENSORS_TIMEOUT);
343 }
344 }
345 return ASIO_ACTION_DONE;
346 }
347
348 /* A callback that is invoked on SDK controller port connection events. */
349 static void
_on_sensors_port_connection(void * client_opaque,SDKCtlSocket * sdkctl,SdkCtlPortStatus status)350 _on_sensors_port_connection(void* client_opaque,
351 SDKCtlSocket* sdkctl,
352 SdkCtlPortStatus status)
353 {
354 AndroidSensorsPort* const asp = (AndroidSensorsPort*)client_opaque;
355 switch (status) {
356 case SDKCTL_PORT_CONNECTED: {
357 D("Sensors: SDK Controller is connected.");
358 /* Query list of available sensors. */
359 SDKCtlQuery* const query =
360 sdkctl_query_build_and_send(asp->sdkctl, SDKCTL_SENSORS_QUERY_LIST,
361 0, NULL, NULL, NULL,
362 _on_sensor_list_query, asp,
363 SDKCTL_SENSORS_TIMEOUT);
364 sdkctl_query_release(query);
365 break;
366 }
367
368 case SDKCTL_PORT_DISCONNECTED:
369 _sensors_port_discard_sensors(asp);
370 D("Sensors: SDK Controller is disconnected.");
371 break;
372
373 case SDKCTL_PORT_ENABLED:
374 _sensors_port_start(asp);
375 D("Sensors: SDK Controller is enabled.");
376 break;
377
378 case SDKCTL_PORT_DISABLED:
379 D("Sensors: SDK Controller is disabled.");
380 break;
381
382 case SDKCTL_HANDSHAKE_CONNECTED:
383 D("Sensors: SDK Controller has succeeded handshake, and port is connected.");
384 break;
385
386 case SDKCTL_HANDSHAKE_NO_PORT:
387 D("Sensors: SDK Controller has succeeded handshake, and port is not connected.");
388 break;
389
390 case SDKCTL_HANDSHAKE_DUP:
391 E("Sensors: SDK Controller has failed the handshake due to port duplication.");
392 sdkctl_socket_disconnect(sdkctl);
393 break;
394
395 case SDKCTL_HANDSHAKE_UNKNOWN_QUERY:
396 E("Sensors: SDK Controller has failed the handshake due to unknown query.");
397 sdkctl_socket_disconnect(sdkctl);
398 break;
399
400 case SDKCTL_HANDSHAKE_UNKNOWN_RESPONSE:
401 default:
402 E("Sensors: Handshake has failed due to unknown reasons.");
403 sdkctl_socket_disconnect(sdkctl);
404 break;
405 }
406 }
407
408 /* A callback that is invoked when a message is received from SDK controller. */
409 static void
_on_sensors_message(void * client_opaque,SDKCtlSocket * sdkctl,SDKCtlMessage * message,int msg_type,void * msg_data,int msg_size)410 _on_sensors_message(void* client_opaque,
411 SDKCtlSocket* sdkctl,
412 SDKCtlMessage* message,
413 int msg_type,
414 void* msg_data,
415 int msg_size)
416 {
417 AndroidSensorsPort* const asp = (AndroidSensorsPort*)client_opaque;
418 switch (msg_type) {
419 case SDKCTL_SENSORS_SENSOR_EVENT:
420 _on_sensor_event(asp, (const SensorEvent*)msg_data);
421 break;
422
423 default:
424 E("Sensors: Unknown message type %d", msg_type);
425 break;
426 }
427 }
428
429 /********************************************************************************
430 * Sensors port API
431 *******************************************************************************/
432
433 AndroidSensorsPort*
sensors_port_create(void * opaque)434 sensors_port_create(void* opaque)
435 {
436 AndroidSensorsPort* asp;
437
438 ANEW0(asp);
439 asp->opaque = opaque;
440 asp->sensors = NULL;
441 asp->sensors_count = 0;
442 asp->sdkctl = sdkctl_socket_new(SDKCTL_SENSORS_TIMEOUT, "sensors",
443 _on_sensors_socket_connection,
444 _on_sensors_port_connection,
445 _on_sensors_message, asp);
446 sdkctl_init_recycler(asp->sdkctl, 76, 8);
447 sdkctl_socket_connect(asp->sdkctl, SDKCTL_DEFAULT_TCP_PORT,
448 SDKCTL_SENSORS_TIMEOUT);
449 return asp;
450 }
451
452 void
sensors_port_destroy(AndroidSensorsPort * asp)453 sensors_port_destroy(AndroidSensorsPort* asp)
454 {
455 if (asp->sdkctl != NULL) {
456 sdkctl_socket_disconnect(asp->sdkctl);
457 }
458 _sensors_port_free(asp);
459 }
460
461 int
sensors_port_enable_sensor(AndroidSensorsPort * asp,const char * name)462 sensors_port_enable_sensor(AndroidSensorsPort* asp, const char* name)
463 {
464 if (asp->sdkctl != NULL && sdkctl_socket_is_port_ready(asp->sdkctl)) {
465 SDKCtlMessage* const msg = sdkctl_message_send(asp->sdkctl,
466 SDKCTL_SENSORS_ENABLE,
467 name, strlen(name));
468 sdkctl_message_release(msg);
469 return 0;
470 } else {
471 return -1;
472 }
473 }
474
475 int
sensors_port_disable_sensor(AndroidSensorsPort * asp,const char * name)476 sensors_port_disable_sensor(AndroidSensorsPort* asp, const char* name)
477 {
478 if (asp->sdkctl != NULL && sdkctl_socket_is_port_ready(asp->sdkctl)) {
479 SDKCtlMessage* const msg = sdkctl_message_send(asp->sdkctl,
480 SDKCTL_SENSORS_DISABLE,
481 name, strlen(name));
482 sdkctl_message_release(msg);
483 return 0;
484 } else {
485 return -1;
486 }
487 }
488