1 /* 2 * Copyright (C) 2016 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 CONTEXTHUB_H_ 18 #define CONTEXTHUB_H_ 19 20 #include "nanomessage.h" 21 #include "noncopyable.h" 22 23 #include <bitset> 24 #include <functional> 25 #include <vector> 26 27 namespace android { 28 29 class AppToHostEvent; 30 class SensorEvent; 31 32 // Array length helper macro 33 #define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0])) 34 35 enum class SensorType { 36 Invalid_ = 0, 37 38 // The order of this enum must correspond to sensor types in nanohub's 39 // sensType.h 40 Accel, 41 AnyMotion, 42 NoMotion, 43 SignificantMotion, 44 Flat, 45 Gyro, 46 GyroUncal, 47 Magnetometer, 48 MagnetometerUncal, 49 Barometer, 50 Temperature, 51 AmbientLightSensor, 52 Proximity, 53 Orientation, 54 HeartRateECG, 55 HeartRatePPG, 56 Gravity, 57 LinearAccel, 58 RotationVector, 59 GeomagneticRotationVector, 60 GameRotationVector, 61 StepCount, 62 StepDetect, 63 Gesture, 64 Tilt, 65 DoubleTwist, 66 DoubleTap, 67 WindowOrientation, 68 Hall, 69 Activity, 70 Vsync, 71 CompressedAccel, 72 73 Max_ 74 }; 75 76 // Overloaded values of rate used in sensor enable request (see sensors.h) 77 enum class SensorSpecialRate : uint32_t { 78 None = 0, 79 OnDemand = 0xFFFFFF00, 80 OnChange = 0xFFFFFF01, 81 OneShot = 0xFFFFFF02, 82 }; 83 84 struct SensorSpec { 85 SensorType sensor_type = SensorType::Invalid_; 86 87 // When enabling a sensor, rate can be specified in Hz or as one of the 88 // special values 89 SensorSpecialRate special_rate = SensorSpecialRate::None; 90 float rate_hz = -1; 91 uint64_t latency_ns = 0; 92 93 // Reference value (ground truth) used for calibration 94 bool have_cal_ref = false; 95 float cal_ref; 96 }; 97 98 /* 99 * An interface for communicating with a ContextHub. 100 */ 101 class ContextHub : public NonCopyable { 102 public: 103 virtual ~ContextHub() {}; 104 105 static std::string SensorTypeToAbbrevName(SensorType sensor_type); 106 static SensorType SensorAbbrevNameToType(const char *abbrev_name); 107 static SensorType SensorAbbrevNameToType(const std::string& abbrev_name); 108 static std::string ListAllSensorAbbrevNames(); 109 110 /* 111 * Performs initialization to allow commands to be sent to the context hub. 112 * Must be called before any other functions that send commands. Returns 113 * true on success, false on failure. 114 */ 115 virtual bool Initialize() = 0; 116 117 /* 118 * Configures the ContextHub to allow logs to be printed to stdout. 119 */ 120 virtual void SetLoggingEnabled(bool logging_enabled) = 0; 121 122 /* 123 * Loads a new firmware image to the ContextHub. The firmware image is 124 * specified by filename. Returns false if an error occurs. 125 */ 126 bool Flash(const std::string& filename); 127 128 /* 129 * Performs the sensor calibration routine and writes the resulting data to 130 * a file. 131 */ 132 bool CalibrateSensors(const std::vector<SensorSpec>& sensors); 133 134 /* 135 * Sends a sensor enable request to the context hub. 136 */ 137 bool EnableSensor(const SensorSpec& sensor); 138 bool EnableSensors(const std::vector<SensorSpec>& sensors); 139 140 /* 141 * Sends a disable sensor request to context hub. Note that this always 142 * results in sending a request, i.e. this does not check whether the sensor 143 * is currently enabled or not. 144 */ 145 bool DisableSensor(SensorType sensor_type); 146 bool DisableSensors(const std::vector<SensorSpec>& sensors); 147 148 /* 149 * Sends a disable sensor request for every sensor type we know about. 150 */ 151 bool DisableAllSensors(); 152 153 /* 154 * Calls DisableSensor() on all active sensors (i.e. those which have been 155 * enabled but not yet disabled). This should be called from the destructor 156 * of derived classes before tearing down communications to ensure we don't 157 * leave sensors enabled after exiting. 158 */ 159 bool DisableActiveSensors(); 160 161 /* 162 * Sends all data stored in the calibration file to the context hub. 163 */ 164 virtual bool LoadCalibration(); 165 166 /* 167 * Prints up to <limit> incoming events. If limit is 0, then continues 168 * indefinitely. 169 */ 170 void PrintAllEvents(unsigned int limit); 171 172 /* 173 * Prints up to <sample_limit> incoming sensor samples corresponding to the 174 * given SensorType, ignoring other events. If sample_limit is 0, then 175 * continues indefinitely. 176 */ 177 void PrintSensorEvents(SensorType sensor_type, int sample_limit); 178 void PrintSensorEvents(const std::vector<SensorSpec>& sensors, 179 int sample_limit); 180 181 protected: 182 enum class TransportResult { 183 Success, 184 GeneralFailure, 185 Timeout, 186 ParseFailure, 187 Canceled, 188 // Add more specific error reasons as needed 189 }; 190 191 // Performs the calibration routine, but does not call SaveCalibration() 192 bool CalibrateSingleSensor(const SensorSpec& sensor); 193 194 /* 195 * Iterates over sensors, invoking the given callback on each element. 196 * Returns true if all callbacks returned true. Exits early on failure. 197 */ 198 bool ForEachSensor(const std::vector<SensorSpec>& sensors, 199 std::function<bool(const SensorSpec&)> callback); 200 201 /* 202 * Parses a calibration result event and invokes the appropriate 203 * SetCalibration function with the calibration data. 204 */ 205 bool HandleCalibrationResult(const SensorSpec& sensor, 206 const AppToHostEvent &event); 207 208 /* 209 * Same as ReadSensorEvents, but filters on AppToHostEvent instead of 210 * SensorEvent. 211 */ 212 TransportResult ReadAppEvents(std::function<bool(const AppToHostEvent&)> callback, 213 int timeout_ms = 0); 214 215 /* 216 * Calls ReadEvent in a loop, handling errors and ignoring events that 217 * didn't originate from a sensor. Valid SensorEvents are passed to the 218 * callback for further processing. The callback should return a boolean 219 * indicating whether to continue (true) or exit the read loop (false). 220 */ 221 void ReadSensorEvents(std::function<bool(const SensorEvent&)> callback); 222 223 /* 224 * Sends the given calibration data down to the hub 225 */ 226 bool SendCalibrationData(SensorType sensor_type, 227 const std::vector<uint8_t>& cal_data); 228 229 /* 230 * Read an event from the sensor hub. Block until a event is successfully 231 * read, no event traffic is generated for the timeout period, or an error 232 * occurs, such as a CRC check failure. 233 */ 234 virtual TransportResult ReadEvent(std::vector<uint8_t>& response, 235 int timeout_ms) = 0; 236 virtual TransportResult WriteEvent(const std::vector<uint8_t>& request) = 0; 237 238 // Implements the firmware loading functionality for the sensor hub. Returns 239 // false if an error occurs while writing the firmware to the device. 240 virtual bool FlashSensorHub(const std::vector<uint8_t>& bytes) = 0; 241 242 // Convenience functions that build on top of the more generic byte-level 243 // interface 244 TransportResult ReadEvent(std::unique_ptr<ReadEventResponse>* response, 245 int timeout_ms = 0); 246 TransportResult WriteEvent(const WriteEventRequest& request); 247 248 // Override these if saving calibration data to persistent storage is 249 // supported on the platform 250 virtual bool SetCalibration(SensorType sensor_type, int32_t data); 251 virtual bool SetCalibration(SensorType sensor_type, float data); 252 virtual bool SetCalibration(SensorType sensor_type, int32_t x, 253 int32_t y, int32_t z); 254 virtual bool SetCalibration(SensorType sensor_type, int32_t x, 255 int32_t y, int32_t z, int32_t w); 256 virtual bool SaveCalibration(); 257 258 private: 259 std::bitset<static_cast<int>(SensorType::Max_)> sensor_is_active_; 260 }; 261 262 } // namespace android 263 264 #endif // CONTEXTHUB_H_ 265