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 <cutils/log.h>
     18 #include <hardware/sensors.h>
     19 #include <errno.h>
     20 #include "Sensor.hpp"
     21 
     22 /* maximum delay: 1000ms */
     23 const int64_t kMaxDelay = 1000000000;
     24 /* Gravitational acceleration constant in m/s^2 */
     25 const float Sensor::kGravitationalAcceleration = 9.81f;
     26 
     27 Sensor::Sensor() : acquisitionThread(nullptr), handle(-1), type(-1), delay(kMaxDelay) {}
     28 
     29 Sensor::~Sensor() {
     30   if (acquisitionThread != nullptr) {
     31     delete acquisitionThread;
     32     acquisitionThread = nullptr;
     33   }
     34 }
     35 
     36 int Sensor::activate(int handle, int enabled) { return 0; }
     37 
     38 bool Sensor::readOneEvent(sensors_event_t *event) {
     39   int bytes_read = 0, bytes_to_read = sizeof(sensors_event_t);
     40   int fd = -1;
     41   char *ptr = (char *)event;
     42 
     43   if (acquisitionThread == nullptr) {
     44     ALOGE("%s: sensor %d doesn't have an acquisition thread", __func__, handle);
     45     return false;
     46   }
     47 
     48   /* read one event from the pipe read endpoint */
     49   fd = acquisitionThread->getReadPipeFd();
     50   do {
     51     bytes_read = read(fd, ptr, bytes_to_read);
     52     if (bytes_read <= 0) {
     53       break;
     54     }
     55     bytes_to_read -= bytes_read;
     56     ptr += bytes_read;
     57   } while (bytes_to_read > 0);
     58 
     59   if (bytes_to_read != 0) {
     60     return false;
     61   }
     62 
     63   return true;
     64 }
     65 
     66 int Sensor::activateAcquisitionThread(int pollFd, int handle, int enabled) {
     67   if (enabled) {
     68     /* create/init acquisition thread if necessary */
     69     if (acquisitionThread == nullptr) {
     70       acquisitionThread = new AcquisitionThread(pollFd, this);
     71       if (!acquisitionThread->init()) {
     72         ALOGE("%s: Cannot initialize acquisition thread for sensor %d",
     73             __func__, handle);
     74         delete acquisitionThread;
     75         acquisitionThread = nullptr;
     76         return -1;
     77       }
     78     } else {
     79       ALOGE("%s: Sensor %d is already enabled", __func__, handle);
     80     }
     81   } else {
     82     /* free acquisition thread resources */
     83     if (acquisitionThread != nullptr) {
     84       delete acquisitionThread;
     85       acquisitionThread = nullptr;
     86     } else {
     87       ALOGE("%s: Sensor %d is already disabled", __func__, handle);
     88     }
     89   }
     90   return 0;
     91 }
     92 
     93 int Sensor::setDelay(int handle, int64_t requestedDelay) {
     94   if (requestedDelay < 0) {
     95     return -EINVAL;
     96   }
     97 
     98   if (requestedDelay > kMaxDelay) {
     99     requestedDelay = kMaxDelay;
    100   }
    101 
    102   this->delay = requestedDelay;
    103   /* wake up thread to immediately change the delay */
    104   if (acquisitionThread != nullptr) {
    105     return acquisitionThread->wakeup();
    106   }
    107 
    108   return 0;
    109 }
    110 
    111 int Sensor::batch(int handle, int flags,
    112                       int64_t period_ns, int64_t timeout) {
    113   /* batching mode is not supported; call setDelay */
    114   return setDelay(handle, period_ns);
    115 }
    116 
    117 int Sensor::flush(int handle) {
    118   if (acquisitionThread == nullptr) {
    119     return -EINVAL;
    120   }
    121 
    122   /* batching mode is not supported; generate META_DATA_FLUSH_COMPLETE */
    123   if (acquisitionThread->generateFlushCompleteEvent()) {
    124     return 0;
    125   }
    126 
    127   return -1;
    128 }
    129