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