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