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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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