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