1 /*
2  * Copyright (C) 2018 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 CHRE_PLATFORM_SLPI_SEE_SEE_CAL_HELPER_H_
18 #define CHRE_PLATFORM_SLPI_SEE_SEE_CAL_HELPER_H_
19 
20 extern "C" {
21 
22 #include "sns_client.h"
23 
24 }  // extern "C"
25 
26 #include "sns_suid.pb.h"
27 
28 #include "chre/core/sensor_type.h"
29 #include "chre/platform/mutex.h"
30 #include "chre/util/non_copyable.h"
31 #include "chre/util/optional.h"
32 
33 namespace chre {
34 
35 class SeeHelper;
36 
37 /**
38  * Helps manage and apply sensor calibration data provided through SEE.
39  */
40 class SeeCalHelper : public NonCopyable {
41  public:
42   /**
43    * Applies cached calibration (if any) to raw 3-axis sensor readings.
44    * Thread-safe.
45    *
46    * @param sensorType Type of sensor that generated the sample
47    * @param input 3-axis raw sample {x,y,z}
48    * @param output Location to store sample with calibration applied (can be
49    *               same as input)
50    */
51   void applyCalibration(uint8_t sensorType, const float input[3],
52                         float output[3]) const;
53 
54   /**
55    * Returns the cached calibration data. If the calibration data is available,
56    * this method will store all fields in the provided chreSensorThreeAxisData
57    * pointer, where the sample count is one. Thread-safe.
58    *
59    * @param sensorType Type of sensor to retrieve calibration data from, should
60    *                   be the type of a runtime-calibrated sensor
61    * @param biasData A non-null pointer to store the calibration data, not used
62    *                 if the calibration data is not available
63    *
64    * @return true if calibration data is successfully stored, false otherwise
65    */
66   bool getBias(uint8_t sensorType,
67                struct chreSensorThreeAxisData *biasData) const;
68 
69   /**
70    * @return Whether calibration updates are enabled for the given SUID.
71    */
72   bool areCalUpdatesEnabled(const sns_std_suid &suid) const;
73 
74   /**
75    * Configures calibration updates for the given SUID.
76    *
77    * If enabled, the SeeHelper instance should then pass decoded calibration
78    * data to updateCalibration() and use applyCalibration() as needed.
79    *
80    * @param suid The cached SUID of a calibration sensor
81    * @param enable Whether to enable or disable updates
82    * @param helper SeeHelper used to configure updates
83    * @return true if updates were successfully configured
84    */
85   bool configureCalUpdates(const sns_std_suid &suid, bool enable,
86                            SeeHelper &helper);
87 
88   /**
89    * Get the cached SUID of a calibration sensor that corresponds to the
90    * specified sensorType.
91    *
92    * @param sensorType The sensor type of the calibration sensor
93    *
94    * @return If found, a valid pointer to the SUID. Otherwise, nullptr.
95    */
96   const sns_std_suid *getCalSuidFromSensorType(uint8_t sensorType) const;
97 
98   /**
99    * Uses the supplied SeeHelper instance to find SEE calibration sensors that
100    * can be used to register for calibration updates.
101    *
102    * @param seeHelper SeeHelper instance to use when looking up calibration
103    *                  sensor SUIDs
104    *
105    * @return true if all expected SEE calibration sensors were successfully
106    *         found
107    */
108   bool findCalibrationSensors(SeeHelper &seeHelper);
109 
110   /**
111    * Updates the cached calibration data used in subsequent calls to
112    * applyCalibration. Thread-safe.
113    *
114    * @param suid Sensor UID associated with the incoming calibration data
115    * @param hasBias true if bias was decoded from the proto
116    * @param bias 3-axis bias; only valid if hasBias is true
117    * @param hasScale true if scale was decoded from the proto
118    * @param scale 3-axis scale factor; only valid if hasScale is true
119    * @param hasMatrix true if matrix was decoded from the proto
120    * @param matrix 3x3 compensation matrix; only valid if hasMatrix is true
121    * @param accuracy CHRE accuracy rating of the calibration quality (see
122    *     CHRE_SENSOR_ACCURACY)
123    * @param timestamp The timestamp of the calibration event
124    *
125    * @see CHRE_SENSOR_ACCURACY
126    */
127   void updateCalibration(const sns_std_suid &suid, bool hasBias, float bias[3],
128                          bool hasScale, float scale[3], bool hasMatrix,
129                          float matrix[9], uint8_t accuracy, uint64_t timestamp);
130 
131   /**
132    * @param suid SUID of the calibration sensor
133    * @param sensorType A non-null pointer that will contain the sensor type
134    *     corresponding to the given SUID, if found.
135    *
136    * @return true if a sensor type was found for the given SUID.
137    */
138   bool getSensorTypeFromSuid(const sns_std_suid &suid,
139                              uint8_t *sensorType) const;
140 
141  private:
142   //! A struct to store a sensor's calibration data
143   struct SeeCalData {
144     float bias[3];
145     float scale[3];
146     float matrix[9];
147     bool hasBias;
148     bool hasScale;
149     bool hasMatrix;
150     uint8_t accuracy;
151     uint64_t timestamp;
152   };
153 
154   //! A struct to store a cal sensor's UID and its cal data.
155   struct SeeCalInfo {
156     Optional<sns_std_suid> suid;
157     SeeCalData cal;
158     bool enabled = false;
159   };
160 
161   //! The list of SEE cal sensors supported.
162   enum class SeeCalSensor : size_t {
163 #ifdef CHRE_ENABLE_ACCEL_CAL
164     AccelCal,
165 #endif  // CHRE_ENABLE_ACCEL_CAL
166     GyroCal,
167     MagCal,
168     NumCalSensors,
169   };
170 
171   //! A convenience constant.
172   static constexpr size_t kNumSeeCalSensors =
173       static_cast<size_t>(SeeCalSensor::NumCalSensors);
174 
175   //! Protects access to calibration data, which may be used in multiple threads
176   mutable Mutex mMutex;
177 
178   //! Cal info of all the cal sensors.
179   SeeCalInfo mCalInfo[kNumSeeCalSensors] = {};
180 
181   //! Map SensorType to associated index in mCalInfo
182   static size_t getCalIndexFromSensorType(uint8_t sensorType);
183 
184   //! Map index in mCalInfo to SEE sensor data type string
185   static const char *getDataTypeForCalSensorIndex(size_t calSensorIndex);
186 
187   //! Map SUID to associated index in mCalInfo
188   size_t getCalIndexFromSuid(const sns_std_suid &suid) const;
189 };
190 
191 }  // namespace chre
192 
193 #endif  // CHRE_PLATFORM_SLPI_SEE_SEE_CAL_HELPER_H_
194