1 /*
2  * Copyright (C) 2020 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_CROSS_VALIDATOR_MANAGER_H_
18 #define CHRE_CROSS_VALIDATOR_MANAGER_H_
19 
20 #include <chre.h>
21 #include <pb_encode.h>
22 
23 #include "chre_cross_validation_sensor.nanopb.h"
24 
25 #include "chre/util/optional.h"
26 #include "chre/util/singleton.h"
27 
28 namespace chre {
29 
30 namespace cross_validator_sensor {
31 
32 // TODO(b/154271551): Break up the Manager class into more fine-grained classes
33 // to avoid it becoming to complex.
34 
35 //! The maximum size of a sensor name.
36 constexpr size_t kMaxSensorNameSize = 128;
37 
38 /**
39  * Class to manage a CHRE cross validator nanoapp.
40  */
41 class Manager {
42  public:
43   /**
44    * Calls the cleanup helper method. This dtor is called on a singleton deinit
45    * call.
46    */
47   ~Manager();
48 
49   /**
50    * Handle a CHRE event.
51    *
52    * @param senderInstanceId The instand ID that sent the event.
53    * @param eventType The type of the event.
54    * @param eventData The data for the event.
55    */
56   void handleEvent(uint32_t senderInstanceId, uint16_t eventType,
57                    const void *eventData);
58 
59  private:
60   /**
61    * The enum that describes the type of cross validator in use.
62    */
63   enum class CrossValidatorType { SENSOR };
64 
65   /**
66    * Struct to hold the state of the cross validator nanoapp.
67    */
68   struct CrossValidatorState {
69     // Set upon received start message and read when nanoapp ends to handle
70     // cleanup
71     CrossValidatorType crossValidatorType;
72     // Set when start message received and checked against when a sensor data
73     // event from CHRE comes in
74     uint8_t sensorType;
75     // Set when start message is received and default sensor is found for
76     // requested sensor type and read when the sensor configuration is being
77     // cleaned up. Unused in non-sensor type validations
78     uint32_t sensorHandle;
79     // The host endpoint which is read from the start message and used when
80     // sending data back to AP.
81     uint64_t timeStart;
82     // The host endpoint which is read from the start message and used when
83     // sending data back to AP.
84     uint16_t hostEndpoint = CHRE_HOST_ENDPOINT_BROADCAST;
85     // The sensor for this validation uses continuous reporting mode.
86     bool isContinuous;
87 
CrossValidatorStateCrossValidatorState88     CrossValidatorState(CrossValidatorType crossValidatorTypeIn,
89                         uint8_t sensorTypeIn, uint32_t sensorHandleIn,
90                         uint64_t timeStartIn, uint16_t hostEndpointIn,
91                         bool isContinuousIn)
92         : crossValidatorType(crossValidatorTypeIn),
93           sensorType(sensorTypeIn),
94           sensorHandle(sensorHandleIn),
95           timeStart(timeStartIn),
96           hostEndpoint(hostEndpointIn),
97           isContinuous(isContinuousIn) {}
98   };
99 
100   //! The current state of the nanoapp.
101   //! Unset if start message was not received or error while processing start
102   //! message.
103   chre::Optional<CrossValidatorState> mCrossValidatorState;
104 
105   //! A temporary global buffer where the sensor name is stored.
106   char mSensorNameArray[kMaxSensorNameSize];
107 
108   /**
109    * Make a SensorDatapoint proto message.
110    *
111    * @param sampleDataFromChre The sample data from CHRE.
112    * @param currentTimestamp The current CHRE timestamp.
113    *
114    * @return The SensorDatapoint proto message.
115    */
116   static chre_cross_validation_sensor_SensorDatapoint makeDatapoint(
117       bool (*encodeFunc)(pb_ostream_t *, const pb_field_t *, void *const *),
118       const void *sampleDataFromChre, uint64_t currentTimestamp);
119 
120   /**
121    * Encodes the values array of a sensor datapoint proto message. Used as the
122    * encode field of the SenorDatapoint message.
123    *
124    * @param stream The stream to write to.
125    * @param field The field to write to (unused).
126    * @param arg The data passed in order to write to the stream.
127    * @return true if successful.
128    */
129   static bool encodeThreeAxisSensorDatapointValues(pb_ostream_t *stream,
130                                                    const pb_field_t * /*field*/,
131                                                    void *const *arg);
132 
133   /**
134    * Encodes the datapoints into a SensorData message.
135    *
136    * @param stream The stream to write to.
137    * @param field The field to write to (unused).
138    * @param arg The data passed in order to write to the stream.
139    * @return true if successful.
140    */
141   static bool encodeThreeAxisSensorDatapoints(pb_ostream_t *stream,
142                                               const pb_field_t * /*field*/,
143                                               void *const *arg);
144 
145   /**
146    * Encodes the datapoints into a SensorData message.
147    *
148    * @param stream The stream to write to.
149    * @param field The field to write to (unused).
150    * @param arg The data passed in order to write to the stream.
151    * @return true if successful.
152    */
153   static bool encodeFloatSensorDatapoints(pb_ostream_t *stream,
154                                           const pb_field_t * /*field*/,
155                                           void *const *arg);
156 
157   /**
158    * Encodes the datapoints into a SensorData message.
159    *
160    * @param stream The stream to write to.
161    * @param field The field to write to (unused).
162    * @param arg The data passed in order to write to the stream.
163    * @return true if successful.
164    */
165   static bool encodeProximitySensorDatapoints(pb_ostream_t *stream,
166                                               const pb_field_t * /*field*/,
167                                               void *const *arg);
168 
169   /**
170    * Encodes the datapoints into a SensorData message.
171    *
172    * @param stream The stream to write to.
173    * @param field The field to write to.
174    * @param arg The data passed in order to write to the stream.
175    * @return true if successful.
176    */
177   static bool encodeStepCounterSensorDatapoints(pb_ostream_t *stream,
178                                                 const pb_field_t *field,
179                                                 void *const *arg);
180 
181   /**
182    * Encodes a single float value into values list of SensorDatapoint object.
183    *
184    * @param stream The stream to write to.
185    * @param field The field to write to (unused).
186    * @param arg The data passed in order to write to the stream.
187    * @return true if successful.
188    */
189   static bool encodeFloatSensorDatapointValue(pb_ostream_t *stream,
190                                               const pb_field_t * /*field*/,
191                                               void *const *arg);
192 
193   /**
194    * Encodes a single promximity value into values list of SensorDatapoint
195    * object, converting the isNear property into 5.0 (false) or 0.0 (true) in
196    * the process.
197    *
198    * @param stream The stream to write to.
199    * @param field The field to write to (unused).
200    * @param arg The data passed in order to write to the stream.
201    * @return true if successful.
202    */
203   static bool encodeProximitySensorDatapointValue(pb_ostream_t *stream,
204                                                   const pb_field_t * /*field*/,
205                                                   void *const *arg);
206 
207   /**
208    * Encodes a single step counter value into the values list of SensorDatapoint
209    * object, converting the uint64 value property into a float in the process.
210    *
211    * @param stream The stream to write to.
212    * @param field The field to write to (unused).
213    * @param arg The data passed in order to write to the stream.
214    * @return true if successful.
215    */
216   static bool encodeStepCounterSensorDatapointValue(pb_ostream_t *stream,
217                                                     const pb_field_t *field,
218                                                     void *const *arg);
219 
220   /**
221    * Handle a start sensor message.
222    *
223    * @param startSensorCommand The StartSensorCommand proto message received.
224    *
225    * @return true if successful.
226    */
227   bool handleStartSensorMessage(
228       const chre_cross_validation_sensor_StartSensorCommand
229           &startSensorCommand);
230 
231   /**
232    * @param header The sensor data header from CHRE sensor data event.
233    *
234    * @return true if header is valid.
235    */
236   bool isValidHeader(const chreSensorDataHeader &header);
237 
238   /**
239    * Handle a start message from CHRE with the given data from host.
240    *
241    * @param hostEndpoint The host endpoint the data was sent from.
242    * @param hostData The data from host that has a start message.
243    */
244   void handleStartMessage(uint16_t hostEndpoint,
245                           const chreMessageFromHostData *hostData);
246 
247   /**
248    * Handle an info message from CHRE with the given data from host.
249    *
250    * @param hostEndpoint The host endpoint the data was sent from.
251    * @param hostData The data from host that has a start message.
252    */
253   void handleInfoMessage(uint16_t hostEndpoint,
254                          const chreMessageFromHostData *hostData);
255 
256   /**
257    * Handle a message from the host.
258    *
259    * @param senderInstanceId The instance ID of the sender of this message.
260    * @param hostData The data from the host message.
261    */
262   void handleMessageFromHost(uint32_t senderInstanceId,
263                              const chreMessageFromHostData *hostData);
264 
265   /**
266    * @param threeAxisDataFromChre Three axis sensor data from CHRE.
267    * @param sensorType The sensor type that sent the three axis data.
268    *
269    * @return The Data proto message that is ready to be sent to host with three
270    * axis data.
271    */
272   chre_cross_validation_sensor_Data makeSensorThreeAxisData(
273       const chreSensorThreeAxisData *threeAxisDataFromChre, uint8_t sensorType);
274 
275   /**
276    * @param floatDataFromChre Float sensor data from CHRE.
277    * @param sensorType The sensor type that sent the three axis data.
278    *
279    * @return The Data proto message that is ready to be sent to host with float
280    * data.
281    */
282   chre_cross_validation_sensor_Data makeSensorFloatData(
283       const chreSensorFloatData *floatDataFromChre, uint8_t sensorType);
284 
285   /**
286    * @param proximtyDataFromChre Proximity sensor data from CHRE.
287    * @param sensorType The sensor type that sent the three axis data.
288    *
289    * @return The Data proto message that is ready to be sent to host with float
290    * data.
291    */
292   chre_cross_validation_sensor_Data makeSensorProximityData(
293       const chreSensorByteData *proximityDataFromChre);
294 
295   /**
296    * @param stepCounterDataFromChre Proximity sensor data from CHRE.
297    * @param sensorType The sensor type that sent the uint64 data.
298    *
299    * @return The Data proto message that is ready to be sent to host with float
300    * data.
301    */
302   chre_cross_validation_sensor_Data makeSensorStepCounterData(
303       const chreSensorUint64Data *stepCounterDataFromChre);
304 
305   /**
306    * Handle sensor three axis data from CHRE.
307    *
308    * @param threeAxisDataFromChre The data from CHRE to parse.
309    * @param sensorType The sensor type that sent the three axis data.
310    */
311   void handleSensorThreeAxisData(
312       const chreSensorThreeAxisData *threeAxisDataFromChre, uint8_t sensorType);
313 
314   /**
315    * Handle sensor float data from CHRE.
316    *
317    * @param floatDataFromChre The data from CHRE to parse.
318    * @param sensorType The sensor type that sent the float data.
319    */
320   void handleSensorFloatData(const chreSensorFloatData *floatDataFromChre,
321                              uint8_t sensorType);
322 
323   /**
324    * Handle proximity sensor data from CHRE.
325    *
326    * @param proximityDataFromChre The data to parse.
327    */
328   void handleProximityData(const chreSensorByteData *proximityDataFromChre);
329 
330   /**
331    * Send data to be validated to the host.
332    * Handle step counter sensor data from CHRE.
333    *
334    * @param stepCounterDataFromChre The data to parse.
335    */
336   void handleStepCounterData(
337       const chreSensorUint64Data *stepCounterDataFromChre);
338 
339   /**
340    * Encode and send data to be validated to host.
341    *
342    * @param data The data to send.
343    */
344   void sendDataToHost(const chre_cross_validation_sensor_Data &data);
345 
346   /**
347    * Encode and send the info response to the host.
348    *
349    * @param hostEndpoint The endpoint to send the response to.
350    * @param infoResponse The info response to be encoded and sent.
351    */
352   void sendInfoResponse(
353       uint16_t hostEndpoint,
354       const chre_cross_validation_sensor_SensorInfoResponse &infoResponse);
355 
356   /**
357    * Sends the provided message to the host.
358    *
359    * @param hostEndpoint The endpoint to send the message to.
360    * @param messageType The type of message being sent to the host.
361    * @param fields The fields of the provided struct that should be encoded.
362    * @param srcStruct The struct that should be encoded prior to sending to the
363    *     host.
364    */
365   void sendMessageToHost(uint16_t hostEndpoint, uint16_t messageType,
366                          const pb_field_t fields[], const void *srcStruct);
367 
368   /**
369    * Determine if nanoapp is ready to process new sensor data.
370    *
371    * @param header The sensor data header that was received with data.
372    * @param sensorType The sensor type of received data.
373    *
374    * @return true if state is inline with receiving this new sensor data.
375    */
376   bool processSensorData(const chreSensorDataHeader &header,
377                          uint8_t sensorType);
378 
379   /**
380    * @param sensorType The sensor type received from a CHRE sensor data event.
381    *
382    * @return true if sensorType matches the sensorType of current cross
383    * validator state.
384    */
385   bool sensorTypeIsValid(uint8_t sensorType);
386 
387   /**
388    * Cleanup the manager by tearing down any CHRE API resources that were used
389    * during validation.
390    */
391   void cleanup();
392 
393   /**
394    * @param sensorType The CHRE sensor type.
395    * @param sensorIndex The CHRE sensor index as defined in chreSensorFind.
396    * @param handle A non-null pointer where the sensor handle is stored, if
397    * found.
398    *
399    * @return true if the sensor corresponding to the input is available.
400    */
401   bool getSensor(uint32_t sensorType, uint32_t sensorIndex, uint32_t *handle);
402 };
403 
404 // The chre cross validator manager singleton.
405 typedef chre::Singleton<Manager> ManagerSingleton;
406 
407 }  // namespace cross_validator_sensor
408 
409 }  // namespace chre
410 
411 #endif  // CHRE_CROSS_VALIDATOR_MANAGER_H_
412