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
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;
44bool SensorBase::DEBUG_BATCHING = 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    property_get("invn.hal.debug.batching", value, "0");
91    if (atoi(value)) {
92        DEBUG_BATCHING = true;
93    }
94}
95
96SensorBase::~SensorBase()
97{
98    if (data_fd >= 0) {
99        close(data_fd);
100    }
101    if (dev_fd >= 0) {
102        close(dev_fd);
103    }
104}
105
106int SensorBase::open_device()
107{
108    if (dev_fd<0 && dev_name) {
109        dev_fd = open(dev_name, O_RDONLY);
110        LOGE_IF(dev_fd<0, "Couldn't open %s (%s)", dev_name, strerror(errno));
111    }
112    return 0;
113}
114
115int SensorBase::close_device()
116{
117    if (dev_fd >= 0) {
118        close(dev_fd);
119        dev_fd = -1;
120    }
121    return 0;
122}
123
124int SensorBase::getFd() const
125{
126    if (!data_name) {
127        return dev_fd;
128    }
129    return data_fd;
130}
131
132int SensorBase::setDelay(int32_t handle, int64_t ns)
133{
134    return 0;
135}
136
137bool SensorBase::hasPendingEvents() const
138{
139    return false;
140}
141
142int64_t SensorBase::getTimestamp()
143{
144    struct timespec t;
145    t.tv_sec = t.tv_nsec = 0;
146    clock_gettime(CLOCK_MONOTONIC, &t);
147    return int64_t(t.tv_sec) * 1000000000LL + t.tv_nsec;
148}
149
150int SensorBase::openInput(const char *inputName)
151{
152    int fd = -1;
153    const char *dirname = "/dev/input";
154    char devname[PATH_MAX];
155    char *filename;
156    DIR *dir;
157    struct dirent *de;
158    dir = opendir(dirname);
159    if(dir == NULL)
160        return -1;
161    strcpy(devname, dirname);
162    filename = devname + strlen(devname);
163    *filename++ = '/';
164    while((de = readdir(dir))) {
165        if(de->d_name[0] == '.' &&
166                (de->d_name[1] == '\0' ||
167                        (de->d_name[1] == '.' && de->d_name[2] == '\0')))
168            continue;
169        strcpy(filename, de->d_name);
170        fd = open(devname, O_RDONLY);
171        LOGV_IF(EXTRA_VERBOSE, "path open %s", devname);
172        LOGI("path open %s", devname);
173        if (fd >= 0) {
174            char name[80];
175            if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
176                name[0] = '\0';
177            }
178            LOGV_IF(EXTRA_VERBOSE, "name read %s", name);
179            if (!strcmp(name, inputName)) {
180                strcpy(input_name, filename);
181                break;
182            } else {
183                close(fd);
184                fd = -1;
185            }
186        }
187    }
188    closedir(dir);
189    LOGE_IF(fd < 0, "couldn't find '%s' input device", inputName);
190    return fd;
191}
192
193int SensorBase::enable(int32_t handle, int enabled)
194{
195    return 0;
196}
197
198int SensorBase::query(int what, int* value)
199{
200    return 0;
201}
202
203int SensorBase::batch(int handle, int flags, int64_t period_ns, int64_t timeout)
204{
205    return 0;
206}
207
208int SensorBase::flush(int handle)
209{
210    return 0;
211}
212