/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef CONTEXTHUB_H_ #define CONTEXTHUB_H_ #include "nanomessage.h" #include "noncopyable.h" #include <bitset> #include <functional> #include <vector> namespace android { class AppToHostEvent; class SensorEvent; // Array length helper macro #define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0])) enum class SensorType { Invalid_ = 0, // The order of this enum must correspond to sensor types in nanohub's // sensType.h Accel, AnyMotion, NoMotion, SignificantMotion, Flat, Gyro, GyroUncal, Magnetometer, MagnetometerUncal, Barometer, Temperature, AmbientLightSensor, Proximity, Orientation, HeartRateECG, HeartRatePPG, Gravity, LinearAccel, RotationVector, GeomagneticRotationVector, GameRotationVector, StepCount, StepDetect, Gesture, Tilt, DoubleTwist, DoubleTap, WindowOrientation, Hall, Activity, Vsync, CompressedAccel, WristTilt = 39, Max_ }; // Overloaded values of rate used in sensor enable request (see sensors.h) enum class SensorSpecialRate : uint32_t { None = 0, OnDemand = 0xFFFFFF00, OnChange = 0xFFFFFF01, OneShot = 0xFFFFFF02, }; struct SensorSpec { SensorType sensor_type = SensorType::Invalid_; // When enabling a sensor, rate can be specified in Hz or as one of the // special values SensorSpecialRate special_rate = SensorSpecialRate::None; float rate_hz = -1; uint64_t latency_ns = 0; // Reference value (ground truth) used for calibration bool have_cal_ref = false; float cal_ref; }; /* * An interface for communicating with a ContextHub. */ class ContextHub : public NonCopyable { public: virtual ~ContextHub() {}; static std::string SensorTypeToAbbrevName(SensorType sensor_type); static SensorType SensorAbbrevNameToType(const char *abbrev_name); static SensorType SensorAbbrevNameToType(const std::string& abbrev_name); static std::string ListAllSensorAbbrevNames(); /* * Performs initialization to allow commands to be sent to the context hub. * Must be called before any other functions that send commands. Returns * true on success, false on failure. */ virtual bool Initialize() = 0; /* * Configures the ContextHub to allow logs to be printed to stdout. */ virtual void SetLoggingEnabled(bool logging_enabled) = 0; /* * Loads a new firmware image to the ContextHub. The firmware image is * specified by filename. Returns false if an error occurs. */ bool Flash(const std::string& filename); /* * Performs the sensor calibration routine and writes the resulting data to * a file. */ bool CalibrateSensors(const std::vector<SensorSpec>& sensors); /* * Performs the sensor self-test routine. */ bool TestSensors(const std::vector<SensorSpec>& sensors); /* * Sends a sensor enable request to the context hub. */ bool EnableSensor(const SensorSpec& sensor); bool EnableSensors(const std::vector<SensorSpec>& sensors); /* * Sends a disable sensor request to context hub. Note that this always * results in sending a request, i.e. this does not check whether the sensor * is currently enabled or not. */ bool DisableSensor(SensorType sensor_type); bool DisableSensors(const std::vector<SensorSpec>& sensors); /* * Sends a disable sensor request for every sensor type we know about. */ bool DisableAllSensors(); /* * Calls DisableSensor() on all active sensors (i.e. those which have been * enabled but not yet disabled). This should be called from the destructor * of derived classes before tearing down communications to ensure we don't * leave sensors enabled after exiting. */ bool DisableActiveSensors(); /* * Sends all data stored in the calibration file to the context hub. */ virtual bool LoadCalibration(); /* * Prints up to <limit> incoming events. If limit is 0, then continues * indefinitely. */ void PrintAllEvents(unsigned int limit); /* * Requests bridge version information */ bool PrintBridgeVersion(); /* * Prints up to <sample_limit> incoming sensor samples corresponding to the * given SensorType, ignoring other events. If sample_limit is 0, then * continues indefinitely. */ void PrintSensorEvents(SensorType sensor_type, int sample_limit); void PrintSensorEvents(const std::vector<SensorSpec>& sensors, int sample_limit); protected: enum class TransportResult { Success, GeneralFailure, Timeout, ParseFailure, Canceled, // Add more specific error reasons as needed }; // Performs the calibration routine, but does not call SaveCalibration() bool CalibrateSingleSensor(const SensorSpec& sensor); // Performs the self-test routine bool TestSingleSensor(const SensorSpec& sensor); /* * Iterates over sensors, invoking the given callback on each element. * Returns true if all callbacks returned true. Exits early on failure. */ bool ForEachSensor(const std::vector<SensorSpec>& sensors, std::function<bool(const SensorSpec&)> callback); /* * Parses a calibration result event and invokes the appropriate * SetCalibration function with the calibration data. */ bool HandleCalibrationResult(const SensorSpec& sensor, const AppToHostEvent &event); /* * Parses a self-test result event */ bool HandleTestResult(const SensorSpec& sensor, const AppToHostEvent &event); /* * Same as ReadSensorEvents, but filters on AppToHostEvent instead of * SensorEvent. */ TransportResult ReadAppEvents(std::function<bool(const AppToHostEvent&)> callback, int timeout_ms = 0); /* * Calls ReadEvent in a loop, handling errors and ignoring events that * didn't originate from a sensor. Valid SensorEvents are passed to the * callback for further processing. The callback should return a boolean * indicating whether to continue (true) or exit the read loop (false). */ void ReadSensorEvents(std::function<bool(const SensorEvent&)> callback); /* * Sends the given calibration data down to the hub */ bool SendCalibrationData(SensorType sensor_type, const std::vector<uint8_t>& cal_data); /* * Read an event from the sensor hub. Block until a event is successfully * read, no event traffic is generated for the timeout period, or an error * occurs, such as a CRC check failure. */ virtual TransportResult ReadEvent(std::vector<uint8_t>& response, int timeout_ms) = 0; virtual TransportResult WriteEvent(const std::vector<uint8_t>& request) = 0; // Implements the firmware loading functionality for the sensor hub. Returns // false if an error occurs while writing the firmware to the device. virtual bool FlashSensorHub(const std::vector<uint8_t>& bytes) = 0; // Convenience functions that build on top of the more generic byte-level // interface TransportResult ReadEvent(std::unique_ptr<ReadEventResponse>* response, int timeout_ms = 0); TransportResult WriteEvent(const WriteEventRequest& request); // Override these if saving calibration data to persistent storage is // supported on the platform virtual bool SetCalibration(SensorType sensor_type, int32_t data); virtual bool SetCalibration(SensorType sensor_type, float data); virtual bool SetCalibration(SensorType sensor_type, int32_t x, int32_t y, int32_t z); virtual bool SetCalibration(SensorType sensor_type, int32_t x, int32_t y, int32_t z, int32_t w); virtual bool SaveCalibration(); private: std::bitset<static_cast<int>(SensorType::Max_)> sensor_is_active_; }; } // namespace android #endif // CONTEXTHUB_H_