• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~ContextHub()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