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