1 /*
2  * Copyright (C) 2015 Intel Corporation
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 <string.h>
18 #include <cutils/log.h>
19 #include <stdexcept>
20 #include <errno.h>
21 #include <sys/epoll.h>
22 #include "SensorsHAL.hpp"
23 
24 Sensor * (*SensorContext::sensorFactoryFuncs[MAX_DEVICES])(int);
25 struct sensor_t SensorContext::sensorDescs[MAX_DEVICES];
26 int SensorContext::sensorsNum = 0;
27 android::Mutex SensorContext::mutex;
28 
SensorContext(const hw_module_t * module)29 SensorContext::SensorContext(const hw_module_t *module) {
30   /* create the epoll fd used to register the incoming fds */
31   pollFd = epoll_create(MAX_DEVICES);
32   if (pollFd == -1) {
33     throw std::runtime_error("Failed to create poll file descriptor");
34   }
35 
36   memset(&device, 0, sizeof(device));
37 
38   device.common.tag = HARDWARE_DEVICE_TAG;
39   device.common.version = SENSORS_DEVICE_API_VERSION_1_0;
40   device.common.module = const_cast<hw_module_t*>(module);
41   device.common.close = CloseWrapper;
42   device.activate = ActivateWrapper;
43   device.setDelay = SetDelayWrapper;
44   device.poll = PollEventsWrapper;
45   device.batch = BatchWrapper;
46   device.flush = FlushWrapper;
47 
48   memset(sensors, 0, sizeof(Sensor *) * MAX_DEVICES);
49 }
50 
~SensorContext()51 SensorContext::~SensorContext() {
52   int rc;
53 
54   for (int i = 0; i < sensorsNum; i++) {
55     if (sensors[i]) {
56       delete sensors[i];
57       sensors[i] = nullptr;
58     }
59   }
60 
61   rc = close(pollFd);
62   if (rc != 0) {
63     ALOGE("Cannot close poll file descriptor");
64   }
65 }
66 
addSensorModule(struct sensor_t * sensorDesc,Sensor * (* sensorFactoryFunc)(int))67 int SensorContext::addSensorModule(struct sensor_t *sensorDesc,
68     Sensor * (*sensorFactoryFunc)(int)) {
69   android::Mutex::Autolock autolock(mutex);
70 
71   if ((sensorDesc == nullptr) || (sensorFactoryFunc == nullptr)) {
72     ALOGE("%s: cannot add a null sensor", __func__);
73     return -EINVAL;
74   }
75 
76   if (sensorsNum >= MAX_DEVICES) {
77     ALOGE("%s: Cannot add more than %d sensors.", __func__, MAX_DEVICES);
78     return -E2BIG;
79   }
80 
81   sensorDesc->handle = sensorsNum;
82   sensorDescs[sensorsNum] = *sensorDesc;
83   sensorFactoryFuncs[sensorsNum] = sensorFactoryFunc;
84   sensorsNum++;
85 
86   return 0;
87 }
88 
OpenWrapper(const struct hw_module_t * module,const char * id,struct hw_device_t ** device)89 int SensorContext::OpenWrapper(const struct hw_module_t *module,
90                         const char* id, struct hw_device_t **device) {
91   SensorContext *ctx;
92 
93   try {
94     ctx = new SensorContext(module);
95   } catch (const std::runtime_error& e) {
96     ALOGE("%s: Failed to open sensors hal. Error message: %s",
97         __func__, e.what());
98     return -1;
99   }
100 
101   *device = &ctx->device.common;
102 
103   return 0;
104 }
105 
GetSensorsListWrapper(struct sensors_module_t * module,struct sensor_t const ** list)106 int SensorContext::GetSensorsListWrapper(struct sensors_module_t *module,
107                             struct sensor_t const **list) {
108   android::Mutex::Autolock autolock(mutex);
109 
110   if (!list || (sensorsNum == 0)) {
111     return 0;
112   }
113 
114   *list = sensorDescs;
115   return sensorsNum;
116 }
117 
activate(int handle,int enabled)118 int SensorContext::activate(int handle, int enabled) {
119   int rc = 0;
120 
121   if (enabled != 0 && enabled != 1) {
122     ALOGE("%s: Invalid parameter", __func__);
123     return -EINVAL;
124   }
125 
126   if (handle < 0 || handle >= sensorsNum) {
127     return -EINVAL;
128   }
129 
130   try {
131     if (enabled) {
132       if (sensors[handle] == nullptr) {
133         sensors[handle] = sensorFactoryFuncs[handle](pollFd);
134         if (sensors[handle] == nullptr) {
135           return -1;
136         }
137         rc = sensors[handle]->activate(handle, enabled);
138         if (rc != 0) {
139           goto delete_sensor;
140         }
141       } else {
142         return 0;
143       }
144     } else {
145       if (sensors[handle] != nullptr) {
146         rc = sensors[handle]->activate(handle, enabled);
147         delete sensors[handle];
148         sensors[handle] = nullptr;
149       } else {
150         return 0;
151       }
152     }
153 
154     return rc;
155   } catch (const std::exception& e) {
156     /* The upper layer doesn't expect exceptions. Catch them all. */
157     ALOGE("%s: Failed to %s sensor %d. Error message: %s.",
158         __func__, enabled ? "activate" : "deactivate", handle, e.what());
159   }
160 
161 delete_sensor:
162   if (sensors[handle] != nullptr) {
163     delete sensors[handle];
164     sensors[handle] = nullptr;
165   }
166 
167   return -1;
168 }
169 
setDelay(int handle,int64_t ns)170 int SensorContext::setDelay(int handle, int64_t ns) {
171   if (handle < 0 || handle >= sensorsNum) {
172     return -EINVAL;
173   }
174 
175   if (sensors[handle] == nullptr) {
176     ALOGE("%s: cannot set delay. sensor %d is not activated", __func__, handle);
177     return -EINVAL;
178   }
179 
180   return sensors[handle]->setDelay(handle, ns);
181 }
182 
pollEvents(sensors_event_t * data,int count)183 int SensorContext::pollEvents(sensors_event_t *data, int count) {
184   int nfds, i;
185   struct epoll_event ev[MAX_DEVICES];
186   int returnedEvents = 0, sensorIndex = -1;
187 
188   /* return only when at least one event is available */
189   while(true) {
190     nfds = epoll_wait(pollFd, ev, MAX_DEVICES, -1);
191     if (nfds < 0) {
192       ALOGE("%s: epoll_wait returned an error: %d", __func__, errno);
193       return nfds;
194     }
195 
196     { // Autolock scope
197       android::Mutex::Autolock autolock(mutex);
198       for(i = 0; i < nfds && returnedEvents < count; i++) {
199         if (ev[i].events == EPOLLIN) {
200           sensorIndex = ev[i].data.u32;
201           if ((sensorIndex < 0) || (sensorIndex > sensorsNum)) {
202             ALOGE("%s: Invalid sensor index", __func__);
203             return -1;
204           }
205 
206           if (sensors[sensorIndex] == nullptr) {
207             /* The sensor might have been deactivated by another thread */
208             continue;
209           }
210 
211           /*
212           * The read operation might fail if the data is read by another
213           * pollEvents call executed by another thread.
214           */
215           if (sensors[sensorIndex]->readOneEvent(data + returnedEvents)) {
216             returnedEvents++;
217           }
218         }
219       }
220     } // Autolock scope
221 
222     if (returnedEvents > 0) {
223       return returnedEvents;
224     }
225   }
226 }
227 
batch(int handle,int flags,int64_t period_ns,int64_t timeout)228 int SensorContext::batch(int handle, int flags,
229                          int64_t period_ns, int64_t timeout) {
230   if (handle < 0 || handle >= sensorsNum) {
231     return -EINVAL;
232   }
233 
234   if (sensors[handle] == nullptr) {
235     ALOGE("%s: cannot set delay. sensor %d is not activated", __func__, handle);
236     return -EINVAL;
237   }
238 
239   return sensors[handle]->batch(handle, flags, period_ns, timeout);
240 }
241 
flush(int handle)242 int SensorContext::flush(int handle) {
243   if (handle < 0 || handle >= sensorsNum) {
244     return -EINVAL;
245   }
246 
247   if (sensors[handle] == nullptr) {
248     ALOGE("%s: cannot set delay. sensor %d is not activated", __func__, handle);
249     return -EINVAL;
250   }
251 
252   /* flush doesn't apply to one-shot sensors */
253   if (sensorDescs[handle].flags & SENSOR_FLAG_ONE_SHOT_MODE)
254     return -EINVAL;
255 
256   return sensors[handle]->flush(handle);
257 }
258 
CloseWrapper(hw_device_t * dev)259 int SensorContext::CloseWrapper(hw_device_t *dev) {
260   SensorContext *sensorContext = reinterpret_cast<SensorContext *>(dev);
261   android::Mutex::Autolock autolock(mutex);
262 
263   if (sensorContext != nullptr) {
264     delete sensorContext;
265   }
266 
267   return 0;
268 }
269 
ActivateWrapper(sensors_poll_device_t * dev,int handle,int enabled)270 int SensorContext::ActivateWrapper(sensors_poll_device_t *dev,
271                                    int handle, int enabled) {
272   android::Mutex::Autolock autolock(mutex);
273 
274   return reinterpret_cast<SensorContext *>(dev)->activate(handle, enabled);
275 }
276 
SetDelayWrapper(sensors_poll_device_t * dev,int handle,int64_t ns)277 int SensorContext::SetDelayWrapper(sensors_poll_device_t *dev,
278                                    int handle, int64_t ns) {
279   android::Mutex::Autolock autolock(mutex);
280 
281   return reinterpret_cast<SensorContext *>(dev)->setDelay(handle, ns);
282 }
283 
PollEventsWrapper(sensors_poll_device_t * dev,sensors_event_t * data,int count)284 int SensorContext::PollEventsWrapper(sensors_poll_device_t *dev,
285                                      sensors_event_t *data, int count) {
286   return reinterpret_cast<SensorContext *>(dev)->pollEvents(data, count);
287 }
288 
BatchWrapper(sensors_poll_device_1_t * dev,int handle,int flags,int64_t period_ns,int64_t timeout)289 int SensorContext::BatchWrapper(sensors_poll_device_1_t *dev, int handle,
290                                 int flags, int64_t period_ns, int64_t timeout) {
291   android::Mutex::Autolock autolock(mutex);
292 
293   return reinterpret_cast<SensorContext *>(dev)->batch(handle, flags, period_ns,
294                                                       timeout);
295 }
296 
FlushWrapper(sensors_poll_device_1_t * dev,int handle)297 int SensorContext::FlushWrapper(sensors_poll_device_1_t *dev,
298                                 int handle) {
299   android::Mutex::Autolock autolock(mutex);
300 
301   return reinterpret_cast<SensorContext *>(dev)->flush(handle);
302 }
303 
304 static struct hw_module_methods_t sensors_module_methods = {
305   .open = SensorContext::OpenWrapper,
306 };
307 
308 struct sensors_module_t HAL_MODULE_INFO_SYM = {
309     .common = {
310         .tag = HARDWARE_MODULE_TAG,
311         .version_major = 1,
312         .version_minor = 0,
313         .id = SENSORS_HARDWARE_MODULE_ID,
314         .name = "Edison Sensor HAL",
315         .author = "Intel",
316         .methods = &sensors_module_methods,
317         .dso = nullptr,
318         .reserved = {0},
319     },
320     .get_sensors_list = SensorContext::GetSensorsListWrapper,
321     .set_operation_mode = nullptr
322 };
323