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