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 "directchannel.h" 32 #include "eventnums.h" 33 #include "halIntf.h" 34 #include "hubdefs.h" 35 #include "ring.h" 36 37 #ifdef USE_SENSORSERVICE_TO_GET_FIFO 38 #include <thread> 39 #endif 40 #include <unordered_map> 41 42 #define WAKELOCK_NAME "sensorHal" 43 44 #define ACCEL_BIAS_TAG "accel" 45 #define ACCEL_SW_BIAS_TAG "accel_sw" 46 #define GYRO_BIAS_TAG "gyro" 47 #define GYRO_OTC_DATA_TAG "gyro_otc" 48 #define GYRO_SW_BIAS_TAG "gyro_sw" 49 #define MAG_BIAS_TAG "mag" 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 bool isWakeEvent(int32_t sensor); 79 void releaseWakeLockIfAppropriate(); 80 ssize_t getWakeEventCount(); 81 ssize_t decrementWakeEventCount(); 82 83 //TODO: factor out event ring buffer functionality into a separate class 84 ssize_t read(sensors_event_t *ev, size_t size); 85 ssize_t write(const sensors_event_t *ev, size_t n); 86 87 void setActivityCallback(ActivityEventHandler *eventHandler); 88 89 void saveSensorSettings() const; 90 setRawScaleHubConnection91 void setRawScale(float scaleAccel, float scaleMag) { 92 mScaleAccel = scaleAccel; 93 mScaleMag = scaleMag; 94 } 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 protectIfWakeEvent(int32_t sensor); 109 period_ns_to_frequency_q10HubConnection110 static inline uint64_t period_ns_to_frequency_q10(nsecs_t period_ns) { 111 return 1024000000000ULL / period_ns; 112 } 113 frequency_q10_to_period_nsHubConnection114 static inline nsecs_t frequency_q10_to_period_ns(uint64_t frequency_q10) { 115 if (frequency_q10) 116 return 1024000000000LL / frequency_q10; 117 else 118 return (nsecs_t)0; 119 } 120 frequency_to_frequency_q10HubConnection121 static inline uint64_t frequency_to_frequency_q10(float frequency) { 122 return period_ns_to_frequency_q10(static_cast<nsecs_t>(1e9f/frequency)); 123 } 124 125 enum 126 { 127 CONFIG_CMD_DISABLE = 0, 128 CONFIG_CMD_ENABLE = 1, 129 CONFIG_CMD_FLUSH = 2, 130 CONFIG_CMD_CFG_DATA = 3, 131 CONFIG_CMD_CALIBRATE = 4, 132 }; 133 134 struct ConfigCmd 135 { 136 uint32_t evtType; 137 uint64_t latency; 138 rate_q10_t rate; 139 uint8_t sensorType; 140 uint8_t cmd; 141 uint16_t flags; 142 uint8_t data[]; 143 } __attribute__((packed)); 144 145 struct MsgCmd 146 { 147 uint32_t evtType; 148 struct HostHubRawPacket msg; 149 } __attribute__((packed)); 150 151 struct SensorState { 152 uint64_t latency; 153 rate_q10_t rate; 154 uint8_t sensorType; 155 uint8_t alt; 156 uint8_t flushCnt; 157 bool enable; 158 }; 159 160 struct FirstSample 161 { 162 uint8_t numSamples; 163 uint8_t numFlushes; 164 uint8_t highAccuracy : 1; 165 uint8_t biasPresent : 1; 166 uint8_t biasSample : 6; 167 uint8_t pad; 168 }; 169 170 struct RawThreeAxisSample 171 { 172 uint32_t deltaTime; 173 int16_t ix, iy, iz; 174 } __attribute__((packed)); 175 176 struct ThreeAxisSample 177 { 178 uint32_t deltaTime; 179 float x, y, z; 180 } __attribute__((packed)); 181 182 struct OneAxisSample 183 { 184 uint32_t deltaTime; 185 union 186 { 187 float fdata; 188 uint32_t idata; 189 }; 190 } __attribute__((packed)); 191 192 // The following structure should match struct HostIntfDataBuffer found in 193 // firmware/inc/hostIntf.h 194 struct nAxisEvent 195 { 196 uint32_t evtType; 197 union 198 { 199 struct 200 { 201 uint64_t referenceTime; 202 union 203 { 204 struct FirstSample firstSample; 205 struct OneAxisSample oneSamples[]; 206 struct RawThreeAxisSample rawThreeSamples[]; 207 struct ThreeAxisSample threeSamples[]; 208 }; 209 }; 210 uint8_t buffer[]; 211 }; 212 } __attribute__((packed)); 213 214 static Mutex sInstanceLock; 215 static HubConnection *sInstance; 216 217 // This lock is used for synchronization between the write thread (from 218 // sensorservice) and the read thread polling from the nanohub driver. 219 Mutex mLock; 220 221 RingBuffer mRing; 222 223 ActivityEventHandler *mActivityEventHandler; 224 225 float mMagBias[3]; 226 uint8_t mMagAccuracy; 227 uint8_t mMagAccuracyRestore; 228 229 float mGyroBias[3], mAccelBias[3]; 230 GyroOtcData mGyroOtcData; 231 232 float mScaleAccel, mScaleMag; 233 234 SensorState mSensorState[NUM_COMMS_SENSORS_PLUS_1]; 235 236 uint64_t mStepCounterOffset; 237 uint64_t mLastStepCount; 238 239 int mFd; 240 int mInotifyPollIndex; 241 struct pollfd mPollFds[4]; 242 int mNumPollFds; 243 244 sensors_event_t *initEv(sensors_event_t *ev, uint64_t timestamp, uint32_t type, uint32_t sensor); 245 uint8_t magAccuracyUpdate(sensors_vec_t *sv); 246 void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct OneAxisSample *sample, bool highAccuracy); 247 void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct RawThreeAxisSample *sample, bool highAccuracy); 248 void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct ThreeAxisSample *sample, bool highAccuracy); 249 void postOsLog(uint8_t *buf, ssize_t len); 250 void processAppData(uint8_t *buf, ssize_t len); 251 ssize_t processBuf(uint8_t *buf, size_t len); 252 isValidHandleHubConnection253 inline bool isValidHandle(int handle) { 254 return handle >= 0 255 && handle < NUM_COMMS_SENSORS_PLUS_1 256 && mSensorState[handle].sensorType; 257 } 258 259 void initConfigCmd(struct ConfigCmd *cmd, int handle); 260 261 void queueDataInternal(int handle, void *data, size_t length); 262 263 void discardInotifyEvent(); 264 void waitOnNanohubLock(); 265 266 void initNanohubLock(); 267 268 void restoreSensorState(); 269 void sendCalibrationOffsets(); 270 271 #ifdef USE_SENSORSERVICE_TO_GET_FIFO 272 // Enable SCHED_FIFO priority for main thread 273 std::thread mEnableSchedFifoThread; 274 #endif 275 static void enableSchedFifoMode(sp<HubConnection> hub); 276 277 #ifdef LID_STATE_REPORTING_ENABLED 278 int mUinputFd; 279 280 status_t initializeUinputNode(); 281 void sendFolioEvent(int32_t data); 282 #endif // LID_STATE_REPORTING_ENABLED 283 284 #ifdef USB_MAG_BIAS_REPORTING_ENABLED 285 int mMagBiasPollIndex; 286 float mUsbMagBias; 287 288 void queueUsbMagBias(); 289 #endif // USB_MAG_BIAS_REPORTING_ENABLED 290 291 #ifdef DOUBLE_TOUCH_ENABLED 292 int mDoubleTouchPollIndex; 293 #endif // DOUBLE_TOUCH_ENABLED 294 295 // Direct report functions 296 public: 297 int addDirectChannel(const struct sensors_direct_mem_t *mem); 298 int removeDirectChannel(int channel_handle); 299 int configDirectReport(int sensor_handle, int channel_handle, int rate_level); 300 bool isDirectReportSupported() const; 301 private: 302 void sendDirectReportEvent(const sensors_event_t *nev, size_t n); 303 void mergeDirectReportRequest(struct ConfigCmd *cmd, int handle); 304 #ifdef DIRECT_REPORT_ENABLED 305 int stopAllDirectReportOnChannel( 306 int channel_handle, std::vector<int32_t> *unstoppedSensors); 307 Mutex mDirectChannelLock; 308 //sensor_handle=>(channel_handle, rate_level) 309 std::unordered_map<int32_t, std::unordered_map<int32_t, int32_t> > mSensorToChannel; 310 //channel_handle=>ptr of Channel obj 311 std::unordered_map<int32_t, std::unique_ptr<DirectChannelBase>> mDirectChannel; 312 int32_t mDirectChannelHandle; 313 #endif 314 315 DISALLOW_EVIL_CONSTRUCTORS(HubConnection); 316 }; 317 318 } // namespace android 319 320 #endif // HUB_CONNECTION_H_ 321