2 * Copyright (C) 2014 Intel Corporation.
7 #include <sys/socket.h>
13 #include <hardware/sensors.h>
14 #include <utils/Log.h>
18 fprintf(stderr, "sens start [sensors.gmin.so]\n");
19 fprintf(stderr, "sens [activate | deactivate] sensor_id\n");
20 fprintf(stderr, "sens set_delay sensor_id delay\n");
21 fprintf(stderr, "sens poll\n");
25 static struct sensors_module_t *hmi;
27 static const char* types[] = {
38 "linear acceleration",
41 "ambient temperature",
42 "uncalibrated magnetometer",
43 "game rotation vector",
44 "uncalibrated gyrocope",
48 "geomagnetic rotation vector",
51 static const char *type_str(int type)
53 int type_count = sizeof(types)/sizeof(char *);
55 if (type < 0 || type >= type_count)
61 static struct sensors_module_t *hmi;
62 static struct hw_device_t *dev;
64 static pthread_mutex_t client_mutex = PTHREAD_MUTEX_INITIALIZER;
67 static void print_event(struct sensors_event_t *e)
71 pthread_mutex_lock(&client_mutex);
74 pthread_mutex_unlock(&client_mutex);
79 fprintf(f, "event: version=%d sensor=%d type=%s timestamp=%lld\n",
80 e->version, e->sensor, type_str(e->type), (long long)e->timestamp);
83 case SENSOR_TYPE_META_DATA:
85 case SENSOR_TYPE_ACCELEROMETER:
86 case SENSOR_TYPE_LINEAR_ACCELERATION:
87 case SENSOR_TYPE_GRAVITY:
88 fprintf(f, "event: x=%10.2f y=%10.2f z=%10.2f status=%d\n",
89 e->acceleration.x, e->acceleration.y, e->acceleration.z,
90 e->acceleration.status);
92 case SENSOR_TYPE_MAGNETIC_FIELD:
93 fprintf(f, "event: x=%10.2f y=%10.2f z=%10.2f status=%d\n",
94 e->magnetic.x, e->magnetic.y, e->magnetic.z,
97 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
98 fprintf(f, "event: x=%10.2f y=%10.2f z=%10.2f bias_x=%10.2f bias_y=%10.2f bias_z=%10.2f \n",
99 e->uncalibrated_magnetic.x_uncalib,
100 e->uncalibrated_magnetic.y_uncalib,
101 e->uncalibrated_magnetic.z_uncalib,
102 e->uncalibrated_magnetic.x_bias,
103 e->uncalibrated_magnetic.y_bias,
104 e->uncalibrated_magnetic.z_bias);
106 case SENSOR_TYPE_ORIENTATION:
107 fprintf(f, "event: azimuth=%10.2f pitch=%10.2f roll=%10.2f status=%d\n",
108 e->orientation.azimuth, e->orientation.pitch, e->orientation.roll,
109 e->orientation.status);
111 case SENSOR_TYPE_GYROSCOPE:
112 fprintf(f, "event: x=%10.2f y=%10.2f z=%10.2f status=%d\n",
113 e->gyro.x, e->gyro.y, e->gyro.z, e->gyro.status);
115 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
116 fprintf(f, "event: x=%10.2f y=%10.2f z=%10.2f bias_x=%10.2f bias_y=%10.2f bias_z=%10.2f \n",
117 e->uncalibrated_gyro.x_uncalib,
118 e->uncalibrated_gyro.y_uncalib,
119 e->uncalibrated_gyro.z_uncalib,
120 e->uncalibrated_gyro.x_bias,
121 e->uncalibrated_gyro.y_bias,
122 e->uncalibrated_gyro.z_bias);
124 case SENSOR_TYPE_LIGHT:
125 fprintf(f, "event: light=%10.2f\n", e->light);
127 case SENSOR_TYPE_PRESSURE:
128 fprintf(f, "event: pressure=%10.2f\n", e->pressure);
130 case SENSOR_TYPE_TEMPERATURE:
131 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
132 fprintf(f, "event: temperature=%10.2f\n", e->temperature);
134 case SENSOR_TYPE_PROXIMITY:
135 fprintf(f, "event: distance=%10.2f\n", e->distance);
137 case SENSOR_TYPE_ROTATION_VECTOR:
138 case SENSOR_TYPE_GAME_ROTATION_VECTOR:
139 case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
140 fprintf(f, "event: rot_x=%10.2f rot_y=%10.2f rot_z=%10.2f cos=%10.2f estimated_accuracy=%10.2f\n",
141 e->data[0], e->data[1], e->data[2], e->data[3], e->data[4]);
143 case SENSOR_TYPE_RELATIVE_HUMIDITY:
144 fprintf(f, "event: humidity=%10.2f\n", e->relative_humidity);
146 case SENSOR_TYPE_SIGNIFICANT_MOTION:
147 fprintf(f, "event: significant_motion=%10.2f\n", e->data[0]);
149 case SENSOR_TYPE_STEP_DETECTOR:
150 fprintf(f, "event: step_detector=%10.2f\n", e->data[0]);
152 case SENSOR_TYPE_STEP_COUNTER:
153 fprintf(f, "event: step_detector=%llu\n",
154 (unsigned long long)e->u64.step_counter);
161 pthread_mutex_unlock(&client_mutex);
164 static void run_sensors_poll_v0(void)
166 struct sensors_poll_device_t *poll_dev = (struct sensors_poll_device_t *)dev;
169 sensors_event_t events[256];
172 count = poll_dev->poll(poll_dev, events, sizeof(events)/sizeof(sensors_event_t));
174 for(i = 0; i < count; i++)
175 print_event(&events[i]);
179 static void *run_sensors_thread(void *arg)
181 switch (dev->version) {
182 case SENSORS_DEVICE_API_VERSION_0_1:
184 run_sensors_poll_v0();
191 void print_sensor(const struct sensor_t *s, FILE *f)
196 fprintf(f, "sensor%d: name=%s vendor=%s version=%d type=%s\n",
197 s->handle, s->name, s->vendor, s->version, type_str(s->type));
198 fprintf(f, "sensor%d: maxRange=%10.2f resolution=%10.2f power=%10.2f\n",
199 s->handle, s->maxRange, s->resolution, s->power);
200 fprintf(f, "sensor%d: minDelay=%d fifoReservedEventCount=%d fifoMaxEventCount=%d\n",
201 s->handle, s->minDelay, s->fifoReservedEventCount,
202 s->fifoMaxEventCount);
206 static int sensor_set_delay(int handle, int64_t delay)
208 switch (dev->version) {
210 case SENSORS_DEVICE_API_VERSION_0_1:
212 struct sensors_poll_device_t *poll_dev = (struct sensors_poll_device_t *)dev;
214 return poll_dev->setDelay(poll_dev, handle, delay);
220 static int sensor_activate(int handle, int enable)
222 switch (dev->version) {
224 case SENSORS_DEVICE_API_VERSION_0_1:
226 struct sensors_poll_device_t *poll_dev = (struct sensors_poll_device_t *)dev;
228 return poll_dev->activate(poll_dev, handle, enable);
233 #define CLIENT_ERR(f, fmt...) \
234 { if (f) { fprintf(f, fmt); fprintf(f, "\n"); } ALOGE(fmt); }
236 static int dispatch_cmd(char *cmd, int cmd_len, FILE *f)
238 char *argv[16], *tmp;
239 int argc = 0, handle;
241 tmp = strtok(cmd, " ");
244 tmp = strtok(NULL, " ");
250 CLIENT_ERR(f, "invalid cmd: %s", cmd);
254 if (!strcmp(argv[0], "ls")) {
255 struct sensor_t const* list;
256 int i, count = hmi->get_sensors_list(hmi, &list);
258 for(i = 0; i < count; i++)
259 print_sensor(&list[i], f);;
262 } else if (!strcmp(argv[0], "activate")) {
265 CLIENT_ERR(f, "activate: no sensor handle");
269 handle = atoi(argv[1]);
271 return sensor_activate(handle, 1);
273 } else if (!strcmp(argv[0], "deactivate")) {
276 CLIENT_ERR(f, "activate: no sensor handle");
280 handle = atoi(argv[1]);
282 return sensor_activate(handle, 0);
284 } else if (!strcmp(argv[0], "set_delay")) {
288 CLIENT_ERR(f, "setDelay: no sensor handle and/or delay");
292 handle=atoi(argv[1]);
293 delay=atoll(argv[2]);
295 return sensor_set_delay(handle, delay);
297 } else if (!strcmp(argv[0], "poll")) {
299 pthread_mutex_lock(&client_mutex);
301 pthread_mutex_unlock(&client_mutex);
304 } else if (!strcmp(argv[0], "stop")) {
307 CLIENT_ERR(f, "invalid command: %s", cmd);
314 #define NAME_PREFIX "/dev/socket/"
316 #define NAME_PREFIX "/tmp/"
319 #define SENS_SERVER_NAME NAME_PREFIX "sens-server"
321 struct sockaddr_un server_addr = {
322 .sun_family = AF_UNIX,
323 .sun_path = SENS_SERVER_NAME,
326 static int start_server(void)
328 int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0), conn;
331 unlink(SENS_SERVER_NAME);
334 ALOGE("failed to create socket: %s", strerror(errno));
338 err = bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
340 ALOGE("failed to bind socket: %s", strerror(errno));
347 char data_buff[1024], cmsg_buffer[1024];
348 struct iovec recv_buff = {
349 .iov_base = data_buff,
350 .iov_len = sizeof(data_buff),
352 struct sockaddr_un from;
353 struct msghdr msg = {
355 .msg_namelen = sizeof(from),
356 .msg_iov = &recv_buff,
358 .msg_control = cmsg_buffer,
359 .msg_controllen = sizeof(cmsg_buffer),
363 conn = accept(sock, NULL, NULL);
365 ALOGE("failed to accept connection: %s", strerror(errno));
370 struct cmsghdr *cmsg;
372 err = recvmsg(conn, &msg, 0);
374 ALOGE("error in recvmsg: %s", strerror(errno));
381 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
382 cmsg = CMSG_NXTHDR(&msg,cmsg)) {
383 if (cmsg->cmsg_level == SOL_SOCKET
384 && cmsg->cmsg_type == SCM_RIGHTS) {
385 int *fd = (int *)CMSG_DATA(cmsg);
386 f = fdopen(*fd, "w");
391 err = dispatch_cmd(data_buff, err, f);
393 ALOGE("error dispatching command: %d", err);
399 write(conn, data_buff, 1);
402 pthread_mutex_lock(&client_mutex);
404 pthread_mutex_unlock(&client_mutex);
406 fclose(f); close(conn);
410 static const char *hal_paths[] = {
411 "/system/lib/hw/sensors.gmin.so",
413 "/lib/sensors.gmin.so",
416 static int start_hal(int argc, char **argv)
421 pthread_t sensors_thread;
422 const char *hal_path = NULL;
427 for(i = 0; i < sizeof(hal_paths)/sizeof(const char*); i++) {
428 if (!access(hal_paths[i], R_OK)) {
429 hal_path = hal_paths[i];
435 fprintf(stderr, "unable to find HAL\n");
441 hal = dlopen(hal_path, RTLD_NOW);
443 fprintf(stderr, "unable to load HAL %s: %s\n", hal_path,
448 hmi = dlsym(hal, HAL_MODULE_INFO_SYM_AS_STR);
450 fprintf(stderr, "unable to find %s entry point in HAL\n",
451 HAL_MODULE_INFO_SYM_AS_STR);
455 printf("HAL loaded: name %s vendor %s version %d.%d id %s\n",
456 hmi->common.name, hmi->common.author,
457 hmi->common.version_major, hmi->common.version_minor,
466 if (setsid() == (pid_t)-1) {
467 fprintf(stderr, "failed to send process to background\n");
471 close(0); close(1); close(2);
473 ALOGI("Initializing HAL");
475 err = hmi->common.methods->open((struct hw_module_t *)hmi,
476 SENSORS_HARDWARE_POLL, &dev);
479 ALOGE("failed to initialize HAL: %d\n", err);
483 if (pthread_create(&sensors_thread, NULL, run_sensors_thread, NULL)) {
484 ALOGE("failed to create sensor thread");
488 return start_server();
491 int main(int argc, char **argv)
493 char cmd[1024], *tmp;
495 struct iovec buff = {
503 .cmsg_level = SOL_SOCKET,
504 .cmsg_type = SCM_RIGHTS,
505 .cmsg_len = CMSG_LEN(sizeof(int)),
509 struct msghdr msg = {
514 .msg_control = &cmsg_buff,
515 .msg_controllen = sizeof(cmsg_buff),
524 if (!strcmp(argv[1], "start")) {
528 return start_hal(argc, argv);
531 if (strlen(argv[1]) >= sizeof(cmd))
533 strncpy(cmd, argv[1], sizeof(cmd) - 1);
534 strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
535 for(i = 2; i < argc; i++) {
536 strncat(cmd, argv[i], sizeof(cmd) - strlen(cmd) - 1);
537 strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
540 sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
542 fprintf(stderr, "failed to create socket: %s\n", strerror(errno));
546 if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
547 fprintf(stderr, "failed to connect to server: %s\n", strerror(errno));
551 buff.iov_len = strlen(cmd) + 1;
552 if (sendmsg(sock, &msg, 0) < 0) {
553 fprintf(stderr, "failed sending command to server: %s\n", strerror(errno));
557 buff.iov_len = sizeof(cmd);
558 if (read(sock, cmd, 1) < 0) {
559 fprintf(stderr, "failed getting ack from server: %s\n", strerror(errno));