Home | History | Annotate | Download | only in nanotool
      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