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