• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "activityeventhandler.h"
31 #include "eventnums.h"
32 #include "hubdefs.h"
33 #include "ring.h"
34 
35 namespace android {
36 
37 struct HubConnection : public Thread {
38     static HubConnection *getInstance();
39 
40     status_t initCheck() const;
41 
42     enum ProximitySensorType {
43         PROXIMITY_UNKNOWN,
44         PROXIMITY_ROHM,
45         PROXIMITY_AMS,
46     };
47 
48     // Blocks until it can return a status
49     status_t getAliveCheck();
50 
51     virtual bool threadLoop();
52 
53     void queueActivate(int handle, bool enable);
54     void queueSetDelay(int handle, nsecs_t delayNs);
55     void queueBatch(int handle, nsecs_t sampling_period_ns,
56             nsecs_t max_report_latency_ns);
57     void queueFlush(int handle);
58     void queueData(int handle, void *data, size_t length);
59 
60     ssize_t read(sensors_event_t *ev, size_t size);
61 
62     void setActivityCallback(ActivityEventHandler *eventHandler);
63 
64     void saveSensorSettings() const;
65 
66 protected:
67     HubConnection();
68     virtual ~HubConnection();
69 
70     virtual void onFirstRef();
71 
72 private:
73     typedef uint32_t rate_q10_t;  // q10 means lower 10 bits are for fractions
74 
period_ns_to_frequency_q10HubConnection75     static inline uint64_t period_ns_to_frequency_q10(nsecs_t period_ns) {
76         return 1024000000000ULL / period_ns;
77     }
78 
frequency_q10_to_period_nsHubConnection79     static inline nsecs_t frequency_q10_to_period_ns(uint64_t frequency_q10) {
80         if (frequency_q10)
81             return 1024000000000LL / frequency_q10;
82         else
83             return (nsecs_t)0;
84     }
85 
86     enum
87     {
88         CONFIG_CMD_DISABLE      = 0,
89         CONFIG_CMD_ENABLE       = 1,
90         CONFIG_CMD_FLUSH        = 2,
91         CONFIG_CMD_CFG_DATA     = 3,
92         CONFIG_CMD_CALIBRATE    = 4,
93     };
94 
95     struct ConfigCmd
96     {
97         uint32_t evtType;
98         uint64_t latency;
99         rate_q10_t rate;
100         uint8_t sensorType;
101         uint8_t cmd;
102         uint16_t flags;
103         uint8_t data[];
104     } __attribute__((packed));
105 
106     struct MsgCmd
107     {
108         uint32_t evtType;
109         struct HostHubRawPacket msg;
110     } __attribute__((packed));
111 
112     struct SensorState {
113         uint64_t latency;
114         rate_q10_t rate;
115         uint8_t sensorType;
116         uint8_t alt;
117         uint8_t flushCnt;
118         bool enable;
119     };
120 
121     struct FirstSample
122     {
123         uint8_t numSamples;
124         uint8_t numFlushes;
125         uint8_t highAccuracy : 1;
126         uint8_t biasPresent : 1;
127         uint8_t biasSample : 6;
128         uint8_t pad;
129     };
130 
131     struct RawThreeAxisSample
132     {
133         uint32_t deltaTime;
134         int16_t ix, iy, iz;
135     } __attribute__((packed));
136 
137     struct ThreeAxisSample
138     {
139         uint32_t deltaTime;
140         float x, y, z;
141     } __attribute__((packed));
142 
143     struct OneAxisSample
144     {
145         uint32_t deltaTime;
146         union
147         {
148             float fdata;
149             uint32_t idata;
150         };
151     } __attribute__((packed));
152 
153     // The following structure should match struct HostIntfDataBuffer found in
154     // firmware/inc/hostIntf.h
155     struct nAxisEvent
156     {
157         uint32_t evtType;
158         union
159         {
160             struct
161             {
162                 uint64_t referenceTime;
163                 union
164                 {
165                     struct FirstSample firstSample;
166                     struct OneAxisSample oneSamples[];
167                     struct RawThreeAxisSample rawThreeSamples[];
168                     struct ThreeAxisSample threeSamples[];
169                 };
170             };
171             uint8_t buffer[];
172         };
173     } __attribute__((packed));
174 
175     static Mutex sInstanceLock;
176     static HubConnection *sInstance;
177 
178     // This lock is used for synchronization between the write thread (from
179     // sensorservice) and the read thread polling from the nanohub driver.
180     Mutex mLock;
181 
182     RingBuffer mRing;
183 
184     ActivityEventHandler *mActivityEventHandler;
185 
186     float mMagBias[3];
187     uint8_t mMagAccuracy;
188     uint8_t mMagAccuracyRestore;
189 
190     float mGyroBias[3], mAccelBias[3];
191 
192     SensorState mSensorState[NUM_COMMS_SENSORS_PLUS_1];
193 
194     uint64_t mStepCounterOffset;
195     uint64_t mLastStepCount;
196 
197     int mFd;
198     int mInotifyPollIndex;
199     struct pollfd mPollFds[4];
200     int mNumPollFds;
201 
202     sensors_event_t *initEv(sensors_event_t *ev, uint64_t timestamp, uint32_t type, uint32_t sensor);
203     void magAccuracyUpdate(float x, float y, float z);
204     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct OneAxisSample *sample, bool highAccuracy);
205     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct RawThreeAxisSample *sample, bool highAccuracy);
206     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct ThreeAxisSample *sample, bool highAccuracy);
207     void postOsLog(uint8_t *buf, ssize_t len);
208     ssize_t processBuf(uint8_t *buf, size_t len);
209 
210     void initConfigCmd(struct ConfigCmd *cmd, int handle);
211 
212     void queueDataInternal(int handle, void *data, size_t length);
213 
214     void discardInotifyEvent();
215     void waitOnNanohubLock();
216 
217     void initNanohubLock();
218 
219     void restoreSensorState();
220     void sendCalibrationOffsets();
221 
222     // Enable SCHED_FIFO priority for main thread
223     void enableSchedFifoMode();
224 
225 #ifdef LID_STATE_REPORTING_ENABLED
226     int mUinputFd;
227 
228     status_t initializeUinputNode();
229     void sendFolioEvent(int32_t data);
230 #endif  // LID_STATE_REPORTING_ENABLED
231 
232 #ifdef USB_MAG_BIAS_REPORTING_ENABLED
233     int mMagBiasPollIndex;
234     float mUsbMagBias;
235 
236     void queueUsbMagBias();
237 #endif  // USB_MAG_BIAS_REPORTING_ENABLED
238 
239 #ifdef DOUBLE_TOUCH_ENABLED
240     int mDoubleTouchPollIndex;
241 #endif  // DOUBLE_TOUCH_ENABLED
242 
243     DISALLOW_EVIL_CONSTRUCTORS(HubConnection);
244 };
245 
246 }  // namespace android
247 
248 #endif  // HUB_CONNECTION_H_
249