/*
- * Copyright (C) 2014 Intel Corporation.
- */
+// Copyright (c) 2015 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <pthread.h>
#include <errno.h>
+#include <signal.h>
+#include <string.h>
#include <hardware/sensors.h>
#include <utils/Log.h>
int usage(void)
{
- fprintf(stderr, "sens start hal.so\n");
+ fprintf(stderr, "sens start [sensors.gmin.so]\n");
fprintf(stderr, "sens [activate | deactivate] sensor_id\n");
fprintf(stderr, "sens set_delay sensor_id delay\n");
fprintf(stderr, "sens poll\n");
+ fprintf(stderr, "sens poll [duration] [number_of_events] \n");
+ fprintf(stderr, "sens poll_stop\n");
+ fprintf(stderr, "sens check_sample_rate [rate] \n");
return 1;
}
static const char *type_str(int type)
{
- if (type < 0 || type > (int)sizeof(types)/sizeof(char *))
+ int type_count = sizeof(types)/sizeof(char *);
+
+ if (type < 0 || type >= type_count)
return "unknown";
return types[type];
}
static struct hw_device_t *dev;
static FILE *client;
static pthread_mutex_t client_mutex = PTHREAD_MUTEX_INITIALIZER;
-
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static int ready_to_close = 0;
+static int number_of_events = 0;
+static int non_param_poll = 1;
+static int event_no = 0;
+static int init_events = 0;
+static int print_events = 1;
+static long long timestamp = 0;
+static long long event_init_poll_time = 0;
+static long long poll_duration = 0;
static void print_event(struct sensors_event_t *e)
{
FILE *f;
pthread_mutex_lock(&client_mutex);
-
if (!client) {
pthread_mutex_unlock(&client_mutex);
return;
}
f = client;
- fprintf(f, "event: version=%d sensor=%d type=%s timestamp=%lld\n",
+ fprintf(f, "event %d: version=%d sensor=%d type=%s timestamp=%lld\n",event_no,
e->version, e->sensor, type_str(e->type), (long long)e->timestamp);
-
+ if (poll_duration != 0)
+ fprintf(f,"Time remaining:%lld \n",poll_duration - ((long long)e->timestamp
+ - event_init_poll_time));
switch (e->type) {
case SENSOR_TYPE_META_DATA:
break;
fprintf(f, "event: step_detector=%10.2f\n", e->data[0]);
break;
case SENSOR_TYPE_STEP_COUNTER:
- fprintf(f, "event: step_detector=%llu\n",
+ fprintf(f, "event: step_counter=%llu\n",
(unsigned long long)e->u64.step_counter);
break;
}
-
fprintf(f, "\n");
fflush(f);
pthread_mutex_unlock(&client_mutex);
}
+static void print_result(int result)
+{
+ FILE *f;
+ pthread_mutex_lock(&client_mutex);
+ if (!client) {
+ pthread_mutex_unlock(&client_mutex);
+ return;
+ }
+ f = client;
+ fprintf(f, "Number of events: %d \n", event_no - init_events);
+ fprintf(f, "Duration: %lld \n\n", (long long) timestamp - event_init_poll_time);
+ if(!print_events){
+ if(result)
+ fprintf(f, "Test passed\n\n");
+ else
+ fprintf(f, "Test failed\n\n");
+ }
+ fflush(f);
+ pthread_mutex_unlock(&client_mutex);
+
+}
+
+static void process_event(struct sensors_event_t *e)
+{
+ int is_poll_duration_over = 0;
+ int is_event_number_reached = 0;
+
+ if (event_init_poll_time == 0) {
+ event_init_poll_time = (long long) e->timestamp;
+ init_events = event_no;
+ }
+ is_poll_duration_over = (long long) e->timestamp - event_init_poll_time <= poll_duration ? 0 : 1;
+ is_event_number_reached = (event_no - init_events) < number_of_events ? 0 : 1;
+
+ if ((!is_poll_duration_over && !is_event_number_reached) || non_param_poll)
+ {
+ timestamp = e -> timestamp;
+ event_no++;
+ if(print_events)
+ print_event(e);
+ } else {
+ ready_to_close = 1;
+ print_result(is_event_number_reached);
+ pthread_cond_signal(&cond);
+ }
+}
+
static void run_sensors_poll_v0(void)
{
struct sensors_poll_device_t *poll_dev = (struct sensors_poll_device_t *)dev;
count = poll_dev->poll(poll_dev, events, sizeof(events)/sizeof(sensors_event_t));
for(i = 0; i < count; i++)
- print_event(&events[i]);
+ process_event(&events[i]);
}
}
-static void *run_sensors_thread(void *arg)
+static void sig_pipe(int sig)
{
+ client = NULL;
+}
+
+static void *run_sensors_thread(void *arg __attribute((unused)))
+{
+
+ signal(SIGPIPE, sig_pipe);
+
switch (dev->version) {
case SENSORS_DEVICE_API_VERSION_0_1:
default:
#define CLIENT_ERR(f, fmt...) \
{ if (f) { fprintf(f, fmt); fprintf(f, "\n"); } ALOGE(fmt); }
-static int dispatch_cmd(char *cmd, int cmd_len, FILE *f)
+static int dispatch_cmd(char *cmd, FILE *f)
{
char *argv[16], *tmp;
int argc = 0, handle;
return sensor_set_delay(handle, delay);
} else if (!strcmp(argv[0], "poll")) {
+ if (argc == 1) {
+ non_param_poll = 1;
+ } else if (argc == 3) {
+ non_param_poll = 0;
+ poll_duration = atoll(argv[1]);
+ number_of_events = atoi(argv[2]);
+ event_init_poll_time = 0;
+ ready_to_close = 0;
+ } else {
+ CLIENT_ERR(f, "poll: no poll duration or number of events set");
+ return -1;
+ }
+ print_events = 1;
+ pthread_mutex_lock(&client_mutex);
+ if (client)
+ fclose(client);
+ client = f;
+
+ if (!non_param_poll) {
+ pthread_cond_wait(&cond, &client_mutex);
+ fclose(client);
+ client = NULL;
+ }
+
+ pthread_mutex_unlock(&client_mutex);
+
+ return 1;
+ } else if (!strcmp(argv[0], "check_sample_rate")) {
+
+ if (argc < 2) {
+ CLIENT_ERR(f, "check_sample_rate: no events rate");
+ return -1;
+ }
+
+ non_param_poll = 0;
+ poll_duration = 1000000000;
+ number_of_events = atoi(argv[1]);
+ event_init_poll_time = 0;
+ ready_to_close = 0;
+ print_events = 0;
pthread_mutex_lock(&client_mutex);
+ if (client)
+ fclose(client);
client = f;
+ pthread_cond_wait(&cond, &client_mutex);
+ fclose(client);
+ client = NULL;
+ pthread_mutex_unlock(&client_mutex);
+ return 1;
+ } else if (!strcmp(argv[0], "poll_stop")) {
+ pthread_mutex_lock(&client_mutex);
+ if (client){
+ fclose(client);
+ client = NULL;
+ }
pthread_mutex_unlock(&client_mutex);
return 1;
.msg_controllen = sizeof(cmsg_buffer),
};
FILE *f =NULL;
+ struct cmsghdr *cmsg;
conn = accept(sock, NULL, NULL);
if (conn < 0) {
continue;
}
- while (1) {
- struct cmsghdr *cmsg;
+ err = recvmsg(conn, &msg, 0);
+ if (err < 0) {
+ ALOGE("error in recvmsg: %s", strerror(errno));
+ close(conn);
+ continue;
+ }
- err = recvmsg(conn, &msg, 0);
- if (err < 0) {
- ALOGE("error in recvmsg: %s", strerror(errno));
- break;
- }
+ if (err == 0)
+ continue;
- if (err == 0)
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg,cmsg)) {
+ if (cmsg->cmsg_level == SOL_SOCKET
+ && cmsg->cmsg_type == SCM_RIGHTS) {
+ int *fd = (int *)CMSG_DATA(cmsg);
+ f = fdopen(*fd, "w");
break;
-
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
- cmsg = CMSG_NXTHDR(&msg,cmsg)) {
- if (cmsg->cmsg_level == SOL_SOCKET
- && cmsg->cmsg_type == SCM_RIGHTS) {
- int *fd = (int *)CMSG_DATA(cmsg);
- f = fdopen(*fd, "w");
- break;
- }
}
+ }
- err = dispatch_cmd(data_buff, err, f);
- if (err < 0) {
- ALOGE("error dispatching command: %d", err);
- break;
- }
+ if (data_buff[err - 1] != 0) {
+ ALOGE("command is not NULL terminated\n");
+ close(conn);
+ continue;
+ }
- /* send ack */
- if (!err)
- write(conn, data_buff, 1);
+ err = dispatch_cmd(data_buff, f);
+ if (err < 0) {
+ ALOGE("error dispatching command: %d", err);
+ close(conn);
+ continue;
}
- pthread_mutex_lock(&client_mutex);
- client = NULL;
- pthread_mutex_unlock(&client_mutex);
+ /* send ack */
+ if (!err) {
+ write(conn, data_buff, 1);
+ fclose(f);
+ }
- fclose(f); close(conn);
+ close(conn);
}
}
-static int start_hal(const char *hal_path)
+static const char *hal_paths[] = {
+ "/system/lib/hw/sensors.gmin.so",
+ "sensors.gmin.so",
+ "/lib/sensors.gmin.so",
+};
+
+static int start_hal(int argc, char **argv)
{
void *hal;
pid_t child;
int err;
pthread_t sensors_thread;
+ const char *hal_path = NULL;
+ if (argc == 2) {
+ unsigned i;
+
+ for(i = 0; i < sizeof(hal_paths)/sizeof(const char*); i++) {
+ if (!access(hal_paths[i], R_OK)) {
+ hal_path = hal_paths[i];
+ break;
+ }
+ }
+
+ if (!hal_path) {
+ fprintf(stderr, "unable to find HAL\n");
+ exit(1);
+ }
+ } else
+ hal_path = argv[2];
hal = dlopen(hal_path, RTLD_NOW);
if (!hal) {
{
char cmd[1024];
int sock, i;
- struct iovec recv_buff = {
+ struct iovec buff = {
.iov_base = cmd,
- .iov_len = sizeof(cmd),
};
struct cmsg_fd {
struct cmsghdr hdr;
struct msghdr msg = {
.msg_name = NULL,
.msg_namelen = 0,
- .msg_iov = &recv_buff,
+ .msg_iov = &buff,
.msg_iovlen = 1,
.msg_control = &cmsg_buff,
.msg_controllen = sizeof(cmsg_buff),
}
if (!strcmp(argv[1], "start")) {
- if (argc < 3)
+ if (argc < 2)
return usage();
- return start_hal(argv[2]);
+ return start_hal(argc, argv);
}
- strcpy(cmd, argv[1]); strcat(cmd, " ");
+ if (strlen(argv[1]) >= sizeof(cmd))
+ return usage();
+ strncpy(cmd, argv[1], sizeof(cmd) - 1);
+ strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
for(i = 2; i < argc; i++) {
- strcat(cmd, argv[i]); strcat(cmd, " ");
+ strncat(cmd, argv[i], sizeof(cmd) - strlen(cmd) - 1);
+ strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
}
sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
return 5;
}
+ buff.iov_len = strlen(cmd) + 1;
if (sendmsg(sock, &msg, 0) < 0) {
fprintf(stderr, "failed sending command to server: %s\n", strerror(errno));
return 6;
}
+ buff.iov_len = sizeof(cmd);
if (read(sock, cmd, 1) < 0) {
fprintf(stderr, "failed getting ack from server: %s\n", strerror(errno));
return 7;