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
24Sensor * (*SensorContext::sensorFactoryFuncs[MAX_DEVICES])(int);
25struct sensor_t SensorContext::sensorDescs[MAX_DEVICES];
26int SensorContext::sensorsNum = 0;
27android::Mutex SensorContext::mutex;
28
29SensorContext::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
51SensorContext::~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
67int 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
89int 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
106int 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
118int 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
161delete_sensor:
162  if (sensors[handle] != nullptr) {
163    delete sensors[handle];
164    sensors[handle] = nullptr;
165  }
166
167  return -1;
168}
169
170int 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
183int 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
228int 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
242int 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
259int 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
270int 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
277int 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
284int 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
289int 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
297int 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
304static struct hw_module_methods_t sensors_module_methods = {
305  .open = SensorContext::OpenWrapper,
306};
307
308struct 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