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     WristTilt = 39,
     73     Humidity = 61,
     74 
     75     Max_
     76 };
     77 
     78 // Overloaded values of rate used in sensor enable request (see sensors.h)
     79 enum class SensorSpecialRate : uint32_t {
     80     None     = 0,
     81     OnDemand = 0xFFFFFF00,
     82     OnChange = 0xFFFFFF01,
     83     OneShot  = 0xFFFFFF02,
     84 };
     85 
     86 struct SensorSpec {
     87     SensorType sensor_type = SensorType::Invalid_;
     88 
     89     // When enabling a sensor, rate can be specified in Hz or as one of the
     90     // special values
     91     SensorSpecialRate special_rate = SensorSpecialRate::None;
     92     float rate_hz = -1;
     93     uint64_t latency_ns = 0;
     94 
     95     // Reference value (ground truth) used for calibration
     96     bool have_cal_ref = false;
     97     float cal_ref;
     98 };
     99 
    100 /*
    101  * An interface for communicating with a ContextHub.
    102  */
    103 class ContextHub : public NonCopyable {
    104   public:
    105     virtual ~ContextHub() {};
    106 
    107     static std::string SensorTypeToAbbrevName(SensorType sensor_type);
    108     static SensorType SensorAbbrevNameToType(const char *abbrev_name);
    109     static SensorType SensorAbbrevNameToType(const std::string& abbrev_name);
    110     static std::string ListAllSensorAbbrevNames();
    111 
    112     /*
    113      * Performs initialization to allow commands to be sent to the context hub.
    114      * Must be called before any other functions that send commands. Returns
    115      * true on success, false on failure.
    116      */
    117     virtual bool Initialize() = 0;
    118 
    119     /*
    120      * Configures the ContextHub to allow logs to be printed to stdout.
    121      */
    122     virtual void SetLoggingEnabled(bool logging_enabled) = 0;
    123 
    124     /*
    125      * Loads a new firmware image to the ContextHub. The firmware image is
    126      * specified by filename. Returns false if an error occurs.
    127      */
    128     bool Flash(const std::string& filename);
    129 
    130     /*
    131      * Performs the sensor calibration routine and writes the resulting data to
    132      * a file.
    133      */
    134     bool CalibrateSensors(const std::vector<SensorSpec>& sensors);
    135 
    136     /*
    137      * Performs the sensor self-test routine.
    138      */
    139     bool TestSensors(const std::vector<SensorSpec>& sensors);
    140 
    141     /*
    142      * Sends a sensor enable request to the context hub.
    143      */
    144     bool EnableSensor(const SensorSpec& sensor);
    145     bool EnableSensors(const std::vector<SensorSpec>& sensors);
    146 
    147     /*
    148      * Sends a disable sensor request to context hub. Note that this always
    149      * results in sending a request, i.e. this does not check whether the sensor
    150      * is currently enabled or not.
    151      */
    152     bool DisableSensor(SensorType sensor_type);
    153     bool DisableSensors(const std::vector<SensorSpec>& sensors);
    154 
    155     /*
    156      * Sends a disable sensor request for every sensor type we know about.
    157      */
    158     bool DisableAllSensors();
    159 
    160     /*
    161      * Calls DisableSensor() on all active sensors (i.e. those which have been
    162      * enabled but not yet disabled). This should be called from the destructor
    163      * of derived classes before tearing down communications to ensure we don't
    164      * leave sensors enabled after exiting.
    165      */
    166     bool DisableActiveSensors();
    167 
    168     /*
    169      * Sends all data stored in the calibration file to the context hub.
    170      */
    171     virtual bool LoadCalibration();
    172 
    173     /*
    174      * Prints up to <limit> incoming events. If limit is 0, then continues
    175      * indefinitely.
    176      */
    177     void PrintAllEvents(unsigned int limit);
    178 
    179     /*
    180      * Requests bridge version information
    181      */
    182     bool PrintBridgeVersion();
    183 
    184     /*
    185      * Prints up to <sample_limit> incoming sensor samples corresponding to the
    186      * given SensorType, ignoring other events. If sample_limit is 0, then
    187      * continues indefinitely.
    188      */
    189     void PrintSensorEvents(SensorType sensor_type, int sample_limit);
    190     void PrintSensorEvents(const std::vector<SensorSpec>& sensors,
    191         int sample_limit);
    192 
    193   protected:
    194     enum class TransportResult {
    195         Success,
    196         GeneralFailure,
    197         Timeout,
    198         ParseFailure,
    199         Canceled,
    200         // Add more specific error reasons as needed
    201     };
    202 
    203     // Performs the calibration routine, but does not call SaveCalibration()
    204     bool CalibrateSingleSensor(const SensorSpec& sensor);
    205 
    206     // Performs the self-test routine
    207     bool TestSingleSensor(const SensorSpec& sensor);
    208 
    209     /*
    210      * Iterates over sensors, invoking the given callback on each element.
    211      * Returns true if all callbacks returned true. Exits early on failure.
    212      */
    213     bool ForEachSensor(const std::vector<SensorSpec>& sensors,
    214         std::function<bool(const SensorSpec&)> callback);
    215 
    216     /*
    217      * Parses a calibration result event and invokes the appropriate
    218      * SetCalibration function with the calibration data.
    219      */
    220     bool HandleCalibrationResult(const SensorSpec& sensor,
    221         const AppToHostEvent &event);
    222 
    223     /*
    224      * Parses a self-test result event
    225      */
    226     bool HandleTestResult(const SensorSpec& sensor,
    227         const AppToHostEvent &event);
    228 
    229     /*
    230      * Same as ReadSensorEvents, but filters on AppToHostEvent instead of
    231      * SensorEvent.
    232      */
    233     TransportResult ReadAppEvents(std::function<bool(const AppToHostEvent&)> callback,
    234         int timeout_ms = 0);
    235 
    236     /*
    237      * Calls ReadEvent in a loop, handling errors and ignoring events that
    238      * didn't originate from a sensor. Valid SensorEvents are passed to the
    239      * callback for further processing. The callback should return a boolean
    240      * indicating whether to continue (true) or exit the read loop (false).
    241      */
    242     void ReadSensorEvents(std::function<bool(const SensorEvent&)> callback);
    243 
    244     /*
    245      * Sends the given calibration data down to the hub
    246      */
    247     bool SendCalibrationData(SensorType sensor_type,
    248         const std::vector<uint8_t>& cal_data);
    249 
    250     /*
    251      * Read an event from the sensor hub. Block until a event is successfully
    252      * read, no event traffic is generated for the timeout period, or an error
    253      * occurs, such as a CRC check failure.
    254      */
    255     virtual TransportResult ReadEvent(std::vector<uint8_t>& response,
    256         int timeout_ms) = 0;
    257     virtual TransportResult WriteEvent(const std::vector<uint8_t>& request) = 0;
    258 
    259     // Implements the firmware loading functionality for the sensor hub. Returns
    260     // false if an error occurs while writing the firmware to the device.
    261     virtual bool FlashSensorHub(const std::vector<uint8_t>& bytes) = 0;
    262 
    263     // Convenience functions that build on top of the more generic byte-level
    264     // interface
    265     TransportResult ReadEvent(std::unique_ptr<ReadEventResponse>* response,
    266         int timeout_ms = 0);
    267     TransportResult WriteEvent(const WriteEventRequest& request);
    268 
    269     // Override these if saving calibration data to persistent storage is
    270     // supported on the platform
    271     virtual bool SetCalibration(SensorType sensor_type, int32_t data);
    272     virtual bool SetCalibration(SensorType sensor_type, float data);
    273     virtual bool SetCalibration(SensorType sensor_type, int32_t x,
    274         int32_t y, int32_t z);
    275     virtual bool SetCalibration(SensorType sensor_type, int32_t x,
    276         int32_t y, int32_t z, int32_t w);
    277     virtual bool SaveCalibration();
    278 
    279 private:
    280     std::bitset<static_cast<int>(SensorType::Max_)> sensor_is_active_;
    281 };
    282 
    283 }  // namespace android
    284 
    285 #endif  // CONTEXTHUB_H_
    286