sensors_qemu.c revision 1c8fdff64e5cb89e687925812ea0b372e0db72bc
1/*
2 * Copyright (C) 2009 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/* this implements a sensors hardware library for the Android emulator.
18 * the following code should be built as a shared library that will be
19 * placed into /system/lib/hw/sensors.goldfish.so
20 *
21 * it will be loaded by the code in hardware/libhardware/hardware.c
22 * which is itself called from com_android_server_SensorService.cpp
23 */
24
25
26/* we connect with the emulator through the "sensors" qemud service
27 */
28#define  SENSORS_SERVICE_NAME "sensors"
29
30#define LOG_TAG "QemuSensors"
31
32#include <unistd.h>
33#include <fcntl.h>
34#include <errno.h>
35#include <string.h>
36#include <cutils/log.h>
37#include <cutils/sockets.h>
38#include <hardware/sensors.h>
39
40#if 0
41#define  D(...)  LOGD(__VA_ARGS__)
42#else
43#define  D(...)  ((void)0)
44#endif
45
46#define  E(...)  LOGE(__VA_ARGS__)
47
48#include <hardware/qemud.h>
49
50/** SENSOR IDS AND NAMES
51 **/
52
53#define MAX_NUM_SENSORS 4
54
55#define SUPPORTED_SENSORS  ((1<<MAX_NUM_SENSORS)-1)
56
57#define  ID_BASE           SENSORS_HANDLE_BASE
58#define  ID_ACCELERATION   (ID_BASE+0)
59#define  ID_MAGNETIC_FIELD (ID_BASE+1)
60#define  ID_ORIENTATION    (ID_BASE+2)
61#define  ID_TEMPERATURE    (ID_BASE+3)
62
63#define  SENSORS_ACCELERATION   (1 << ID_ACCELERATION)
64#define  SENSORS_MAGNETIC_FIELD  (1 << ID_MAGNETIC_FIELD)
65#define  SENSORS_ORIENTATION     (1 << ID_ORIENTATION)
66#define  SENSORS_TEMPERATURE     (1 << ID_TEMPERATURE)
67
68#define  ID_CHECK(x)  ((unsigned)((x)-ID_BASE) < 4)
69
70#define  SENSORS_LIST  \
71    SENSOR_(ACCELERATION,"acceleration") \
72    SENSOR_(MAGNETIC_FIELD,"magnetic-field") \
73    SENSOR_(ORIENTATION,"orientation") \
74    SENSOR_(TEMPERATURE,"temperature") \
75
76static const struct {
77    const char*  name;
78    int          id; } _sensorIds[MAX_NUM_SENSORS] =
79{
80#define SENSOR_(x,y)  { y, ID_##x },
81    SENSORS_LIST
82#undef  SENSOR_
83};
84
85static const char*
86_sensorIdToName( int  id )
87{
88    int  nn;
89    for (nn = 0; nn < MAX_NUM_SENSORS; nn++)
90        if (id == _sensorIds[nn].id)
91            return _sensorIds[nn].name;
92    return "<UNKNOWN>";
93}
94
95static int
96_sensorIdFromName( const char*  name )
97{
98    int  nn;
99
100    if (name == NULL)
101        return -1;
102
103    for (nn = 0; nn < MAX_NUM_SENSORS; nn++)
104        if (!strcmp(name, _sensorIds[nn].name))
105            return _sensorIds[nn].id;
106
107    return -1;
108}
109
110/** SENSORS CONTROL DEVICE
111 **
112 ** This one is used to send commands to the sensors drivers.
113 ** We implement this by sending directly commands to the emulator
114 ** through the QEMUD channel.
115 **/
116
117typedef struct SensorControl {
118    struct sensors_control_device_t  device;
119    int                              fd;
120    uint32_t                         active_sensors;
121} SensorControl;
122
123/* this must return a file descriptor that will be used to read
124 * the sensors data (it is passed to data__data_open() below
125 */
126static int
127control__open_data_source(struct sensors_control_device_t *dev)
128{
129    SensorControl*  ctl = (void*)dev;
130
131    if (ctl->fd < 0) {
132        ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
133    }
134    D("%s: fd=%d", __FUNCTION__, ctl->fd);
135    return ctl->fd;
136}
137
138static int
139control__activate(struct sensors_control_device_t *dev,
140                  int handle,
141                  int enabled)
142{
143    SensorControl*  ctl = (void*)dev;
144    uint32_t        mask, sensors, active, new_sensors, changed;
145    char            command[128];
146    int             ret;
147
148    D("%s: handle=%s (%d) enabled=%d", __FUNCTION__,
149        _sensorIdToName(handle), handle, enabled);
150
151    if (!ID_CHECK(handle)) {
152        E("%s: bad handle ID", __FUNCTION__);
153        return -1;
154    }
155
156    mask    = (1<<handle);
157    sensors = enabled ? mask : 0;
158
159    active      = ctl->active_sensors;
160    new_sensors = (active & ~mask) | (sensors & mask);
161    changed     = active ^ new_sensors;
162
163    if (!changed)
164        return 0;
165
166    snprintf(command, sizeof command, "set:%s:%d",
167                _sensorIdToName(handle), enabled != 0);
168
169    if (ctl->fd < 0) {
170        ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
171    }
172
173    ret = qemud_channel_send(ctl->fd, command, -1);
174    if (ret < 0)
175        return -1;
176
177    ctl->active_sensors = new_sensors;
178
179    return 0;
180}
181
182static int
183control__set_delay(struct sensors_control_device_t *dev, int32_t ms)
184{
185    SensorControl*  ctl = (void*)dev;
186    char            command[128];
187
188    D("%s: dev=%p delay-ms=%d", __FUNCTION__, dev, ms);
189
190    snprintf(command, sizeof command, "set-delay:%d", ms);
191
192    return qemud_channel_send(ctl->fd, command, -1);
193}
194
195/* this function is used to force-stop the blocking read() in
196 * data__poll. In order to keep the implementation as simple
197 * as possible here, we send a command to the emulator which
198 * shall send back an appropriate data block to the system.
199 */
200static int
201control__wake(struct sensors_control_device_t *dev)
202{
203    SensorControl*  ctl = (void*)dev;
204    D("%s: dev=%p", __FUNCTION__, dev);
205    return qemud_channel_send(ctl->fd, "wake", -1);
206}
207
208
209static int
210control__close(struct hw_device_t *dev)
211{
212    SensorControl*  ctl = (void*)dev;
213    close(ctl->fd);
214    free(ctl);
215    return 0;
216}
217
218/** SENSORS DATA DEVICE
219 **
220 ** This one is used to read sensor data from the hardware.
221 ** We implement this by simply reading the data from the
222 ** emulator through the QEMUD channel.
223 **/
224
225
226typedef struct SensorData {
227    struct sensors_data_device_t  device;
228    sensors_data_t                sensors[MAX_NUM_SENSORS];
229    int                           events_fd;
230    uint32_t                      pendingSensors;
231    int64_t                       timeStart;
232    int64_t                       timeOffset;
233} SensorData;
234
235/* return the current time in nanoseconds */
236static int64_t
237data__now_ns(void)
238{
239    struct timespec  ts;
240
241    clock_gettime(CLOCK_MONOTONIC, &ts);
242
243    return (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec;
244}
245
246static int
247data__data_open(struct sensors_data_device_t *dev, int fd)
248{
249    SensorData*  data = (void*)dev;
250    int i;
251    D("%s: dev=%p fd=%d", __FUNCTION__, dev, fd);
252    memset(&data->sensors, 0, sizeof(data->sensors));
253
254    for (i=0 ; i<MAX_NUM_SENSORS ; i++) {
255        data->sensors[i].vector.status = SENSOR_STATUS_ACCURACY_HIGH;
256    }
257    data->pendingSensors = 0;
258    data->timeStart      = 0;
259    data->timeOffset     = 0;
260
261    data->events_fd = dup(fd);
262    return 0;
263}
264
265static int
266data__data_close(struct sensors_data_device_t *dev)
267{
268    SensorData*  data = (void*)dev;
269    D("%s: dev=%p", __FUNCTION__, dev);
270    if (data->events_fd > 0) {
271        close(data->events_fd);
272        data->events_fd = -1;
273    }
274    return 0;
275}
276
277static int
278pick_sensor(SensorData*      data,
279            sensors_data_t*  values)
280{
281    uint32_t mask = SUPPORTED_SENSORS;
282    while (mask) {
283        uint32_t i = 31 - __builtin_clz(mask);
284        mask &= ~(1<<i);
285        if (data->pendingSensors & (1<<i)) {
286            data->pendingSensors &= ~(1<<i);
287            *values = data->sensors[i];
288            values->sensor = (1<<i);
289            LOGD_IF(0, "%s: %d [%f, %f, %f]", __FUNCTION__,
290                    (1<<i),
291                    values->vector.x,
292                    values->vector.y,
293                    values->vector.z);
294            return i;
295        }
296    }
297    LOGE("No sensor to return!!! pendingSensors=%08x", data->pendingSensors);
298    // we may end-up in a busy loop, slow things down, just in case.
299    usleep(100000);
300    return -1;
301}
302
303static int
304data__poll(struct sensors_data_device_t *dev, sensors_data_t* values)
305{
306    SensorData*  data = (void*)dev;
307    int fd = data->events_fd;
308
309    D("%s: data=%p", __FUNCTION__, dev);
310
311    // there are pending sensors, returns them now...
312    if (data->pendingSensors) {
313        return pick_sensor(data, values);
314    }
315
316    // wait until we get a complete event for an enabled sensor
317    uint32_t new_sensors = 0;
318
319    while (1) {
320        /* read the next event */
321        char     buff[256];
322        int      len = qemud_channel_recv(data->events_fd, buff, sizeof buff-1);
323        float    params[3];
324        int64_t  event_time;
325
326        if (len < 0)
327            continue;
328
329        buff[len] = 0;
330
331        /* "wake" is sent from the emulator to exit this loop. This shall
332         * really be because another thread called "control__wake" in this
333         * process.
334         */
335        if (!strcmp((const char*)data, "wake")) {
336            return 0x7FFFFFFF;
337        }
338
339        /* "acceleration:<x>:<y>:<z>" corresponds to an acceleration event */
340        if (sscanf(buff, "acceleration:%g:%g:%g", params+0, params+1, params+2) == 3) {
341            new_sensors |= SENSORS_ACCELERATION;
342            data->sensors[ID_ACCELERATION].acceleration.x = params[0];
343            data->sensors[ID_ACCELERATION].acceleration.y = params[1];
344            data->sensors[ID_ACCELERATION].acceleration.z = params[2];
345            continue;
346        }
347
348        /* "orientation:<azimuth>:<pitch>:<roll>" is sent when orientation changes */
349        if (sscanf(buff, "orientation:%g:%g:%g", params+0, params+1, params+2) == 3) {
350            new_sensors |= SENSORS_ORIENTATION;
351            data->sensors[ID_ORIENTATION].orientation.azimuth = params[0];
352            data->sensors[ID_ORIENTATION].orientation.pitch   = params[1];
353            data->sensors[ID_ORIENTATION].orientation.roll    = params[2];
354            continue;
355        }
356
357        /* "magnetic:<x>:<y>:<z>" is sent for the params of the magnetic field */
358        if (sscanf(buff, "magnetic:%g:%g:%g", params+0, params+1, params+2) == 3) {
359            new_sensors |= SENSORS_MAGNETIC_FIELD;
360            data->sensors[ID_MAGNETIC_FIELD].magnetic.x = params[0];
361            data->sensors[ID_MAGNETIC_FIELD].magnetic.y = params[1];
362            data->sensors[ID_MAGNETIC_FIELD].magnetic.z = params[2];
363            continue;
364        }
365
366        /* "temperature:<celsius>" */
367        if (sscanf(buff, "temperature:%g", params+0) == 2) {
368            new_sensors |= SENSORS_TEMPERATURE;
369            data->sensors[ID_TEMPERATURE].temperature = params[0];
370            continue;
371        }
372
373        /* "sync:<time>" is sent after a series of sensor events.
374         * where 'time' is expressed in micro-seconds and corresponds
375         * to the VM time when the real poll occured.
376         */
377        if (sscanf(buff, "sync:%lld", &event_time) == 1) {
378            if (new_sensors) {
379                data->pendingSensors = new_sensors;
380                int64_t t = event_time * 1000LL;  /* convert to nano-seconds */
381
382                /* use the time at the first sync: as the base for later
383                 * time values */
384                if (data->timeStart == 0) {
385                    data->timeStart  = data__now_ns();
386                    data->timeOffset = data->timeStart - t;
387                }
388                t += data->timeOffset;
389
390                while (new_sensors) {
391                    uint32_t i = 31 - __builtin_clz(new_sensors);
392                    new_sensors &= ~(1<<i);
393                    data->sensors[i].time = t;
394                }
395                return pick_sensor(data, values);
396            } else {
397                D("huh ? sync without any sensor data ?");
398            }
399            continue;
400        }
401        D("huh ? unsupported command");
402    }
403}
404
405static int
406data__close(struct hw_device_t *dev)
407{
408    SensorData* data = (SensorData*)dev;
409    if (data) {
410        if (data->events_fd > 0) {
411            //LOGD("(device close) about to close fd=%d", data->events_fd);
412            close(data->events_fd);
413        }
414        free(data);
415    }
416    return 0;
417}
418
419
420/** MODULE REGISTRATION SUPPORT
421 **
422 ** This is required so that hardware/libhardware/hardware.c
423 ** will dlopen() this library appropriately.
424 **/
425
426/*
427 * the following is the list of all supported sensors.
428 * this table is used to build sSensorList declared below
429 * according to which hardware sensors are reported as
430 * available from the emulator (see get_sensors_list below)
431 *
432 * note: numerical values for maxRange/resolution/power were
433 *       taken from the reference AK8976A implementation
434 */
435static const struct sensor_t sSensorListInit[] = {
436        { .name       = "Goldfish 3-axis Accelerometer",
437          .vendor     = "The Android Open Source Project",
438          .version    = 1,
439          .handle     = ID_ACCELERATION,
440          .type       = SENSOR_TYPE_ACCELEROMETER,
441          .maxRange   = 2.8f,
442          .resolution = 1.0f/4032.0f,
443          .power      = 3.0f,
444          .reserved   = {}
445        },
446
447        { .name       = "Goldfish 3-axis Magnetic field sensor",
448          .vendor     = "The Android Open Source Project",
449          .version    = 1,
450          .handle     = ID_MAGNETIC_FIELD,
451          .type       = SENSOR_TYPE_MAGNETIC_FIELD,
452          .maxRange   = 2000.0f,
453          .resolution = 1.0f,
454          .power      = 6.7f,
455          .reserved   = {}
456        },
457
458        { .name       = "Goldfish Orientation sensor",
459          .vendor     = "The Android Open Source Project",
460          .version    = 1,
461          .handle     = ID_ORIENTATION,
462          .type       = SENSOR_TYPE_ORIENTATION,
463          .maxRange   = 360.0f,
464          .resolution = 1.0f,
465          .power      = 9.7f,
466          .reserved   = {}
467        },
468
469        { .name       = "Goldfish Temperature sensor",
470          .vendor     = "The Android Open Source Project",
471          .version    = 1,
472          .handle     = ID_TEMPERATURE,
473          .type       = SENSOR_TYPE_TEMPERATURE,
474          .maxRange   = 80.0f,
475          .resolution = 1.0f,
476          .power      = 0.0f,
477          .reserved   = {}
478        },
479};
480
481static struct sensor_t  sSensorList[MAX_NUM_SENSORS];
482
483static uint32_t sensors__get_sensors_list(struct sensors_module_t* module,
484        struct sensor_t const** list)
485{
486    int  fd = qemud_channel_open(SENSORS_SERVICE_NAME);
487    char buffer[12];
488    int  mask, nn, count;
489
490    int  ret;
491    if (fd < 0) {
492        E("%s: no qemud connection", __FUNCTION__);
493        return 0;
494    }
495    ret = qemud_channel_send(fd, "list-sensors", -1);
496    if (ret < 0) {
497        E("%s: could not query sensor list: %s", __FUNCTION__,
498          strerror(errno));
499        close(fd);
500        return 0;
501    }
502    ret = qemud_channel_recv(fd, buffer, sizeof buffer-1);
503    if (ret < 0) {
504        E("%s: could not receive sensor list: %s", __FUNCTION__,
505          strerror(errno));
506        close(fd);
507        return 0;
508    }
509    buffer[ret] = 0;
510    close(fd);
511
512    /* the result is a integer used as a mask for available sensors */
513    mask  = atoi(buffer);
514    count = 0;
515    for (nn = 0; nn < MAX_NUM_SENSORS; nn++) {
516        if (((1 << nn) & mask) == 0)
517            continue;
518
519        sSensorList[count++] = sSensorListInit[nn];
520    }
521    D("%s: returned %d sensors (mask=%d)", __FUNCTION__, count, mask);
522    *list = sSensorList;
523    return count;
524}
525
526
527static int
528open_sensors(const struct hw_module_t* module,
529             const char*               name,
530             struct hw_device_t*      *device)
531{
532    int  status = -EINVAL;
533
534    D("%s: name=%s", __FUNCTION__, name);
535
536    if (!strcmp(name, SENSORS_HARDWARE_CONTROL))
537    {
538        SensorControl *dev = malloc(sizeof(*dev));
539
540        memset(dev, 0, sizeof(*dev));
541
542        dev->device.common.tag       = HARDWARE_DEVICE_TAG;
543        dev->device.common.version   = 0;
544        dev->device.common.module    = (struct hw_module_t*) module;
545        dev->device.common.close     = control__close;
546        dev->device.open_data_source = control__open_data_source;
547        dev->device.activate         = control__activate;
548        dev->device.set_delay        = control__set_delay;
549        dev->device.wake             = control__wake;
550        dev->fd                      = -1;
551
552        *device = &dev->device.common;
553        status  = 0;
554    }
555    else if (!strcmp(name, SENSORS_HARDWARE_DATA)) {
556        SensorData *dev = malloc(sizeof(*dev));
557
558        memset(dev, 0, sizeof(*dev));
559
560        dev->device.common.tag     = HARDWARE_DEVICE_TAG;
561        dev->device.common.version = 0;
562        dev->device.common.module  = (struct hw_module_t*) module;
563        dev->device.common.close   = data__close;
564        dev->device.data_open      = data__data_open;
565        dev->device.data_close     = data__data_close;
566        dev->device.poll           = data__poll;
567        dev->events_fd             = -1;
568
569        *device = &dev->device.common;
570        status  = 0;
571    }
572    return status;
573}
574
575
576static struct hw_module_methods_t sensors_module_methods = {
577    .open = open_sensors
578};
579
580const struct sensors_module_t HAL_MODULE_INFO_SYM = {
581    .common = {
582        .tag = HARDWARE_MODULE_TAG,
583        .version_major = 1,
584        .version_minor = 0,
585        .id = SENSORS_HARDWARE_MODULE_ID,
586        .name = "Goldfish SENSORS Module",
587        .author = "The Android Open Source Project",
588        .methods = &sensors_module_methods,
589    },
590    .get_sensors_list = sensors__get_sensors_list
591};
592