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 #include "chre_cross_validator_sensor_manager.h"
18
19 #include <algorithm>
20 #include <cinttypes>
21
22 #include <chre.h>
23 #include <pb_decode.h>
24 #include <pb_encode.h>
25
26 #include "chre/util/nanoapp/callbacks.h"
27 #include "chre/util/nanoapp/log.h"
28 #include "chre/util/optional.h"
29 #include "chre/util/time.h"
30 #include "chre_cross_validation_sensor.nanopb.h"
31
32 #define LOG_TAG "ChreCrossValidator"
33
34 namespace chre {
35
36 namespace cross_validator_sensor {
37
~Manager()38 Manager::~Manager() {
39 cleanup();
40 }
41
cleanup()42 void Manager::cleanup() {
43 if (mCrossValidatorState.has_value()) {
44 switch (mCrossValidatorState->crossValidatorType) {
45 case CrossValidatorType::SENSOR:
46 if (!chreSensorConfigureModeOnly(mCrossValidatorState->sensorHandle,
47 CHRE_SENSOR_CONFIGURE_MODE_DONE)) {
48 LOGE(
49 "Sensor cleanup failed when trying to configure sensor with "
50 "handle "
51 "%" PRIu32 " to done mode",
52 mCrossValidatorState->sensorHandle);
53 }
54 break;
55 default:
56 break;
57 }
58 }
59 }
60
handleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)61 void Manager::handleEvent(uint32_t senderInstanceId, uint16_t eventType,
62 const void *eventData) {
63 switch (eventType) {
64 case CHRE_EVENT_MESSAGE_FROM_HOST:
65 handleMessageFromHost(
66 senderInstanceId,
67 static_cast<const chreMessageFromHostData *>(eventData));
68 break;
69 // TODO(b/146052784): Check that data received from CHRE apis is the correct
70 // type for current test.
71 case CHRE_EVENT_SENSOR_ACCELEROMETER_DATA:
72 handleSensorThreeAxisData(
73 static_cast<const chreSensorThreeAxisData *>(eventData),
74 CHRE_SENSOR_TYPE_ACCELEROMETER);
75 break;
76 case CHRE_EVENT_SENSOR_GYROSCOPE_DATA:
77 handleSensorThreeAxisData(
78 static_cast<const chreSensorThreeAxisData *>(eventData),
79 CHRE_SENSOR_TYPE_GYROSCOPE);
80 break;
81 case CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_DATA:
82 handleSensorThreeAxisData(
83 static_cast<const chreSensorThreeAxisData *>(eventData),
84 CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD);
85 break;
86 case CHRE_EVENT_SENSOR_PRESSURE_DATA:
87 handleSensorFloatData(static_cast<const chreSensorFloatData *>(eventData),
88 CHRE_SENSOR_TYPE_PRESSURE);
89 break;
90 case CHRE_EVENT_SENSOR_LIGHT_DATA:
91 handleSensorFloatData(static_cast<const chreSensorFloatData *>(eventData),
92 CHRE_SENSOR_TYPE_LIGHT);
93 break;
94 case CHRE_EVENT_SENSOR_PROXIMITY_DATA:
95 handleProximityData(static_cast<const chreSensorByteData *>(eventData));
96 break;
97 case CHRE_EVENT_SENSOR_STEP_COUNTER_DATA:
98 handleStepCounterData(
99 static_cast<const chreSensorUint64Data *>(eventData));
100 break;
101 default:
102 LOGE("Got unknown event type from senderInstanceId %" PRIu32
103 " and with eventType %" PRIu16,
104 senderInstanceId, eventType);
105 }
106 }
107
encodeThreeAxisSensorDatapointValues(pb_ostream_t * stream,const pb_field_t *,void * const * arg)108 bool Manager::encodeThreeAxisSensorDatapointValues(pb_ostream_t *stream,
109 const pb_field_t * /*field*/,
110 void *const *arg) {
111 const auto *sensorThreeAxisDataSample = static_cast<
112 const chreSensorThreeAxisData::chreSensorThreeAxisSampleData *>(*arg);
113
114 for (size_t i = 0; i < 3; i++) {
115 if (!pb_encode_tag_for_field(
116 stream,
117 &chre_cross_validation_sensor_SensorDatapoint_fields
118 [chre_cross_validation_sensor_SensorDatapoint_values_tag -
119 1])) {
120 return false;
121 }
122 if (!pb_encode_fixed32(stream, &sensorThreeAxisDataSample->values[i])) {
123 return false;
124 }
125 }
126 return true;
127 }
128
makeDatapoint(bool (* encodeFunc)(pb_ostream_t *,const pb_field_t *,void * const *),const void * sampleDataFromChre,uint64_t currentTimestamp)129 chre_cross_validation_sensor_SensorDatapoint Manager::makeDatapoint(
130 bool (*encodeFunc)(pb_ostream_t *, const pb_field_t *, void *const *),
131 const void *sampleDataFromChre, uint64_t currentTimestamp) {
132 return chre_cross_validation_sensor_SensorDatapoint{
133 .has_timestampInNs = true,
134 .timestampInNs = currentTimestamp,
135 .values = {.funcs = {.encode = encodeFunc},
136 .arg = const_cast<void *>(sampleDataFromChre)}};
137 }
138
encodeFloatSensorDatapointValue(pb_ostream_t * stream,const pb_field_t *,void * const * arg)139 bool Manager::encodeFloatSensorDatapointValue(pb_ostream_t *stream,
140 const pb_field_t * /*field*/,
141 void *const *arg) {
142 const auto *sensorFloatDataSample =
143 static_cast<const chreSensorFloatData::chreSensorFloatSampleData *>(*arg);
144 if (!pb_encode_tag_for_field(
145 stream,
146 &chre_cross_validation_sensor_SensorDatapoint_fields
147 [chre_cross_validation_sensor_SensorDatapoint_values_tag - 1])) {
148 return false;
149 }
150 if (!pb_encode_fixed32(stream, &sensorFloatDataSample->value)) {
151 return false;
152 }
153 return true;
154 }
155
encodeProximitySensorDatapointValue(pb_ostream_t * stream,const pb_field_t *,void * const * arg)156 bool Manager::encodeProximitySensorDatapointValue(pb_ostream_t *stream,
157 const pb_field_t * /*field*/,
158 void *const *arg) {
159 const auto *sensorFloatDataSample =
160 static_cast<const chreSensorByteData::chreSensorByteSampleData *>(*arg);
161 if (!pb_encode_tag_for_field(
162 stream,
163 &chre_cross_validation_sensor_SensorDatapoint_fields
164 [chre_cross_validation_sensor_SensorDatapoint_values_tag - 1])) {
165 return false;
166 }
167 float isNearFloat = sensorFloatDataSample->isNear ? 0.0 : 1.0;
168 if (!pb_encode_fixed32(stream, &isNearFloat)) {
169 return false;
170 }
171 return true;
172 }
173
encodeStepCounterSensorDatapointValue(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)174 bool Manager::encodeStepCounterSensorDatapointValue(pb_ostream_t *stream,
175 const pb_field_t *field,
176 void *const *arg) {
177 const auto *sensorUint64DataSample =
178 static_cast<const chreSensorUint64Data::chreSensorUint64SampleData *>(
179 *arg);
180 if (!pb_encode_tag_for_field(
181 stream,
182 &chre_cross_validation_sensor_SensorDatapoint_fields
183 [chre_cross_validation_sensor_SensorDatapoint_values_tag - 1])) {
184 return false;
185 }
186 // This value is casted to a float for the Java sensors framework so do it
187 // here to make it easier to encode into the existing proto message.
188 float stepValue = float(sensorUint64DataSample->value);
189 if (!pb_encode_fixed32(stream, &stepValue)) {
190 return false;
191 }
192 return true;
193 }
194
encodeThreeAxisSensorDatapoints(pb_ostream_t * stream,const pb_field_t *,void * const * arg)195 bool Manager::encodeThreeAxisSensorDatapoints(pb_ostream_t *stream,
196 const pb_field_t * /*field*/,
197 void *const *arg) {
198 const auto *sensorThreeAxisData =
199 static_cast<const chreSensorThreeAxisData *>(*arg);
200 uint64_t currentTimestamp = sensorThreeAxisData->header.baseTimestamp +
201 chreGetEstimatedHostTimeOffset();
202 for (size_t i = 0; i < sensorThreeAxisData->header.readingCount; i++) {
203 const chreSensorThreeAxisData::chreSensorThreeAxisSampleData &sampleData =
204 sensorThreeAxisData->readings[i];
205 currentTimestamp += sampleData.timestampDelta;
206 if (!pb_encode_tag_for_field(
207 stream,
208 &chre_cross_validation_sensor_SensorData_fields
209 [chre_cross_validation_sensor_SensorData_datapoints_tag - 1])) {
210 return false;
211 }
212 chre_cross_validation_sensor_SensorDatapoint datapoint = makeDatapoint(
213 encodeThreeAxisSensorDatapointValues, &sampleData, currentTimestamp);
214 if (!pb_encode_submessage(
215 stream, chre_cross_validation_sensor_SensorDatapoint_fields,
216 &datapoint)) {
217 return false;
218 }
219 }
220 return true;
221 }
222
encodeFloatSensorDatapoints(pb_ostream_t * stream,const pb_field_t *,void * const * arg)223 bool Manager::encodeFloatSensorDatapoints(pb_ostream_t *stream,
224 const pb_field_t * /*field*/,
225 void *const *arg) {
226 const auto *sensorFloatData = static_cast<const chreSensorFloatData *>(*arg);
227 uint64_t currentTimestamp =
228 sensorFloatData->header.baseTimestamp + chreGetEstimatedHostTimeOffset();
229 for (size_t i = 0; i < sensorFloatData->header.readingCount; i++) {
230 const chreSensorFloatData::chreSensorFloatSampleData &sampleData =
231 sensorFloatData->readings[i];
232 currentTimestamp += sampleData.timestampDelta;
233 if (!pb_encode_tag_for_field(
234 stream,
235 &chre_cross_validation_sensor_SensorData_fields
236 [chre_cross_validation_sensor_SensorData_datapoints_tag - 1])) {
237 return false;
238 }
239 chre_cross_validation_sensor_SensorDatapoint datapoint = makeDatapoint(
240 encodeFloatSensorDatapointValue, &sampleData, currentTimestamp);
241 if (!pb_encode_submessage(
242 stream, chre_cross_validation_sensor_SensorDatapoint_fields,
243 &datapoint)) {
244 return false;
245 }
246 }
247 return true;
248 }
249
encodeProximitySensorDatapoints(pb_ostream_t * stream,const pb_field_t *,void * const * arg)250 bool Manager::encodeProximitySensorDatapoints(pb_ostream_t *stream,
251 const pb_field_t * /*field*/,
252 void *const *arg) {
253 const auto *sensorProximityData =
254 static_cast<const chreSensorByteData *>(*arg);
255 uint64_t currentTimestamp = sensorProximityData->header.baseTimestamp +
256 chreGetEstimatedHostTimeOffset();
257 for (size_t i = 0; i < sensorProximityData->header.readingCount; i++) {
258 const chreSensorByteData::chreSensorByteSampleData &sampleData =
259 sensorProximityData->readings[i];
260 currentTimestamp += sampleData.timestampDelta;
261 if (!pb_encode_tag_for_field(
262 stream,
263 &chre_cross_validation_sensor_SensorData_fields
264 [chre_cross_validation_sensor_SensorData_datapoints_tag - 1])) {
265 return false;
266 }
267 chre_cross_validation_sensor_SensorDatapoint datapoint = makeDatapoint(
268 encodeProximitySensorDatapointValue, &sampleData, currentTimestamp);
269 if (!pb_encode_submessage(
270 stream, chre_cross_validation_sensor_SensorDatapoint_fields,
271 &datapoint)) {
272 return false;
273 }
274 }
275 return true;
276 }
277
encodeStepCounterSensorDatapoints(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)278 bool Manager::encodeStepCounterSensorDatapoints(pb_ostream_t *stream,
279 const pb_field_t *field,
280 void *const *arg) {
281 const auto *sensorStepCounterData =
282 static_cast<const chreSensorUint64Data *>(*arg);
283 uint64_t currentTimestamp = sensorStepCounterData->header.baseTimestamp +
284 chreGetEstimatedHostTimeOffset();
285 for (size_t i = 0; i < sensorStepCounterData->header.readingCount; i++) {
286 const chreSensorUint64Data::chreSensorUint64SampleData &sampleData =
287 sensorStepCounterData->readings[i];
288 currentTimestamp += sampleData.timestampDelta;
289 if (!pb_encode_tag_for_field(
290 stream,
291 &chre_cross_validation_sensor_SensorData_fields
292 [chre_cross_validation_sensor_SensorData_datapoints_tag - 1])) {
293 return false;
294 }
295 chre_cross_validation_sensor_SensorDatapoint datapoint = makeDatapoint(
296 encodeStepCounterSensorDatapointValue, &sampleData, currentTimestamp);
297 if (!pb_encode_submessage(
298 stream, chre_cross_validation_sensor_SensorDatapoint_fields,
299 &datapoint)) {
300 return false;
301 }
302 }
303 return true;
304 }
305
handleStartSensorMessage(const chre_cross_validation_sensor_StartSensorCommand & startSensorCommand)306 bool Manager::handleStartSensorMessage(
307 const chre_cross_validation_sensor_StartSensorCommand &startSensorCommand) {
308 bool success = false;
309 uint8_t sensorType = startSensorCommand.chreSensorType;
310 uint64_t intervalFromApInNs =
311 startSensorCommand.intervalInMs * kOneMillisecondInNanoseconds;
312 uint64_t latencyInNs =
313 startSensorCommand.latencyInMs * kOneMillisecondInNanoseconds;
314 bool isContinuous = startSensorCommand.isContinuous;
315 uint32_t handle;
316 if (!chreSensorFindDefault(sensorType, &handle)) {
317 LOGE("Could not find default sensor for sensorType %" PRIu8, sensorType);
318 // TODO(b/146052784): Test other sensor configure modes
319 } else {
320 chreSensorInfo sensorInfo;
321 if (!chreGetSensorInfo(handle, &sensorInfo)) {
322 LOGE("Error getting sensor info for sensor");
323 } else {
324 // TODO(b/154271547): Send minInterval to AP and have the AP decide from
325 // both CHRE and AP min and max interval.
326 uint64_t intervalInNs =
327 std::max(intervalFromApInNs, sensorInfo.minInterval);
328 // Copy hostEndpoint param from previous version of cross validator
329 // state
330 mCrossValidatorState = CrossValidatorState(
331 CrossValidatorType::SENSOR, sensorType, handle, chreGetTime(),
332 mCrossValidatorState->hostEndpoint, isContinuous);
333 if (!chreSensorConfigure(handle, CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS,
334 intervalInNs, latencyInNs)) {
335 LOGE("Error configuring sensor with sensorType %" PRIu8
336 ", interval %" PRIu64 "ns, and latency %" PRIu64 "ns",
337 sensorType, intervalInNs, latencyInNs);
338 } else {
339 LOGD("Sensor with sensor type %" PRIu8 " configured", sensorType);
340 success = true;
341 }
342 }
343 }
344 return success;
345 }
346
isValidHeader(const chreSensorDataHeader & header)347 bool Manager::isValidHeader(const chreSensorDataHeader &header) {
348 // On-change sensors may send cached values because the data value has not
349 // changed since the test started
350 bool isTimestampValid =
351 !mCrossValidatorState->isContinuous ||
352 header.baseTimestamp >= mCrossValidatorState->timeStart;
353 return header.readingCount > 0 && isTimestampValid;
354 }
355
handleStartMessage(uint16_t hostEndpoint,const chreMessageFromHostData * hostData)356 void Manager::handleStartMessage(uint16_t hostEndpoint,
357 const chreMessageFromHostData *hostData) {
358 bool success = true;
359 // Default values for everything but hostEndpoint param
360 mCrossValidatorState = CrossValidatorState(CrossValidatorType::SENSOR, 0, 0,
361 0, hostEndpoint, false);
362 pb_istream_t istream = pb_istream_from_buffer(
363 static_cast<const pb_byte_t *>(hostData->message), hostData->messageSize);
364 chre_cross_validation_sensor_StartCommand startCommand =
365 chre_cross_validation_sensor_StartCommand_init_default;
366 if (!pb_decode(&istream, chre_cross_validation_sensor_StartCommand_fields,
367 &startCommand)) {
368 LOGE("Could not decode start command");
369 } else {
370 switch (startCommand.which_command) {
371 case chre_cross_validation_sensor_StartCommand_startSensorCommand_tag:
372 success =
373 handleStartSensorMessage(startCommand.command.startSensorCommand);
374 break;
375 default:
376 LOGE("Unknown start command type %" PRIu8, startCommand.which_command);
377 }
378 }
379 // If error occurred in validation setup then resetting mCrossValidatorState
380 // will alert the event handler
381 if (!success) {
382 mCrossValidatorState.reset();
383 }
384 }
385
handleInfoMessage(uint16_t hostEndpoint,const chreMessageFromHostData * hostData)386 void Manager::handleInfoMessage(uint16_t hostEndpoint,
387 const chreMessageFromHostData *hostData) {
388 chre_cross_validation_sensor_SensorInfoResponse infoResponse =
389 chre_cross_validation_sensor_SensorInfoResponse_init_default;
390 pb_istream_t istream = pb_istream_from_buffer(
391 static_cast<const pb_byte_t *>(hostData->message), hostData->messageSize);
392 chre_cross_validation_sensor_SensorInfoCommand infoCommand =
393 chre_cross_validation_sensor_SensorInfoCommand_init_default;
394 if (!pb_decode(&istream,
395 chre_cross_validation_sensor_SensorInfoCommand_fields,
396 &infoCommand)) {
397 LOGE("Could not decode info command");
398 } else {
399 uint32_t handle;
400 infoResponse.has_chreSensorType = true;
401 infoResponse.chreSensorType = infoCommand.chreSensorType;
402 infoResponse.has_isAvailable = true;
403 infoResponse.isAvailable =
404 chreSensorFindDefault(infoResponse.chreSensorType, &handle);
405 }
406
407 sendInfoResponse(hostEndpoint, infoResponse);
408 }
409
handleMessageFromHost(uint32_t senderInstanceId,const chreMessageFromHostData * hostData)410 void Manager::handleMessageFromHost(uint32_t senderInstanceId,
411 const chreMessageFromHostData *hostData) {
412 if (senderInstanceId != CHRE_INSTANCE_ID) {
413 LOGE("Incorrect sender instance id: %" PRIu32, senderInstanceId);
414 } else {
415 uint16_t hostEndpoint;
416 if (hostData->hostEndpoint != CHRE_HOST_ENDPOINT_UNSPECIFIED) {
417 hostEndpoint = hostData->hostEndpoint;
418 } else {
419 hostEndpoint = CHRE_HOST_ENDPOINT_BROADCAST;
420 }
421
422 switch (hostData->messageType) {
423 case chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_START:
424 handleStartMessage(hostEndpoint, hostData);
425 break;
426 case chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_INFO:
427 handleInfoMessage(hostEndpoint, hostData);
428 break;
429 default:
430 LOGE("Unknown message type %" PRIu32 " for host message",
431 hostData->messageType);
432 }
433 }
434 }
435
makeSensorThreeAxisData(const chreSensorThreeAxisData * threeAxisDataFromChre,uint8_t sensorType)436 chre_cross_validation_sensor_Data Manager::makeSensorThreeAxisData(
437 const chreSensorThreeAxisData *threeAxisDataFromChre, uint8_t sensorType) {
438 chre_cross_validation_sensor_SensorData newThreeAxisData = {
439 .has_chreSensorType = true,
440 .chreSensorType = sensorType,
441 .has_accuracy = true,
442 .accuracy = threeAxisDataFromChre->header.accuracy,
443 .datapoints = {
444 .funcs = {.encode = encodeThreeAxisSensorDatapoints},
445 .arg = const_cast<chreSensorThreeAxisData *>(threeAxisDataFromChre)}};
446 chre_cross_validation_sensor_Data newData = {
447 .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
448 .data =
449 {
450 .sensorData = newThreeAxisData,
451 },
452 };
453 return newData;
454 }
455
makeSensorFloatData(const chreSensorFloatData * floatDataFromChre,uint8_t sensorType)456 chre_cross_validation_sensor_Data Manager::makeSensorFloatData(
457 const chreSensorFloatData *floatDataFromChre, uint8_t sensorType) {
458 chre_cross_validation_sensor_SensorData newfloatData = {
459 .has_chreSensorType = true,
460 .chreSensorType = sensorType,
461 .has_accuracy = true,
462 .accuracy = floatDataFromChre->header.accuracy,
463 .datapoints = {
464 .funcs = {.encode = encodeFloatSensorDatapoints},
465 .arg = const_cast<chreSensorFloatData *>(floatDataFromChre)}};
466 chre_cross_validation_sensor_Data newData = {
467 .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
468 .data =
469 {
470 .sensorData = newfloatData,
471 },
472 };
473 return newData;
474 }
475
makeSensorProximityData(const chreSensorByteData * proximityDataFromChre)476 chre_cross_validation_sensor_Data Manager::makeSensorProximityData(
477 const chreSensorByteData *proximityDataFromChre) {
478 chre_cross_validation_sensor_SensorData newProximityData = {
479 .has_chreSensorType = true,
480 .chreSensorType = CHRE_SENSOR_TYPE_PROXIMITY,
481 .has_accuracy = true,
482 .accuracy = proximityDataFromChre->header.accuracy,
483 .datapoints = {
484 .funcs = {.encode = encodeProximitySensorDatapoints},
485 .arg = const_cast<chreSensorByteData *>(proximityDataFromChre)}};
486 chre_cross_validation_sensor_Data newData = {
487 .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
488 .data =
489 {
490 .sensorData = newProximityData,
491 },
492 };
493 return newData;
494 }
495
makeSensorStepCounterData(const chreSensorUint64Data * stepCounterDataFromChre)496 chre_cross_validation_sensor_Data Manager::makeSensorStepCounterData(
497 const chreSensorUint64Data *stepCounterDataFromChre) {
498 chre_cross_validation_sensor_SensorData newStepCounterData = {
499 .has_chreSensorType = true,
500 .chreSensorType = CHRE_SENSOR_TYPE_STEP_COUNTER,
501 .has_accuracy = true,
502 .accuracy = stepCounterDataFromChre->header.accuracy,
503 .datapoints = {
504 .funcs = {.encode = encodeStepCounterSensorDatapoints},
505 .arg = const_cast<chreSensorUint64Data *>(stepCounterDataFromChre)}};
506 chre_cross_validation_sensor_Data newData = {
507 .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
508 .data =
509 {
510 .sensorData = newStepCounterData,
511 },
512 };
513 return newData;
514 }
515
handleSensorThreeAxisData(const chreSensorThreeAxisData * threeAxisDataFromChre,uint8_t sensorType)516 void Manager::handleSensorThreeAxisData(
517 const chreSensorThreeAxisData *threeAxisDataFromChre, uint8_t sensorType) {
518 if (processSensorData(threeAxisDataFromChre->header, sensorType)) {
519 chre_cross_validation_sensor_Data newData =
520 makeSensorThreeAxisData(threeAxisDataFromChre, sensorType);
521 sendDataToHost(newData);
522 }
523 }
524
handleSensorFloatData(const chreSensorFloatData * floatDataFromChre,uint8_t sensorType)525 void Manager::handleSensorFloatData(
526 const chreSensorFloatData *floatDataFromChre, uint8_t sensorType) {
527 if (processSensorData(floatDataFromChre->header, sensorType)) {
528 chre_cross_validation_sensor_Data newData =
529 makeSensorFloatData(floatDataFromChre, sensorType);
530 sendDataToHost(newData);
531 }
532 }
533
handleProximityData(const chreSensorByteData * proximityDataFromChre)534 void Manager::handleProximityData(
535 const chreSensorByteData *proximityDataFromChre) {
536 if (processSensorData(proximityDataFromChre->header,
537 CHRE_SENSOR_TYPE_PROXIMITY)) {
538 chre_cross_validation_sensor_Data newData =
539 makeSensorProximityData(proximityDataFromChre);
540 sendDataToHost(newData);
541 }
542 }
543
handleStepCounterData(const chreSensorUint64Data * stepCounterDataFromChre)544 void Manager::handleStepCounterData(
545 const chreSensorUint64Data *stepCounterDataFromChre) {
546 if (processSensorData(stepCounterDataFromChre->header,
547 CHRE_SENSOR_TYPE_STEP_COUNTER)) {
548 chre_cross_validation_sensor_Data newData =
549 makeSensorStepCounterData(stepCounterDataFromChre);
550 sendDataToHost(newData);
551 }
552 }
553
sendDataToHost(const chre_cross_validation_sensor_Data & data)554 void Manager::sendDataToHost(const chre_cross_validation_sensor_Data &data) {
555 sendMessageToHost(
556 mCrossValidatorState->hostEndpoint,
557 chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_DATA,
558 chre_cross_validation_sensor_Data_fields, &data);
559 }
560
sendInfoResponse(uint16_t hostEndpoint,const chre_cross_validation_sensor_SensorInfoResponse & infoResponse)561 void Manager::sendInfoResponse(
562 uint16_t hostEndpoint,
563 const chre_cross_validation_sensor_SensorInfoResponse &infoResponse) {
564 sendMessageToHost(
565 hostEndpoint,
566 chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_INFO_RESPONSE,
567 chre_cross_validation_sensor_SensorInfoResponse_fields, &infoResponse);
568 }
569
sendMessageToHost(uint16_t hostEndpoint,uint16_t messageType,const pb_field_t fields[],const void * srcStruct)570 void Manager::sendMessageToHost(uint16_t hostEndpoint, uint16_t messageType,
571 const pb_field_t fields[],
572 const void *srcStruct) {
573 size_t encodedSize;
574 if (!pb_get_encoded_size(&encodedSize, fields, srcStruct)) {
575 LOGE("Could not get encoded size of proto message");
576 } else {
577 pb_byte_t *buffer = static_cast<pb_byte_t *>(chreHeapAlloc(encodedSize));
578 if (buffer == nullptr) {
579 LOG_OOM();
580 } else {
581 pb_ostream_t ostream = pb_ostream_from_buffer(buffer, encodedSize);
582 if (!pb_encode(&ostream, fields, srcStruct)) {
583 LOGE("Could not encode proto message");
584 } else if (!chreSendMessageToHostEndpoint(
585 static_cast<void *>(buffer), encodedSize, messageType,
586 hostEndpoint, heapFreeMessageCallback)) {
587 LOGE("Could not send message to host");
588 }
589 }
590 }
591 }
592
processSensorData(const chreSensorDataHeader & header,uint8_t sensorType)593 bool Manager::processSensorData(const chreSensorDataHeader &header,
594 uint8_t sensorType) {
595 if (!mCrossValidatorState.has_value()) {
596 LOGE("Start message not received or invalid when data received");
597 } else if (!isValidHeader(header)) {
598 LOGE("Invalid data being thrown away");
599 } else if (!sensorTypeIsValid(sensorType)) {
600 LOGE("Unexpected sensor data type %" PRIu8 ", expected %" PRIu8, sensorType,
601 mCrossValidatorState->sensorType);
602 } else {
603 return true;
604 }
605 return false;
606 }
607
sensorTypeIsValid(uint8_t sensorType)608 bool Manager::sensorTypeIsValid(uint8_t sensorType) {
609 return sensorType == mCrossValidatorState->sensorType;
610 }
611
612 } // namespace cross_validator_sensor
613
614 } // namespace chre
615