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