2 // Copyright (c) 2015 Intel Corporation
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <sys/socket.h>
27 #include <hardware/sensors.h>
28 #include <utils/Log.h>
32 fprintf(stderr, "sens start [sensors.gmin.so]\n");
33 fprintf(stderr, "sens [activate | deactivate] sensor_id\n");
34 fprintf(stderr, "sens set_delay sensor_id delay\n");
35 fprintf(stderr, "sens poll\n");
36 fprintf(stderr, "sens poll [duration] [number_of_events] \n");
37 fprintf(stderr, "sens poll_stop\n");
38 fprintf(stderr, "sens check_sample_rate [rate] \n");
42 static struct sensors_module_t *hmi;
44 static const char* types[] = {
55 "linear acceleration",
58 "ambient temperature",
59 "uncalibrated magnetometer",
60 "game rotation vector",
61 "uncalibrated gyrocope",
65 "geomagnetic rotation vector",
68 static const char *type_str(int type)
70 int type_count = sizeof(types)/sizeof(char *);
72 if (type < 0 || type >= type_count)
78 static struct sensors_module_t *hmi;
79 static struct hw_device_t *dev;
81 static pthread_mutex_t client_mutex = PTHREAD_MUTEX_INITIALIZER;
82 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
83 static int ready_to_close = 0;
84 static int number_of_events = 0;
85 static int non_param_poll = 1;
86 static int event_no = 0;
87 static int init_events = 0;
88 static int print_events = 1;
89 static long long timestamp = 0;
90 static long long event_init_poll_time = 0;
91 static long long poll_duration = 0;
93 static void print_event(struct sensors_event_t *e)
97 pthread_mutex_lock(&client_mutex);
99 pthread_mutex_unlock(&client_mutex);
104 fprintf(f, "event %d: version=%d sensor=%d type=%s timestamp=%lld\n",event_no,
105 e->version, e->sensor, type_str(e->type), (long long)e->timestamp);
106 if (poll_duration != 0)
107 fprintf(f,"Time remaining:%lld \n",poll_duration - ((long long)e->timestamp
108 - event_init_poll_time));
110 case SENSOR_TYPE_META_DATA:
112 case SENSOR_TYPE_ACCELEROMETER:
113 case SENSOR_TYPE_LINEAR_ACCELERATION:
114 case SENSOR_TYPE_GRAVITY:
115 fprintf(f, "event: x=%10.2f y=%10.2f z=%10.2f status=%d\n",
116 e->acceleration.x, e->acceleration.y, e->acceleration.z,
117 e->acceleration.status);
119 case SENSOR_TYPE_MAGNETIC_FIELD:
120 fprintf(f, "event: x=%10.2f y=%10.2f z=%10.2f status=%d\n",
121 e->magnetic.x, e->magnetic.y, e->magnetic.z,
124 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
125 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",
126 e->uncalibrated_magnetic.x_uncalib,
127 e->uncalibrated_magnetic.y_uncalib,
128 e->uncalibrated_magnetic.z_uncalib,
129 e->uncalibrated_magnetic.x_bias,
130 e->uncalibrated_magnetic.y_bias,
131 e->uncalibrated_magnetic.z_bias);
133 case SENSOR_TYPE_ORIENTATION:
134 fprintf(f, "event: azimuth=%10.2f pitch=%10.2f roll=%10.2f status=%d\n",
135 e->orientation.azimuth, e->orientation.pitch, e->orientation.roll,
136 e->orientation.status);
138 case SENSOR_TYPE_GYROSCOPE:
139 fprintf(f, "event: x=%10.2f y=%10.2f z=%10.2f status=%d\n",
140 e->gyro.x, e->gyro.y, e->gyro.z, e->gyro.status);
142 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
143 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",
144 e->uncalibrated_gyro.x_uncalib,
145 e->uncalibrated_gyro.y_uncalib,
146 e->uncalibrated_gyro.z_uncalib,
147 e->uncalibrated_gyro.x_bias,
148 e->uncalibrated_gyro.y_bias,
149 e->uncalibrated_gyro.z_bias);
151 case SENSOR_TYPE_LIGHT:
152 fprintf(f, "event: light=%10.2f\n", e->light);
154 case SENSOR_TYPE_PRESSURE:
155 fprintf(f, "event: pressure=%10.2f\n", e->pressure);
157 case SENSOR_TYPE_TEMPERATURE:
158 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
159 fprintf(f, "event: temperature=%10.2f\n", e->temperature);
161 case SENSOR_TYPE_PROXIMITY:
162 fprintf(f, "event: distance=%10.2f\n", e->distance);
164 case SENSOR_TYPE_ROTATION_VECTOR:
165 case SENSOR_TYPE_GAME_ROTATION_VECTOR:
166 case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
167 fprintf(f, "event: rot_x=%10.2f rot_y=%10.2f rot_z=%10.2f cos=%10.2f estimated_accuracy=%10.2f\n",
168 e->data[0], e->data[1], e->data[2], e->data[3], e->data[4]);
170 case SENSOR_TYPE_RELATIVE_HUMIDITY:
171 fprintf(f, "event: humidity=%10.2f\n", e->relative_humidity);
173 case SENSOR_TYPE_SIGNIFICANT_MOTION:
174 fprintf(f, "event: significant_motion=%10.2f\n", e->data[0]);
176 case SENSOR_TYPE_STEP_DETECTOR:
177 fprintf(f, "event: step_detector=%10.2f\n", e->data[0]);
179 case SENSOR_TYPE_STEP_COUNTER:
180 fprintf(f, "event: step_counter=%llu\n",
181 (unsigned long long)e->u64.step_counter);
187 pthread_mutex_unlock(&client_mutex);
190 static void print_result(int result)
193 pthread_mutex_lock(&client_mutex);
195 pthread_mutex_unlock(&client_mutex);
199 fprintf(f, "Number of events: %d \n", event_no - init_events);
200 fprintf(f, "Duration: %lld \n\n", (long long) timestamp - event_init_poll_time);
203 fprintf(f, "Test passed\n\n");
205 fprintf(f, "Test failed\n\n");
208 pthread_mutex_unlock(&client_mutex);
212 static void process_event(struct sensors_event_t *e)
214 int is_poll_duration_over = 0;
215 int is_event_number_reached = 0;
217 if (event_init_poll_time == 0) {
218 event_init_poll_time = (long long) e->timestamp;
219 init_events = event_no;
221 is_poll_duration_over = (long long) e->timestamp - event_init_poll_time <= poll_duration ? 0 : 1;
222 is_event_number_reached = (event_no - init_events) < number_of_events ? 0 : 1;
224 if ((!is_poll_duration_over && !is_event_number_reached) || non_param_poll)
226 timestamp = e -> timestamp;
232 print_result(is_event_number_reached);
233 pthread_cond_signal(&cond);
237 static void run_sensors_poll_v0(void)
239 struct sensors_poll_device_t *poll_dev = (struct sensors_poll_device_t *)dev;
242 sensors_event_t events[256];
245 count = poll_dev->poll(poll_dev, events, sizeof(events)/sizeof(sensors_event_t));
247 for(i = 0; i < count; i++)
248 process_event(&events[i]);
252 static void sig_pipe(int sig)
257 static void *run_sensors_thread(void *arg __attribute((unused)))
260 signal(SIGPIPE, sig_pipe);
262 switch (dev->version) {
263 case SENSORS_DEVICE_API_VERSION_0_1:
265 run_sensors_poll_v0();
272 void print_sensor(const struct sensor_t *s, FILE *f)
277 fprintf(f, "sensor%d: name=%s vendor=%s version=%d type=%s\n",
278 s->handle, s->name, s->vendor, s->version, type_str(s->type));
279 fprintf(f, "sensor%d: maxRange=%10.2f resolution=%10.2f power=%10.2f\n",
280 s->handle, s->maxRange, s->resolution, s->power);
281 fprintf(f, "sensor%d: minDelay=%d fifoReservedEventCount=%d fifoMaxEventCount=%d\n",
282 s->handle, s->minDelay, s->fifoReservedEventCount,
283 s->fifoMaxEventCount);
287 static int sensor_set_delay(int handle, int64_t delay)
289 switch (dev->version) {
291 case SENSORS_DEVICE_API_VERSION_0_1:
293 struct sensors_poll_device_t *poll_dev = (struct sensors_poll_device_t *)dev;
295 return poll_dev->setDelay(poll_dev, handle, delay);
301 static int sensor_activate(int handle, int enable)
303 switch (dev->version) {
305 case SENSORS_DEVICE_API_VERSION_0_1:
307 struct sensors_poll_device_t *poll_dev = (struct sensors_poll_device_t *)dev;
309 return poll_dev->activate(poll_dev, handle, enable);
314 #define CLIENT_ERR(f, fmt...) \
315 { if (f) { fprintf(f, fmt); fprintf(f, "\n"); } ALOGE(fmt); }
317 static int dispatch_cmd(char *cmd, FILE *f)
319 char *argv[16], *tmp;
320 int argc = 0, handle;
322 tmp = strtok(cmd, " ");
325 tmp = strtok(NULL, " ");
331 CLIENT_ERR(f, "invalid cmd: %s", cmd);
335 if (!strcmp(argv[0], "ls")) {
336 struct sensor_t const* list;
337 int i, count = hmi->get_sensors_list(hmi, &list);
339 for(i = 0; i < count; i++)
340 print_sensor(&list[i], f);;
343 } else if (!strcmp(argv[0], "activate")) {
346 CLIENT_ERR(f, "activate: no sensor handle");
350 handle = atoi(argv[1]);
352 return sensor_activate(handle, 1);
354 } else if (!strcmp(argv[0], "deactivate")) {
357 CLIENT_ERR(f, "activate: no sensor handle");
361 handle = atoi(argv[1]);
363 return sensor_activate(handle, 0);
365 } else if (!strcmp(argv[0], "set_delay")) {
369 CLIENT_ERR(f, "setDelay: no sensor handle and/or delay");
373 handle=atoi(argv[1]);
374 delay=atoll(argv[2]);
376 return sensor_set_delay(handle, delay);
378 } else if (!strcmp(argv[0], "poll")) {
381 } else if (argc == 3) {
383 poll_duration = atoll(argv[1]);
384 number_of_events = atoi(argv[2]);
385 event_init_poll_time = 0;
388 CLIENT_ERR(f, "poll: no poll duration or number of events set");
392 pthread_mutex_lock(&client_mutex);
397 if (!non_param_poll) {
398 pthread_cond_wait(&cond, &client_mutex);
403 pthread_mutex_unlock(&client_mutex);
406 } else if (!strcmp(argv[0], "check_sample_rate")) {
409 CLIENT_ERR(f, "check_sample_rate: no events rate");
414 poll_duration = 1000000000;
415 number_of_events = atoi(argv[1]);
416 event_init_poll_time = 0;
420 pthread_mutex_lock(&client_mutex);
424 pthread_cond_wait(&cond, &client_mutex);
427 pthread_mutex_unlock(&client_mutex);
429 } else if (!strcmp(argv[0], "poll_stop")) {
430 pthread_mutex_lock(&client_mutex);
435 pthread_mutex_unlock(&client_mutex);
438 } else if (!strcmp(argv[0], "stop")) {
441 CLIENT_ERR(f, "invalid command: %s", cmd);
448 #define NAME_PREFIX "/dev/socket/"
450 #define NAME_PREFIX "/tmp/"
453 #define SENS_SERVER_NAME NAME_PREFIX "sens-server"
455 struct sockaddr_un server_addr = {
456 .sun_family = AF_UNIX,
457 .sun_path = SENS_SERVER_NAME,
460 static int start_server(void)
462 int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0), conn;
465 unlink(SENS_SERVER_NAME);
468 ALOGE("failed to create socket: %s", strerror(errno));
472 err = bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
474 ALOGE("failed to bind socket: %s", strerror(errno));
481 char data_buff[1024], cmsg_buffer[1024];
482 struct iovec recv_buff = {
483 .iov_base = data_buff,
484 .iov_len = sizeof(data_buff),
486 struct sockaddr_un from;
487 struct msghdr msg = {
489 .msg_namelen = sizeof(from),
490 .msg_iov = &recv_buff,
492 .msg_control = cmsg_buffer,
493 .msg_controllen = sizeof(cmsg_buffer),
496 struct cmsghdr *cmsg;
498 conn = accept(sock, NULL, NULL);
500 ALOGE("failed to accept connection: %s", strerror(errno));
504 err = recvmsg(conn, &msg, 0);
506 ALOGE("error in recvmsg: %s", strerror(errno));
514 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
515 cmsg = CMSG_NXTHDR(&msg,cmsg)) {
516 if (cmsg->cmsg_level == SOL_SOCKET
517 && cmsg->cmsg_type == SCM_RIGHTS) {
518 int *fd = (int *)CMSG_DATA(cmsg);
519 f = fdopen(*fd, "w");
524 if (data_buff[err - 1] != 0) {
525 ALOGE("command is not NULL terminated\n");
530 err = dispatch_cmd(data_buff, f);
532 ALOGE("error dispatching command: %d", err);
539 write(conn, data_buff, 1);
547 static const char *hal_paths[] = {
548 "/system/lib/hw/sensors.gmin.so",
550 "/lib/sensors.gmin.so",
553 static int start_hal(int argc, char **argv)
558 pthread_t sensors_thread;
559 const char *hal_path = NULL;
564 for(i = 0; i < sizeof(hal_paths)/sizeof(const char*); i++) {
565 if (!access(hal_paths[i], R_OK)) {
566 hal_path = hal_paths[i];
572 fprintf(stderr, "unable to find HAL\n");
578 hal = dlopen(hal_path, RTLD_NOW);
580 fprintf(stderr, "unable to load HAL %s: %s\n", hal_path,
585 hmi = dlsym(hal, HAL_MODULE_INFO_SYM_AS_STR);
587 fprintf(stderr, "unable to find %s entry point in HAL\n",
588 HAL_MODULE_INFO_SYM_AS_STR);
592 printf("HAL loaded: name %s vendor %s version %d.%d id %s\n",
593 hmi->common.name, hmi->common.author,
594 hmi->common.version_major, hmi->common.version_minor,
603 if (setsid() == (pid_t)-1) {
604 fprintf(stderr, "failed to send process to background\n");
608 close(0); close(1); close(2);
610 ALOGI("Initializing HAL");
612 err = hmi->common.methods->open((struct hw_module_t *)hmi,
613 SENSORS_HARDWARE_POLL, &dev);
616 ALOGE("failed to initialize HAL: %d\n", err);
620 if (pthread_create(&sensors_thread, NULL, run_sensors_thread, NULL)) {
621 ALOGE("failed to create sensor thread");
625 return start_server();
628 int main(int argc, char **argv)
632 struct iovec buff = {
640 .cmsg_level = SOL_SOCKET,
641 .cmsg_type = SCM_RIGHTS,
642 .cmsg_len = CMSG_LEN(sizeof(int)),
646 struct msghdr msg = {
651 .msg_control = &cmsg_buff,
652 .msg_controllen = sizeof(cmsg_buff),
661 if (!strcmp(argv[1], "start")) {
665 return start_hal(argc, argv);
668 if (strlen(argv[1]) >= sizeof(cmd))
670 strncpy(cmd, argv[1], sizeof(cmd) - 1);
671 strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
672 for(i = 2; i < argc; i++) {
673 strncat(cmd, argv[i], sizeof(cmd) - strlen(cmd) - 1);
674 strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
677 sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
679 fprintf(stderr, "failed to create socket: %s\n", strerror(errno));
683 if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
684 fprintf(stderr, "failed to connect to server: %s\n", strerror(errno));
688 buff.iov_len = strlen(cmd) + 1;
689 if (sendmsg(sock, &msg, 0) < 0) {
690 fprintf(stderr, "failed sending command to server: %s\n", strerror(errno));
694 buff.iov_len = sizeof(cmd);
695 if (read(sock, cmd, 1) < 0) {
696 fprintf(stderr, "failed getting ack from server: %s\n", strerror(errno));