Home | History | Annotate | Download | only in sensorhal
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      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 #ifndef HUB_CONNECTION_H_
     18 
     19 #define HUB_CONNECTION_H_
     20 
     21 #include <sys/types.h>
     22 #include <sys/stat.h>
     23 #include <fcntl.h>
     24 #include <poll.h>
     25 
     26 #include <utils/Errors.h>
     27 #include <utils/Mutex.h>
     28 #include <utils/Thread.h>
     29 
     30 #include <list>
     31 
     32 #include "directchannel.h"
     33 #include "eventnums.h"
     34 #include "halIntf.h"
     35 #include "hubdefs.h"
     36 #include "ring.h"
     37 
     38 #include <unordered_map>
     39 
     40 #define WAKELOCK_NAME "sensorHal"
     41 
     42 #define ACCEL_BIAS_TAG     "accel"
     43 #define ACCEL_SW_BIAS_TAG  "accel_sw"
     44 #define GYRO_BIAS_TAG      "gyro"
     45 #define GYRO_OTC_DATA_TAG  "gyro_otc"
     46 #define GYRO_SW_BIAS_TAG   "gyro_sw"
     47 #define MAG_BIAS_TAG       "mag"
     48 
     49 #define MAX_ALTERNATES     2
     50 
     51 namespace android {
     52 
     53 struct HubConnection : public Thread {
     54     static HubConnection *getInstance();
     55 
     56     status_t initCheck() const;
     57 
     58     enum ProximitySensorType {
     59         PROXIMITY_UNKNOWN,
     60         PROXIMITY_ROHM,
     61         PROXIMITY_AMS,
     62     };
     63 
     64     // Blocks until it can return a status
     65     status_t getAliveCheck();
     66 
     67     virtual bool threadLoop();
     68 
     69     void queueActivate(int handle, bool enable);
     70     void queueSetDelay(int handle, nsecs_t delayNs);
     71     void queueBatch(int handle, nsecs_t sampling_period_ns,
     72             nsecs_t max_report_latency_ns);
     73     void queueFlush(int handle);
     74     void queueData(int handle, void *data, size_t length);
     75 
     76     void setOperationParameter(const additional_info_event_t &info);
     77 
     78     void releaseWakeLockIfAppropriate();
     79 
     80     //TODO: factor out event ring buffer functionality into a separate class
     81     ssize_t read(sensors_event_t *ev, size_t size);
     82     ssize_t write(const sensors_event_t *ev, size_t n);
     83 
     84     void saveSensorSettings() const;
     85 
     86     void setRawScale(float scaleAccel, float scaleMag) {
     87         mScaleAccel = scaleAccel;
     88         mScaleMag = scaleMag;
     89     }
     90 
     91     void setLeftyMode(bool enable);
     92 
     93 protected:
     94     HubConnection();
     95     virtual ~HubConnection();
     96 
     97     virtual void onFirstRef();
     98 
     99 private:
    100     typedef uint32_t rate_q10_t;  // q10 means lower 10 bits are for fractions
    101 
    102     bool mWakelockHeld;
    103     int32_t mWakeEventCount;
    104 
    105     void protectIfWakeEventLocked(int32_t sensor);
    106     ssize_t decrementIfWakeEventLocked(int32_t sensor);
    107 
    108     static inline uint64_t period_ns_to_frequency_q10(nsecs_t period_ns) {
    109         return 1024000000000ULL / period_ns;
    110     }
    111 
    112     static inline nsecs_t frequency_q10_to_period_ns(uint64_t frequency_q10) {
    113         if (frequency_q10)
    114             return 1024000000000LL / frequency_q10;
    115         else
    116             return (nsecs_t)0;
    117     }
    118 
    119     static inline uint64_t frequency_to_frequency_q10(float frequency) {
    120         return period_ns_to_frequency_q10(static_cast<nsecs_t>(1e9f/frequency));
    121     }
    122 
    123     enum
    124     {
    125         CONFIG_CMD_DISABLE      = 0,
    126         CONFIG_CMD_ENABLE       = 1,
    127         CONFIG_CMD_FLUSH        = 2,
    128         CONFIG_CMD_CFG_DATA     = 3,
    129         CONFIG_CMD_CALIBRATE    = 4,
    130     };
    131 
    132     struct ConfigCmd
    133     {
    134         uint32_t evtType;
    135         uint64_t latency;
    136         rate_q10_t rate;
    137         uint8_t sensorType;
    138         uint8_t cmd;
    139         uint16_t flags;
    140         uint8_t data[];
    141     } __attribute__((packed));
    142 
    143     struct MsgCmd
    144     {
    145         uint32_t evtType;
    146         struct HostHubRawPacket msg;
    147     } __attribute__((packed));
    148 
    149     struct LeftyState
    150     {
    151         bool accel; // Process wrist-aware accel samples as lefty mode
    152         bool gyro; // Process wrist-aware gyro samples as lefty mode
    153         bool hub; // Sensor hub is currently operating in lefty mode
    154     };
    155 
    156     struct Flush
    157     {
    158         int handle;
    159         uint8_t count;
    160 
    161         // Used to synchronize the transition in and out of
    162         // lefty mode between nanohub and the AP.
    163         bool internal;
    164     };
    165 
    166     struct SensorState {
    167         uint64_t latency;
    168         uint64_t lastTimestamp;
    169         uint64_t desiredTSample;
    170         rate_q10_t rate;
    171         uint8_t sensorType;
    172         uint8_t primary;
    173         uint8_t alt[MAX_ALTERNATES];
    174         bool enable;
    175     };
    176 
    177     struct FirstSample
    178     {
    179         uint8_t numSamples;
    180         uint8_t numFlushes;
    181         uint8_t highAccuracy : 1;
    182         uint8_t biasPresent : 1;
    183         uint8_t biasSample : 6;
    184         uint8_t pad;
    185     };
    186 
    187     struct RawThreeAxisSample
    188     {
    189         uint32_t deltaTime;
    190         int16_t ix, iy, iz;
    191     } __attribute__((packed));
    192 
    193     struct ThreeAxisSample
    194     {
    195         uint32_t deltaTime;
    196         float x, y, z;
    197     } __attribute__((packed));
    198 
    199     struct OneAxisSample
    200     {
    201         uint32_t deltaTime;
    202         union
    203         {
    204             float fdata;
    205             uint32_t idata;
    206         };
    207     } __attribute__((packed));
    208 
    209     // The following structure should match struct HostIntfDataBuffer found in
    210     // firmware/inc/hostIntf.h
    211     struct nAxisEvent
    212     {
    213         uint32_t evtType;
    214         union
    215         {
    216             struct
    217             {
    218                 uint64_t referenceTime;
    219                 union
    220                 {
    221                     struct FirstSample firstSample;
    222                     struct OneAxisSample oneSamples[];
    223                     struct RawThreeAxisSample rawThreeSamples[];
    224                     struct ThreeAxisSample threeSamples[];
    225                 };
    226             };
    227             uint8_t buffer[];
    228         };
    229     } __attribute__((packed));
    230 
    231     static Mutex sInstanceLock;
    232     static HubConnection *sInstance;
    233 
    234     // This lock is used for synchronization between the write thread (from
    235     // sensorservice) and the read thread polling from the nanohub driver.
    236     Mutex mLock;
    237 
    238     RingBuffer mRing;
    239     int32_t mWriteFailures;
    240 
    241     float mMagBias[3];
    242     uint8_t mMagAccuracy;
    243     uint8_t mMagAccuracyRestore;
    244 
    245     float mGyroBias[3], mAccelBias[3], mAccelEnabledBias[3];
    246     bool mAccelEnabledBiasStored;
    247     GyroOtcData mGyroOtcData;
    248 
    249     float mScaleAccel, mScaleMag;
    250 
    251     LeftyState mLefty;
    252 
    253     SensorState mSensorState[NUM_COMMS_SENSORS_PLUS_1];
    254     std::list<struct Flush> mFlushesPending[NUM_COMMS_SENSORS_PLUS_1];
    255 
    256     uint64_t mStepCounterOffset;
    257     uint64_t mLastStepCount;
    258 
    259     int mFd;
    260     int mInotifyPollIndex;
    261     struct pollfd mPollFds[4];
    262     int mNumPollFds;
    263 
    264     sensors_event_t *initEv(sensors_event_t *ev, uint64_t timestamp, uint32_t type, uint32_t sensor);
    265     uint8_t magAccuracyUpdate(sensors_vec_t *sv);
    266     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct OneAxisSample *sample, bool highAccuracy);
    267     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct RawThreeAxisSample *sample, bool highAccuracy);
    268     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct ThreeAxisSample *sample, bool highAccuracy);
    269     void postOsLog(uint8_t *buf, ssize_t len);
    270     void processAppData(uint8_t *buf, ssize_t len);
    271     ssize_t processBuf(uint8_t *buf, size_t len);
    272 
    273     inline bool isValidHandle(int handle) {
    274         return handle >= 0
    275             && handle < NUM_COMMS_SENSORS_PLUS_1
    276             && mSensorState[handle].sensorType;
    277     }
    278 
    279     ssize_t sendCmd(const void *buf, size_t count);
    280     void initConfigCmd(struct ConfigCmd *cmd, int handle);
    281 
    282     void queueFlushInternal(int handle, bool internal);
    283 
    284     void queueDataInternal(int handle, void *data, size_t length);
    285 
    286     void discardInotifyEvent();
    287     void waitOnNanohubLock();
    288 
    289     void initNanohubLock();
    290 
    291     void restoreSensorState();
    292     void sendCalibrationOffsets();
    293 
    294     // Enable SCHED_FIFO priority for main thread
    295     void enableSchedFifoMode();
    296 
    297 #ifdef LID_STATE_REPORTING_ENABLED
    298     int mUinputFd;
    299 
    300     status_t initializeUinputNode();
    301     void sendFolioEvent(int32_t data);
    302 #endif  // LID_STATE_REPORTING_ENABLED
    303 
    304 #ifdef USB_MAG_BIAS_REPORTING_ENABLED
    305     int mMagBiasPollIndex;
    306     float mUsbMagBias;
    307 
    308     void queueUsbMagBias();
    309 #endif  // USB_MAG_BIAS_REPORTING_ENABLED
    310 
    311 #ifdef DOUBLE_TOUCH_ENABLED
    312     int mDoubleTouchPollIndex;
    313 #endif  // DOUBLE_TOUCH_ENABLED
    314 
    315     // Direct report functions
    316 public:
    317     int addDirectChannel(const struct sensors_direct_mem_t *mem);
    318     int removeDirectChannel(int channel_handle);
    319     int configDirectReport(int sensor_handle, int channel_handle, int rate_level);
    320     bool isDirectReportSupported() const;
    321 private:
    322     void sendDirectReportEvent(const sensors_event_t *nev, size_t n);
    323     void mergeDirectReportRequest(struct ConfigCmd *cmd, int handle);
    324     bool isSampleIntervalSatisfied(int handle, uint64_t timestamp);
    325     void updateSampleRate(int handle, int reason);
    326 #ifdef DIRECT_REPORT_ENABLED
    327     int stopAllDirectReportOnChannel(
    328             int channel_handle, std::vector<int32_t> *unstoppedSensors);
    329     uint64_t rateLevelToDeviceSamplingPeriodNs(int handle, int rateLevel) const;
    330     inline static bool intervalLargeEnough(uint64_t actual, uint64_t desired) {
    331         return (actual + (actual >> 4)) >= desired; // >= 94.11% of desired
    332     }
    333 
    334     struct DirectChannelTimingInfo{
    335         uint64_t lastTimestamp;
    336         int rateLevel;
    337     };
    338     Mutex mDirectChannelLock;
    339     //sensor_handle=>(channel_handle => DirectChannelTimingInfo)
    340     std::unordered_map<int32_t,
    341             std::unordered_map<int32_t, DirectChannelTimingInfo> > mSensorToChannel;
    342     //channel_handle=>ptr of Channel obj
    343     std::unordered_map<int32_t, std::unique_ptr<DirectChannelBase>> mDirectChannel;
    344     int32_t mDirectChannelHandle;
    345 #endif
    346 
    347     DISALLOW_EVIL_CONSTRUCTORS(HubConnection);
    348 };
    349 
    350 }  // namespace android
    351 
    352 #endif  // HUB_CONNECTION_H_
    353