Home | History | Annotate | Download | only in mraa
      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