1/*
2* Copyright (C) 2012 Invensense, Inc.
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#include <fcntl.h>
18#include <errno.h>
19#include <math.h>
20#include <poll.h>
21#include <unistd.h>
22#include <stdlib.h>
23#include <dirent.h>
24#include <sys/select.h>
25#include <cutils/log.h>
26#include <linux/input.h>
27
28#include <cutils/properties.h>
29
30#include "SensorBase.h"
31
32/*****************************************************************************/
33
34// static vars
35bool SensorBase::PROCESS_VERBOSE = false;
36bool SensorBase::EXTRA_VERBOSE = false;
37bool SensorBase::SYSFS_VERBOSE = false;
38
39bool SensorBase::FUNC_ENTRY = false;
40bool SensorBase::HANDLER_ENTRY = false;
41bool SensorBase::ENG_VERBOSE = false;
42bool SensorBase::INPUT_DATA = false;
43bool SensorBase::HANDLER_DATA = false;
44
45SensorBase::SensorBase(const char* dev_name,
46                       const char* data_name)
47                        : dev_name(dev_name),
48                          data_name(data_name),
49                          dev_fd(-1),
50                          data_fd(-1)
51{
52    if (data_name) {
53        data_fd = openInput(data_name);
54    }
55
56    char value[PROPERTY_VALUE_MAX];
57    property_get("invn.hal.verbose.basic", value, "0");
58    if (atoi(value)) {
59        PROCESS_VERBOSE = true;
60    }
61    property_get("invn.hal.verbose.extra", value, "0");
62    if (atoi(value)) {
63        EXTRA_VERBOSE = true;
64    }
65    property_get("invn.hal.verbose.sysfs", value, "0");
66    if (atoi(value)) {
67        SYSFS_VERBOSE = true;
68    }
69    property_get("invn.hal.verbose.engineering", value, "0");
70    if (atoi(value)) {
71        ENG_VERBOSE = true;
72    }
73    property_get("invn.hal.entry.function", value, "0");
74    if (atoi(value)) {
75        FUNC_ENTRY = true;
76    }
77    property_get("invn.hal.entry.handler", value, "0");
78    if (atoi(value)) {
79        HANDLER_ENTRY = true;
80    }
81    property_get("invn.hal.data.input", value, "0");
82    if (atoi(value)) {
83        INPUT_DATA = true;
84    }
85    property_get("invn.hal.data.handler", value, "0");
86    if (atoi(value)) {
87        HANDLER_DATA = true;
88    }
89}
90
91SensorBase::~SensorBase()
92{
93    if (data_fd >= 0) {
94        close(data_fd);
95    }
96    if (dev_fd >= 0) {
97        close(dev_fd);
98    }
99}
100
101int SensorBase::open_device()
102{
103    if (dev_fd<0 && dev_name) {
104        dev_fd = open(dev_name, O_RDONLY);
105        LOGE_IF(dev_fd<0, "Couldn't open %s (%s)", dev_name, strerror(errno));
106    }
107    return 0;
108}
109
110int SensorBase::close_device()
111{
112    if (dev_fd >= 0) {
113        close(dev_fd);
114        dev_fd = -1;
115    }
116    return 0;
117}
118
119int SensorBase::getFd() const
120{
121    if (!data_name) {
122        return dev_fd;
123    }
124    return data_fd;
125}
126
127int SensorBase::setDelay(int32_t handle, int64_t ns)
128{
129    return 0;
130}
131
132bool SensorBase::hasPendingEvents() const
133{
134    return false;
135}
136
137int64_t SensorBase::getTimestamp()
138{
139    struct timespec t;
140    t.tv_sec = t.tv_nsec = 0;
141    clock_gettime(CLOCK_MONOTONIC, &t);
142    return int64_t(t.tv_sec) * 1000000000LL + t.tv_nsec;
143}
144
145int SensorBase::openInput(const char *inputName)
146{
147    int fd = -1;
148    const char *dirname = "/dev/input";
149    char devname[PATH_MAX];
150    char *filename;
151    DIR *dir;
152    struct dirent *de;
153    dir = opendir(dirname);
154    if(dir == NULL)
155        return -1;
156    strcpy(devname, dirname);
157    filename = devname + strlen(devname);
158    *filename++ = '/';
159    while((de = readdir(dir))) {
160        if(de->d_name[0] == '.' &&
161                (de->d_name[1] == '\0' ||
162                        (de->d_name[1] == '.' && de->d_name[2] == '\0')))
163            continue;
164        strcpy(filename, de->d_name);
165        fd = open(devname, O_RDONLY);
166        LOGV_IF(EXTRA_VERBOSE, "path open %s", devname);
167        LOGI("path open %s", devname);
168        if (fd >= 0) {
169            char name[80];
170            if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
171                name[0] = '\0';
172            }
173            LOGV_IF(EXTRA_VERBOSE, "name read %s", name);
174            if (!strcmp(name, inputName)) {
175                strcpy(input_name, filename);
176                break;
177            } else {
178                close(fd);
179                fd = -1;
180            }
181        }
182    }
183    closedir(dir);
184    LOGE_IF(fd < 0, "couldn't find '%s' input device", inputName);
185    return fd;
186}
187
188int SensorBase::enable(int32_t handle, int enabled)
189{
190    return 0;
191}
192
193int SensorBase::query(int what, int* value)
194{
195    return 0;
196}
197
198int SensorBase::batch(int handle, int flags, int64_t period_ns, int64_t timeout)
199{
200    return 0;
201}
202
203int SensorBase::flush(int handle)
204{
205    return 0;
206}
207