• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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/platform/slpi/see/see_helper.h"
18 
19 #include "pb_decode.h"
20 #include "pb_encode.h"
21 #include "sns_cal.pb.h"
22 #include "sns_client.pb.h"
23 #include "sns_client_api_v01.h"
24 #include "sns_proximity.pb.h"
25 #include "sns_rc.h"
26 #include "sns_remote_proc_state.pb.h"
27 #include "sns_std.pb.h"
28 #include "sns_std_sensor.pb.h"
29 #include "stringl.h"
30 #include "timer.h"
31 
32 #include <algorithm>
33 #include <cfloat>
34 #include <cinttypes>
35 #include <cmath>
36 
37 #include "chre/platform/assert.h"
38 #include "chre/platform/log.h"
39 #include "chre/platform/slpi/system_time_util.h"
40 #include "chre/util/lock_guard.h"
41 #include "chre/util/macros.h"
42 
43 #ifdef CHREX_SENSOR_SUPPORT
44 #include "chre/extensions/platform/vendor_sensor_types.h"
45 #endif  // CHREX_SENSOR_SUPPORT
46 
47 #define LOG_NANOPB_ERROR(stream) \
48     LOGE("Nanopb error: %s:%d", PB_GET_ERROR(stream), __LINE__)
49 
50 namespace chre {
51 namespace {
52 
53 //! Operating mode indicating sensor is disabled.
54 const char *kOpModeOff = "OFF";
55 
56 //! The SUID of the look up sensor.
57 const sns_std_suid kSuidLookup = sns_suid_sensor_init_default;
58 
59 //! A struct to facilitate SEE response handling
60 struct SeeRespCbData {
61   SeeHelper *seeHelper;
62   uint32_t txnId;
63 };
64 
65 //! A struct to facilitate pb encode/decode
66 struct SeeBufArg {
67   const void *buf;
68   size_t bufLen;
69 };
70 
71 //! A struct to facilitate pb decode of sync calls.
72 struct SeeSyncArg {
73   sns_std_suid syncSuid;
74   void *syncData;
75   const char *syncDataType;
76   bool syncIndFound;
77 };
78 
79 //! SeeFloatArg can be used to decode a vectorized 3x3 array.
80 constexpr size_t kSeeFloatArgValLen = 9;
81 
82 //! A struct to facilitate decoding a float array.
83 struct SeeFloatArg {
84   size_t index;
85   float val[kSeeFloatArgValLen];
86 };
87 
88 //! A struct to facilitate pb decode of sensor data event.
89 struct SeeDataArg {
90   uint64_t prevTimeNs;
91   uint64_t timeNs;
92   size_t sampleIndex;
93   size_t totalSamples;
94   UniquePtr<uint8_t> event;
95   UniquePtr<SeeHelperCallbackInterface::SamplingStatusData> status;
96   SeeCalData *cal;
97   SensorType sensorType;
98   bool isHostWakeSuspendEvent;
99   bool isHostAwake;
100 };
101 
102 //! A struct to facilitate pb decode
103 struct SeeInfoArg {
104   sns_client *client;
105   sns_std_suid suid;
106   uint32_t msgId;
107   SeeSyncArg *sync;
108   SeeDataArg *data;
109   bool decodeMsgIdOnly;
110   Optional<sns_std_suid> *remoteProcSuid;
111   SeeCalInfo *calInfo;
112 };
113 
114 //! A struct to facilitate decoding sensor attributes.
115 struct SeeAttrArg {
116   union {
117     char strVal[kSeeAttrStrValLen];
118     bool boolVal;
119     struct {
120       float fltMin;
121       float fltMax;
122     };
123     int64_t int64;
124   };
125   bool initialized;
126 };
127 
getCalIndexFromSensorType(SensorType sensorType)128 size_t getCalIndexFromSensorType(SensorType sensorType) {
129   SeeCalSensor index;
130   switch (sensorType) {
131     case SensorType::Accelerometer:
132       index = SeeCalSensor::AccelCal;
133       break;
134     case SensorType::Gyroscope:
135       index = SeeCalSensor::GyroCal;
136       break;
137     case SensorType::GeomagneticField:
138       index = SeeCalSensor::MagCal;
139       break;
140     default:
141       index = SeeCalSensor::NumCalSensors;
142   }
143   return static_cast<size_t>(index);
144 }
145 
getCalIndexFromDataType(const char * dataType)146 size_t getCalIndexFromDataType(const char *dataType) {
147   SensorType sensorType = SensorType::Unknown;
148   if (strcmp(dataType, "accel_cal") == 0) {
149     sensorType = SensorType::Accelerometer;
150   } else if (strcmp(dataType, "gyro_cal") == 0) {
151     sensorType = SensorType::Gyroscope;
152   } else if (strcmp(dataType, "mag_cal") == 0) {
153     sensorType = SensorType::GeomagneticField;
154   }
155   return getCalIndexFromSensorType(sensorType);
156 }
157 
getCalIndexFromSuid(const sns_std_suid & suid,const SeeCalInfo * calInfo)158 size_t getCalIndexFromSuid(const sns_std_suid& suid,
159                            const SeeCalInfo *calInfo) {
160   size_t i = 0;
161   for (; i < kNumSeeCalSensors; i++) {
162     if (calInfo[i].suid.has_value()
163         && suidsMatch(suid, calInfo[i].suid.value())) {
164       break;
165     }
166   }
167   return i;
168 }
169 
170 /**
171  * Copy an encoded pb message to a wrapper proto's field.
172  */
copyPayload(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)173 bool copyPayload(pb_ostream_t *stream, const pb_field_t *field,
174                  void *const *arg) {
175   bool success = false;
176 
177   auto *data = static_cast<const SeeBufArg *>(*arg);
178   if (!pb_encode_tag_for_field(stream, field)) {
179     LOG_NANOPB_ERROR(stream);
180   } else if (!pb_encode_string(
181       stream, static_cast<const pb_byte_t *>(data->buf), data->bufLen)) {
182     LOG_NANOPB_ERROR(stream);
183   } else {
184     success = true;
185   }
186   return success;
187 }
188 
189 /**
190  * Encodes sns_std_attr_req pb message.
191  *
192  * @param msg A non-null pointer to the pb message unique pointer whose object
193  *            will be assigned here.
194  * @param msgLen A non-null pointer to the size of the encoded pb message.
195  *
196  * @return true if the pb message and length were obtained.
197  */
encodeSnsStdAttrReq(UniquePtr<pb_byte_t> * msg,size_t * msgLen)198 bool encodeSnsStdAttrReq(UniquePtr<pb_byte_t> *msg, size_t *msgLen) {
199   CHRE_ASSERT(msg);
200   CHRE_ASSERT(msgLen);
201 
202   // Initialize the pb message
203   sns_std_attr_req req = {};
204 
205   bool success = pb_get_encoded_size(msgLen, sns_std_attr_req_fields, &req);
206   if (!success) {
207     LOGE("pb_get_encoded_size failed for sns_str_attr_req");
208   } else {
209     UniquePtr<pb_byte_t> buf(static_cast<pb_byte_t *>(memoryAlloc(*msgLen)));
210     *msg = std::move(buf);
211 
212     // The encoded size can be 0 as there's only one optional field.
213     if (msg->isNull() && *msgLen > 0) {
214       LOG_OOM();
215     } else {
216       pb_ostream_t stream = pb_ostream_from_buffer(msg->get(), *msgLen);
217 
218       success = pb_encode(&stream, sns_std_attr_req_fields, &req);
219       if (!success) {
220         LOG_NANOPB_ERROR(&stream);
221       }
222     }
223   }
224   return success;
225 }
226 
227 /**
228  * Encodes sns_suid_req pb message.
229  *
230  * @param dataType Sensor data type, "accel" for example.
231  * @param msg A non-null pointer to the pb message unique pointer whose object
232  *            will be assigned here.
233  * @param msgLen A non-null pointer to the size of the encoded pb message.
234  *
235  * @return true if the pb message and length were obtained.
236  */
encodeSnsSuidReq(const char * dataType,UniquePtr<pb_byte_t> * msg,size_t * msgLen)237 bool encodeSnsSuidReq(const char *dataType,
238                       UniquePtr<pb_byte_t> *msg, size_t *msgLen) {
239   CHRE_ASSERT(msg);
240   CHRE_ASSERT(msgLen);
241   bool success = false;
242 
243   // Initialize the pb message
244   SeeBufArg data = {
245     .buf = dataType,
246     .bufLen = strlen(dataType),
247   };
248   sns_suid_req req = {
249     .data_type.funcs.encode = copyPayload,
250     .data_type.arg = &data,
251   };
252 
253   if (!pb_get_encoded_size(msgLen, sns_suid_req_fields, &req)) {
254     LOGE("pb_get_encoded_size failed for sns_suid_req: %s", dataType);
255   } else if (*msgLen == 0) {
256     LOGE("Invalid pb encoded size for sns_suid_req");
257   } else {
258     UniquePtr<pb_byte_t> buf(static_cast<pb_byte_t *>(memoryAlloc(*msgLen)));
259     *msg = std::move(buf);
260     if (msg->isNull()) {
261       LOG_OOM();
262     } else {
263       pb_ostream_t stream = pb_ostream_from_buffer(msg->get(), *msgLen);
264 
265       success = pb_encode(&stream, sns_suid_req_fields, &req);
266       if (!success) {
267         LOG_NANOPB_ERROR(&stream);
268       }
269     }
270   }
271   return success;
272 }
273 
274 /**
275  * Encodes sns_std_sensor_config pb message.
276  *
277  * @param request The request to be encoded.
278  * @param msg A non-null pointer to the pb message unique pointer whose object
279  *            will be assigned here.
280  * @param msgLen A non-null pointer to the size of the encoded pb message.
281  *
282  * @return true if the pb message and length were obtained.
283  */
encodeSnsStdSensorConfig(const SeeSensorRequest & request,UniquePtr<pb_byte_t> * msg,size_t * msgLen)284 bool encodeSnsStdSensorConfig(const SeeSensorRequest& request,
285                               UniquePtr<pb_byte_t> *msg, size_t *msgLen) {
286   CHRE_ASSERT(msg);
287   CHRE_ASSERT(msgLen);
288   bool success = false;
289 
290   // Initialize the pb message
291   sns_std_sensor_config req = {
292     .sample_rate = request.samplingRateHz,
293   };
294 
295   if (!pb_get_encoded_size(msgLen, sns_std_sensor_config_fields, &req)) {
296     LOGE("pb_get_encoded_size failed for sns_std_sensor_config");
297   } else if (*msgLen == 0) {
298     LOGE("Invalid pb encoded size for sns_std_sensor_config");
299   } else {
300     UniquePtr<pb_byte_t> buf(static_cast<pb_byte_t *>(memoryAlloc(*msgLen)));
301     *msg = std::move(buf);
302     if (msg->isNull()) {
303       LOG_OOM();
304     } else {
305       pb_ostream_t stream = pb_ostream_from_buffer(msg->get(), *msgLen);
306 
307       success = pb_encode(&stream, sns_std_sensor_config_fields, &req);
308       if (!success) {
309         LOG_NANOPB_ERROR(&stream);
310       }
311     }
312   }
313   return success;
314 }
315 
encodeSnsRemoteProcSensorConfig(pb_byte_t * msgBuffer,size_t msgBufferSize,size_t * msgLen,sns_std_client_processor processorType)316 bool encodeSnsRemoteProcSensorConfig(pb_byte_t *msgBuffer, size_t msgBufferSize,
317                                      size_t *msgLen,
318                                      sns_std_client_processor processorType) {
319   CHRE_ASSERT(msgBuffer);
320   CHRE_ASSERT(msgLen);
321 
322   sns_remote_proc_state_config request = {
323     .proc_type = processorType,
324   };
325 
326   pb_ostream_t stream = pb_ostream_from_buffer(msgBuffer, msgBufferSize);
327   bool success = pb_encode(
328       &stream, sns_remote_proc_state_config_fields, &request);
329   if (!success) {
330     LOG_NANOPB_ERROR(&stream);
331   } else {
332     *msgLen = stream.bytes_written;
333   }
334 
335   return success;
336 }
337 
338 /**
339  * Prepares a sns_client_req message with provided payload.
340  */
prepSnsClientReq(sns_std_suid suid,uint32_t msgId,void * payload,size_t payloadLen,bool batchValid,uint32_t batchPeriodUs,bool passive,UniquePtr<sns_client_request_msg> * msg,SeeBufArg * data)341 bool prepSnsClientReq(sns_std_suid suid, uint32_t msgId,
342                       void *payload, size_t payloadLen,
343                       bool batchValid, uint32_t batchPeriodUs, bool passive,
344                       UniquePtr<sns_client_request_msg> *msg, SeeBufArg *data) {
345   CHRE_ASSERT(payload || payloadLen == 0);
346   CHRE_ASSERT(msg);
347   CHRE_ASSERT(data);
348   bool success = false;
349 
350   auto req = MakeUniqueZeroFill<sns_client_request_msg>();
351   if (req.isNull()) {
352     LOG_OOM();
353   } else {
354     success = true;
355 
356     // Initialize sns_client_request_msg to be sent
357     data->buf = payload,
358     data->bufLen = payloadLen,
359 
360     req->suid = suid;
361     req->msg_id = msgId;
362     req->susp_config.client_proc_type = SNS_STD_CLIENT_PROCESSOR_SSC;
363     req->susp_config.delivery_type = SNS_CLIENT_DELIVERY_WAKEUP;
364     req->request.has_batching = batchValid;
365     req->request.batching.batch_period = batchPeriodUs;
366     req->request.payload.funcs.encode = copyPayload;
367     req->request.payload.arg = data;
368     req->request.has_is_passive = true,
369     req->request.is_passive = passive,
370 
371     *msg = std::move(req);
372   }
373   return success;
374 }
375 
376 /**
377  * Helps decode a pb string field and passes the string to the calling function.
378  */
decodeStringField(pb_istream_t * stream,const pb_field_t * field,void ** arg)379 bool decodeStringField(pb_istream_t *stream, const pb_field_t *field,
380                        void **arg) {
381   auto *data = static_cast<SeeBufArg *>(*arg);
382   data->bufLen = stream->bytes_left;
383   data->buf = stream->state;
384 
385   bool success = pb_read(stream, nullptr /* buf */, stream->bytes_left);
386   if (!success) {
387     LOG_NANOPB_ERROR(stream);
388   }
389   return success;
390 }
391 
392 /**
393  * Decodes each SUID.
394  */
decodeSnsSuidEventSuid(pb_istream_t * stream,const pb_field_t * field,void ** arg)395 bool decodeSnsSuidEventSuid(pb_istream_t *stream, const pb_field_t *field,
396                             void **arg) {
397   sns_std_suid suid = {};
398   bool success = pb_decode(stream, sns_std_suid_fields, &suid);
399   if (!success) {
400     LOG_NANOPB_ERROR(stream);
401   } else {
402     auto *suids = static_cast<DynamicVector<sns_std_suid> *>(*arg);
403     suids->push_back(suid);
404   }
405   return success;
406 }
407 
decodeSnsSuidEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)408 bool decodeSnsSuidEvent(pb_istream_t *stream, const pb_field_t *field,
409                         void **arg) {
410   auto *info = static_cast<SeeInfoArg *>(*arg);
411   if (!suidsMatch(info->suid, kSuidLookup)) {
412     LOGE("SNS_SUID_MSGID_SNS_SUID_EVENT with incorrect SUID: 0x%" PRIx64
413          " %" PRIx64, info->suid.suid_high, info->suid.suid_low);
414   }
415 
416   SeeBufArg data;
417   DynamicVector<sns_std_suid> suids;
418   sns_suid_event event = {
419     .data_type.funcs.decode = decodeStringField,
420     .data_type.arg = &data,
421     .suid.funcs.decode = decodeSnsSuidEventSuid,
422     .suid.arg = &suids,
423   };
424 
425   bool success = pb_decode(stream, sns_suid_event_fields, &event);
426   if (!success) {
427     LOG_NANOPB_ERROR(stream);
428   } else {
429     // If syncData == nullptr, this indication is received outside of a sync
430     // call. If the decoded data type doesn't match the one we are waiting
431     // for, this indication is from a previous call (may be findSuidSync)
432     // and happens to arrive between another sync req/ind pair.
433     // Note that req/ind misalignment can still happen if findSuidSync is
434     // called again with the same data type.
435     // Note that there's no need to compare the SUIDs as no other calls
436     // but findSuidSync populate mWaitingDataType and can lead to a data
437     // type match.
438     if (info->sync->syncData == nullptr
439         || strncmp(info->sync->syncDataType,
440                    static_cast<const char *>(data.buf),
441                    std::min(data.bufLen, kSeeAttrStrValLen)) != 0) {
442       LOGW("Received late SNS_SUID_MSGID_SNS_SUID_EVENT indication");
443     } else {
444       info->sync->syncIndFound = true;
445       auto *outputSuids = static_cast<DynamicVector<sns_std_suid> *>(
446           info->sync->syncData);
447       for (const auto& suid : suids) {
448         outputSuids->push_back(suid);
449       }
450     }
451   }
452   return success;
453 }
454 
455 /**
456  * Decode messages defined in sns_suid.proto
457  */
decodeSnsSuidProtoEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)458 bool decodeSnsSuidProtoEvent(pb_istream_t *stream, const pb_field_t *field,
459                              void **arg) {
460   bool success = false;
461 
462   auto *info = static_cast<SeeInfoArg *>(*arg);
463   switch (info->msgId) {
464     case SNS_SUID_MSGID_SNS_SUID_EVENT:
465       success = decodeSnsSuidEvent(stream, field, arg);
466       break;
467 
468     default:
469       LOGW("Unhandled sns_suid.proto msg ID: %" PRIu32, info->msgId);
470       break;
471   }
472   return success;
473 }
474 
475 /**
476  * Defined in sns_std_sensor.pb.h
477  */
getAttrNameFromAttrId(int32_t id)478 const char *getAttrNameFromAttrId(int32_t id) {
479   switch (id) {
480     case SNS_STD_SENSOR_ATTRID_NAME:
481       return "NAME";
482     case SNS_STD_SENSOR_ATTRID_VENDOR:
483       return "VENDOR";
484     case SNS_STD_SENSOR_ATTRID_TYPE:
485       return "TYPE";
486     case SNS_STD_SENSOR_ATTRID_AVAILABLE:
487       return "AVAILABLE";
488     case SNS_STD_SENSOR_ATTRID_VERSION:
489       return "VERSION";
490     case SNS_STD_SENSOR_ATTRID_API:
491       return "API";
492     case SNS_STD_SENSOR_ATTRID_RATES:
493       return "RATES";
494     case SNS_STD_SENSOR_ATTRID_RESOLUTIONS:
495       return "RESOLUTIONS";
496     case SNS_STD_SENSOR_ATTRID_FIFO_SIZE:
497       return "FIFO_SIZE";
498     case SNS_STD_SENSOR_ATTRID_ACTIVE_CURRENT:
499       return "ACTIVE_CURRENT";
500     case SNS_STD_SENSOR_ATTRID_SLEEP_CURRENT:
501       return "SLEEP_CURRENT";
502     case SNS_STD_SENSOR_ATTRID_RANGES:
503       return "RANGES";
504     case SNS_STD_SENSOR_ATTRID_OP_MODES:
505       return "OP_MODES";
506     case SNS_STD_SENSOR_ATTRID_DRI:
507       return "DRI";
508     case SNS_STD_SENSOR_ATTRID_STREAM_SYNC:
509       return "STREAM_SYNC";
510     case SNS_STD_SENSOR_ATTRID_EVENT_SIZE:
511       return "EVENT_SIZE";
512     case SNS_STD_SENSOR_ATTRID_STREAM_TYPE:
513       return "STREAM_TYPE";
514     case SNS_STD_SENSOR_ATTRID_DYNAMIC:
515       return "DYNAMIC";
516     case SNS_STD_SENSOR_ATTRID_HW_ID:
517       return "HW_ID";
518     case SNS_STD_SENSOR_ATTRID_RIGID_BODY:
519       return "RIGID_BODY";
520     case SNS_STD_SENSOR_ATTRID_PLACEMENT:
521       return "PLACEMENT";
522     case SNS_STD_SENSOR_ATTRID_PHYSICAL_SENSOR:
523       return "PHYSICAL_SENSOR";
524     case SNS_STD_SENSOR_ATTRID_PHYSICAL_SENSOR_TESTS:
525       return "PHYSICAL_SENSOR_TESTS";
526     case SNS_STD_SENSOR_ATTRID_SELECTED_RESOLUTION:
527       return "SELECTED_RESOLUTION";
528     case SNS_STD_SENSOR_ATTRID_SELECTED_RANGE:
529       return "SELECTED_RANGE";
530     case SNS_STD_SENSOR_ATTRID_ADDITIONAL_LOW_LATENCY_RATES:
531       return "LOW_LATENCY_RATES";
532     case SNS_STD_SENSOR_ATTRID_PASSIVE_REQUEST:
533       return "PASSIVE_REQUEST";
534     default:
535       return "UNKNOWN ATTRIBUTE";
536   }
537 }
538 
539 /**
540  * Decodes each attribute field and passes the value to the calling function.
541  * For repeated fields of float or integers, only store the maximum and
542  * minimum values for the calling function.
543  */
decodeSnsStdAttrValue(pb_istream_t * stream,const pb_field_t * field,void ** arg)544 bool decodeSnsStdAttrValue(pb_istream_t *stream, const pb_field_t *field,
545                            void **arg) {
546   bool success = false;
547 
548   struct DecodeData {
549     SeeBufArg strData;
550     SeeAttrArg subtypeAttrArg;
551     sns_std_attr_value_data value;
552   };
553   auto data = MakeUniqueZeroFill<DecodeData>();
554 
555   if (data.isNull()) {
556     LOG_OOM();
557   } else {
558     data->value.str.funcs.decode = decodeStringField;
559     data->value.str.arg = &data->strData;
560     data->value.subtype.values.funcs.decode = decodeSnsStdAttrValue;
561     data->value.subtype.values.arg = &data->subtypeAttrArg;
562 
563     success = pb_decode(stream, sns_std_attr_value_data_fields, &data->value);
564     if (!success) {
565       LOG_NANOPB_ERROR(stream);
566     } else {
567       auto *attrVal = static_cast<SeeAttrArg *>(*arg);
568       if (data->value.has_flt) {
569         // If this is a float (repeated) field, initialize the union as floats
570         // to store the maximum and minmum values of the repeated fields.
571         if (!attrVal->initialized) {
572           attrVal->initialized = true;
573           attrVal->fltMin = FLT_MAX;
574           attrVal->fltMax = FLT_MIN;
575         }
576         if (data->value.flt < attrVal->fltMin) {
577           attrVal->fltMin = data->value.flt;
578         }
579         if (data->value.flt > attrVal->fltMax) {
580           attrVal->fltMax = data->value.flt;
581         }
582       } else if (data->value.has_sint) {
583         attrVal->int64 = data->value.sint;
584       } else if (data->value.has_boolean) {
585         attrVal->boolVal = data->value.boolean;
586       } else if (data->strData.buf != nullptr) {
587         strlcpy(attrVal->strVal, static_cast<const char *>(data->strData.buf),
588                 sizeof(attrVal->strVal));
589       } else if (!data->value.has_subtype) {
590         LOGW("Unknown attr type");
591       }
592     }
593   }
594   return success;
595 }
596 
decodeSnsStrAttr(pb_istream_t * stream,const pb_field_t * field,void ** arg)597 bool decodeSnsStrAttr(pb_istream_t *stream, const pb_field_t *field,
598                       void **arg) {
599   bool success = false;
600 
601   struct Decodedata {
602     SeeAttrArg attrArg;
603     sns_std_attr attr;
604   };
605   auto data = MakeUniqueZeroFill<Decodedata>();
606 
607   if (data.isNull()) {
608     LOG_OOM();
609   } else {
610     data->attr.value.values.funcs.decode = decodeSnsStdAttrValue;
611     data->attr.value.values.arg = &data->attrArg;
612 
613     success = pb_decode(stream, sns_std_attr_fields, &data->attr);
614     if (!success) {
615       LOG_NANOPB_ERROR(stream);
616     } else {
617       auto *attrData = static_cast<SeeAttributes *>(*arg);
618       switch (data->attr.attr_id) {
619         case SNS_STD_SENSOR_ATTRID_NAME:
620           strlcpy(attrData->name, data->attrArg.strVal, sizeof(attrData->name));
621           break;
622         case SNS_STD_SENSOR_ATTRID_VENDOR:
623           strlcpy(attrData->vendor, data->attrArg.strVal,
624                   sizeof(attrData->vendor));
625           break;
626         case SNS_STD_SENSOR_ATTRID_TYPE:
627           strlcpy(attrData->type, data->attrArg.strVal, sizeof(attrData->type));
628           break;
629         case SNS_STD_SENSOR_ATTRID_AVAILABLE:
630           if (!data->attrArg.boolVal) {
631             LOGW("%s: %d", getAttrNameFromAttrId(data->attr.attr_id),
632                  data->attrArg.boolVal);
633           }
634           break;
635         case SNS_STD_SENSOR_ATTRID_RATES:
636           attrData->maxSampleRate = data->attrArg.fltMax;
637           break;
638         case SNS_STD_SENSOR_ATTRID_STREAM_TYPE:
639           attrData->streamType = data->attrArg.int64;
640           break;
641         case SNS_STD_SENSOR_ATTRID_HW_ID:
642           attrData->hwId = data->attrArg.int64;
643           break;
644         case SNS_STD_SENSOR_ATTRID_PASSIVE_REQUEST:
645           attrData->passiveRequest = data->attrArg.boolVal;
646           break;
647         default:
648           break;
649       }
650     }
651   }
652   return success;
653 }
654 
decodeSnsStdAttrEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)655 bool decodeSnsStdAttrEvent(pb_istream_t *stream, const pb_field_t *field,
656                            void **arg) {
657   bool success = false;
658 
659   struct DecodeData {
660     SeeAttributes attr;
661     sns_std_attr_event event;
662   };
663   auto data = MakeUniqueZeroFill<DecodeData>();
664 
665   if (data.isNull()) {
666     LOG_OOM();
667   } else {
668     data->event.attributes.funcs.decode = decodeSnsStrAttr;
669     data->event.attributes.arg = &data->attr;
670 
671     success = pb_decode(stream, sns_std_attr_event_fields, &data->event);
672     if (!success) {
673       LOG_NANOPB_ERROR(stream);
674     } else {
675       auto *info = static_cast<SeeInfoArg *>(*arg);
676 
677       // If syncData == nullptr, this indication is received outside of a sync
678       // call. If the decoded SUID doesn't match the one we are waiting for,
679       // this indication is from a previous getAttributes call and happens to
680       // arrive between a later findAttributesSync req/ind pair.
681       // Note that req/ind misalignment can still happen if getAttributesSync is
682       // called again with the same SUID.
683       if (info->sync->syncData == nullptr
684           || !suidsMatch(info->suid, info->sync->syncSuid)) {
685         LOGW("Received late SNS_STD_MSGID_SNS_STD_ATTR_EVENT indication");
686       } else {
687         info->sync->syncIndFound = true;
688         memcpy(info->sync->syncData, &data->attr, sizeof(data->attr));
689       }
690     }
691   }
692   return success;
693 }
694 
695 /**
696  * Decode messages defined in sns_std.proto
697  */
decodeSnsStdProtoEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)698 bool decodeSnsStdProtoEvent(pb_istream_t *stream, const pb_field_t *field,
699                             void **arg) {
700   bool success = false;
701 
702   auto *info = static_cast<SeeInfoArg *>(*arg);
703   switch (info->msgId) {
704     case SNS_STD_MSGID_SNS_STD_ATTR_EVENT:
705       success = decodeSnsStdAttrEvent(stream, field, arg);
706       break;
707 
708     case SNS_STD_MSGID_SNS_STD_FLUSH_EVENT:
709       // An empty message.
710       success = true;
711       break;
712 
713     case SNS_STD_MSGID_SNS_STD_ERROR_EVENT: {
714       sns_std_error_event event = {};
715       success = pb_decode(stream, sns_std_error_event_fields, &event);
716       if (!success) {
717         LOG_NANOPB_ERROR(stream);
718       } else {
719         LOGW("SNS_STD_MSGID_SNS_STD_ERROR_EVENT: %d", event.error);
720       }
721       break;
722     }
723 
724     default:
725       LOGW("Unhandled sns_std.proto msg ID %" PRIu32, info->msgId);
726   }
727   return success;
728 }
729 
730 // TODO: Support compensation matrix and scaling factor calibration
applyThreeAxisCalibration(chreSensorThreeAxisData::chreSensorThreeAxisSampleData * sample,const float * val,const SeeCalData * cal)731 void applyThreeAxisCalibration(
732     chreSensorThreeAxisData::chreSensorThreeAxisSampleData *sample,
733     const float *val, const SeeCalData *cal) {
734   float bias[3] = {};
735   if (cal != nullptr && cal->hasBias) {
736     memcpy(bias, cal->bias, sizeof(bias));
737   }
738   sample->x = val[0] - bias[0];
739   sample->y = val[1] - bias[1];
740   sample->z = val[2] - bias[2];
741 }
742 
populateEventSample(SeeDataArg * data,const float * val)743 void populateEventSample(SeeDataArg *data, const float *val) {
744   size_t index = data->sampleIndex;
745   if (!data->event.isNull() && index < data->totalSamples) {
746     SensorSampleType sampleType = getSensorSampleTypeFromSensorType(
747         data->sensorType);
748 
749     uint32_t *timestampDelta = nullptr;
750     switch (sampleType) {
751       case SensorSampleType::ThreeAxis: {
752         auto *event = reinterpret_cast<chreSensorThreeAxisData *>(
753             data->event.get());
754         applyThreeAxisCalibration(&event->readings[index], val, data->cal);
755         timestampDelta = &event->readings[index].timestampDelta;
756         break;
757       }
758 
759       case SensorSampleType::Float: {
760         auto *event = reinterpret_cast<chreSensorFloatData *>(
761             data->event.get());
762         event->readings[index].value = val[0];
763         timestampDelta = &event->readings[index].timestampDelta;
764         break;
765       }
766 
767       case SensorSampleType::Byte: {
768         auto *event = reinterpret_cast<chreSensorByteData *>(data->event.get());
769         event->readings[index].value = 0;
770         event->readings[index].isNear = (val[0] > 0.5f);
771         timestampDelta = &event->readings[index].timestampDelta;
772         break;
773       }
774 
775       case SensorSampleType::Occurrence: {
776         auto *event = reinterpret_cast<chreSensorOccurrenceData *>(
777             data->event.get());
778         timestampDelta = &event->readings[index].timestampDelta;
779         break;
780       }
781 
782 #ifdef CHREX_SENSOR_SUPPORT
783       case SensorSampleType::Vendor0: {
784         auto *event = reinterpret_cast<chrexSensorVendor0Data *>(
785             data->event.get());
786         memcpy(event->readings[index].values, val,
787                sizeof(event->readings[index].values));
788         timestampDelta = &event->readings[index].timestampDelta;
789         break;
790       }
791 
792       case SensorSampleType::Vendor1: {
793         auto *event = reinterpret_cast<chrexSensorVendor1Data *>(
794             data->event.get());
795         memcpy(event->readings[index].values, val,
796                sizeof(event->readings[index].values));
797         timestampDelta = &event->readings[index].timestampDelta;
798         break;
799       }
800 
801       case SensorSampleType::Vendor2: {
802         auto *event = reinterpret_cast<chrexSensorVendor2Data *>(
803             data->event.get());
804         event->readings[index].value = *val;
805         timestampDelta = &event->readings[index].timestampDelta;
806         break;
807       }
808 #endif  // CHREX_SENSOR_SUPPORT
809 
810       default:
811         LOGE("Invalid sample type %" PRIu8, static_cast<uint8_t>(sampleType));
812     }
813 
814     if (data->sampleIndex == 0) {
815       auto *header = reinterpret_cast<chreSensorDataHeader *>(
816           data->event.get());
817       header->baseTimestamp = data->timeNs;
818       *timestampDelta = 0;
819     } else {
820       uint64_t delta = data->timeNs - data->prevTimeNs;
821       if (delta > UINT32_MAX) {
822         LOGE("Sensor %" PRIu8 " timestampDelta overflow: prev %" PRIu64
823              " curr %" PRIu64, static_cast<uint8_t>(data->sensorType),
824              data->prevTimeNs, data->timeNs);
825         delta = UINT32_MAX;
826       }
827       *timestampDelta = static_cast<uint32_t>(delta);
828     }
829     data->prevTimeNs = data->timeNs;
830   }
831 }
832 
833 /**
834  * Decodes a float array and ensures that the data doesn't go out of bound.
835  */
decodeFloatData(pb_istream_t * stream,const pb_field_t * field,void ** arg)836 bool decodeFloatData(pb_istream_t *stream, const pb_field_t *field,
837                      void **arg) {
838   auto *data = static_cast<SeeFloatArg *>(*arg);
839 
840   float value;
841   float *fltPtr = &value;
842   if (data->index >= ARRAY_SIZE(data->val)) {
843     LOGE("Float array length exceeds %zu", ARRAY_SIZE(data->val));
844   } else {
845     // Decode to the provided array only if it doesn't go out of bound.
846     fltPtr = &(data->val[data->index]);
847   }
848   // Increment index whether it's gone out of bounds or not.
849   (data->index)++;
850 
851   bool success = pb_decode_fixed32(stream, fltPtr);
852   if (!success) {
853     LOG_NANOPB_ERROR(stream);
854   }
855   return success;
856 }
857 
decodeSnsStdSensorPhysicalConfigEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)858 bool decodeSnsStdSensorPhysicalConfigEvent(
859     pb_istream_t *stream, const pb_field_t *field, void **arg) {
860   SeeBufArg data = {};
861   sns_std_sensor_physical_config_event event = {
862     .operation_mode.funcs.decode = decodeStringField,
863     .operation_mode.arg = &data,
864   };
865 
866   bool success = pb_decode(stream, sns_std_sensor_physical_config_event_fields,
867                            &event);
868   if (!success) {
869     LOG_NANOPB_ERROR(stream);
870   } else {
871     auto statusData =
872         MakeUniqueZeroFill<SeeHelperCallbackInterface::SamplingStatusData>();
873     if (statusData.isNull()) {
874       LOG_OOM();
875     } else {
876       struct chreSensorSamplingStatus *status = &statusData->status;
877 
878       if (event.has_sample_rate) {
879         statusData->intervalValid = true;
880         status->interval = static_cast<uint64_t>(
881             ceilf(Seconds(1).toRawNanoseconds() / event.sample_rate));
882       }
883 
884       // If operation_mode is populated, decoded string length will be > 0.
885       if (data.bufLen > 0) {
886         statusData->enabledValid = true;
887         status->enabled =
888             (strncmp(static_cast<const char *>(data.buf), kOpModeOff,
889                      std::min(data.bufLen, sizeof(kOpModeOff))) != 0);
890       }
891 
892       if (event.has_sample_rate || data.bufLen > 0) {
893         auto *info = static_cast<SeeInfoArg *>(*arg);
894         statusData->sensorType = info->data->sensorType;
895         info->data->status = std::move(statusData);
896       }
897     }
898   }
899   return success;
900 }
901 
decodeSnsStdSensorEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)902 bool decodeSnsStdSensorEvent(pb_istream_t *stream, const pb_field_t *field,
903                              void **arg) {
904   SeeFloatArg sample = {};
905   sns_std_sensor_event event = {
906     .data.funcs.decode = decodeFloatData,
907     .data.arg = &sample,
908   };
909 
910   bool success = pb_decode(stream, sns_std_sensor_event_fields, &event);
911   if (!success) {
912     LOG_NANOPB_ERROR(stream);
913   } else {
914     auto *info = static_cast<SeeInfoArg *>(*arg);
915     populateEventSample(info->data, sample.val);
916   }
917   return success;
918 }
919 
920 /**
921  * Decode messages defined in sns_std_sensor.proto
922  */
decodeSnsStdSensorProtoEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)923 bool decodeSnsStdSensorProtoEvent(pb_istream_t *stream, const pb_field_t *field,
924                                   void **arg) {
925   bool success = false;
926 
927   auto *info = static_cast<SeeInfoArg *>(*arg);
928   switch (info->msgId) {
929     case SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_PHYSICAL_CONFIG_EVENT:
930       success = decodeSnsStdSensorPhysicalConfigEvent(stream, field, arg);
931       break;
932 
933     case SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_EVENT:
934       success = decodeSnsStdSensorEvent(stream, field, arg);
935       break;
936 
937     default:
938       LOGW("Unhandled sns_std_sensor.proto msg ID %" PRIu32, info->msgId);
939   }
940   return success;
941 }
942 
decodeSnsCalEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)943 bool decodeSnsCalEvent(pb_istream_t *stream, const pb_field_t *field,
944                        void **arg) {
945   SeeFloatArg offset = {};
946   SeeFloatArg scale = {};
947   SeeFloatArg matrix = {};
948   sns_cal_event event = {
949     .bias.funcs.decode = decodeFloatData,
950     .bias.arg = &offset,
951     .scale_factor.funcs.decode = decodeFloatData,
952     .scale_factor.arg = &scale,
953     .comp_matrix.funcs.decode = decodeFloatData,
954     .comp_matrix.arg = &matrix,
955   };
956 
957   bool success = pb_decode(stream, sns_cal_event_fields, &event);
958   if (!success) {
959     LOG_NANOPB_ERROR(stream);
960   } else {
961     auto *info = static_cast<SeeInfoArg *>(*arg);
962     SeeCalInfo *calInfo = info->calInfo;
963     size_t calIndex = getCalIndexFromSuid(info->suid, calInfo);
964     if (calIndex >= kNumSeeCalSensors) {
965       LOGW("Cal sensor index out of bounds 0x%" PRIx64 " %" PRIx64,
966            info->suid.suid_high, info->suid.suid_low);
967     } else {
968       SeeCalData *cal = &calInfo[calIndex].cal;
969 
970       cal->hasBias = (offset.index == 3);
971       if (cal->hasBias) {
972         memcpy(cal->bias, offset.val, sizeof(cal->bias));
973       }
974 
975       cal->hasScale = (scale.index == 3);
976       if (cal->hasScale) {
977         memcpy(cal->scale, scale.val, sizeof(cal->scale));
978       }
979 
980       cal->hasMatrix = (matrix.index == 9);
981       if (cal->hasScale) {
982         memcpy(cal->matrix, matrix.val, sizeof(cal->matrix));
983       }
984 
985       cal->accuracy = static_cast<uint8_t>(event.status);
986     }
987   }
988   return success;
989 }
990 
991 /**
992  * Decode messages defined in sns_cal.proto
993  */
decodeSnsCalProtoEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)994 bool decodeSnsCalProtoEvent(pb_istream_t *stream, const pb_field_t *field,
995                             void **arg) {
996   bool success = false;
997 
998   auto *info = static_cast<SeeInfoArg *>(*arg);
999   switch (info->msgId) {
1000     case SNS_CAL_MSGID_SNS_CAL_EVENT:
1001       success = decodeSnsCalEvent(stream, field, arg);
1002       break;
1003 
1004     default:
1005       LOGW("Unhandled sns_cal.proto msg ID %" PRIu32, info->msgId);
1006   }
1007   return success;
1008 }
1009 
decodeSnsProximityEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)1010 bool decodeSnsProximityEvent(pb_istream_t *stream, const pb_field_t *field,
1011                              void **arg) {
1012   sns_proximity_event event = {};
1013 
1014   bool success = pb_decode(stream, sns_proximity_event_fields, &event);
1015   if (!success) {
1016     LOG_NANOPB_ERROR(stream);
1017   } else {
1018     float value = static_cast<float>(event.proximity_event_type);
1019     auto *info = static_cast<SeeInfoArg *>(*arg);
1020     populateEventSample(info->data, &value);
1021   }
1022   return success;
1023 }
1024 
1025 /**
1026  * Decode messages defined in sns_proximity.proto
1027  */
decodeSnsProximityProtoEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)1028 bool decodeSnsProximityProtoEvent(pb_istream_t *stream, const pb_field_t *field,
1029                                   void **arg) {
1030   bool success = false;
1031 
1032   auto *info = static_cast<SeeInfoArg *>(*arg);
1033   switch (info->msgId) {
1034     case SNS_PROXIMITY_MSGID_SNS_PROXIMITY_EVENT:
1035       success = decodeSnsProximityEvent(stream, field, arg);
1036       break;
1037 
1038     default:
1039       LOGW("Unhandled sns_proximity.proto msg ID %" PRIu32, info->msgId);
1040   }
1041   return success;
1042 }
1043 
decodeSnsRemoteProcStateEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)1044 bool decodeSnsRemoteProcStateEvent(
1045     pb_istream_t *stream, const pb_field_t *field, void **arg) {
1046   sns_remote_proc_state_event event = sns_remote_proc_state_event_init_default;
1047   bool success = pb_decode(stream, sns_remote_proc_state_event_fields, &event);
1048   if (!success) {
1049     LOG_NANOPB_ERROR(stream);
1050   } else if (event.proc_type == SNS_STD_CLIENT_PROCESSOR_APSS) {
1051     auto *info = static_cast<SeeInfoArg *>(*arg);
1052     info->data->isHostWakeSuspendEvent = true;
1053     info->data->isHostAwake =
1054         (event.event_type == SNS_REMOTE_PROC_STATE_AWAKE);
1055   }
1056   return success;
1057 }
1058 
1059 /**
1060  * Decode messages defined in sns_remote_proc_state.proto
1061  */
decodeSnsRemoteProcProtoEvent(pb_istream_t * stream,const pb_field_t * field,void ** arg)1062 bool decodeSnsRemoteProcProtoEvent(
1063     pb_istream_t *stream, const pb_field_t *field, void **arg) {
1064   bool success = false;
1065   auto *info = static_cast<SeeInfoArg *>(*arg);
1066   switch (info->msgId) {
1067     case SNS_REMOTE_PROC_STATE_MSGID_SNS_REMOTE_PROC_STATE_EVENT:
1068       success = decodeSnsRemoteProcStateEvent(stream, field, arg);
1069       break;
1070 
1071     default:
1072       LOGW("Unhandled sns_remote_proc_state.proto msg ID %" PRIu32,
1073            info->msgId);
1074   }
1075   return success;
1076 }
1077 
assignPayloadCallback(const SeeInfoArg * info,pb_callback_t * payload)1078 bool assignPayloadCallback(const SeeInfoArg *info, pb_callback_t *payload) {
1079   bool success = true;
1080 
1081   payload->arg = const_cast<SeeInfoArg *>(info);
1082 
1083   if (info->remoteProcSuid->has_value()
1084       && suidsMatch(info->suid, info->remoteProcSuid->value())) {
1085     payload->funcs.decode = decodeSnsRemoteProcProtoEvent;
1086   } else if (suidsMatch(info->suid, kSuidLookup)) {
1087     payload->funcs.decode = decodeSnsSuidProtoEvent;
1088   } else {
1089     // Assumed: "real" sensors SUIDs
1090     switch (info->msgId) {
1091       case SNS_STD_MSGID_SNS_STD_ATTR_EVENT:
1092       case SNS_STD_MSGID_SNS_STD_FLUSH_EVENT:
1093       case SNS_STD_MSGID_SNS_STD_ERROR_EVENT:
1094         payload->funcs.decode = decodeSnsStdProtoEvent;
1095         break;
1096 
1097       case SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_PHYSICAL_CONFIG_EVENT:
1098       case SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_EVENT:
1099         payload->funcs.decode = decodeSnsStdSensorProtoEvent;
1100         break;
1101 
1102       case SNS_CAL_MSGID_SNS_CAL_EVENT:
1103         payload->funcs.decode = decodeSnsCalProtoEvent;
1104         break;
1105 
1106       case SNS_PROXIMITY_MSGID_SNS_PROXIMITY_EVENT:
1107         payload->funcs.decode = decodeSnsProximityProtoEvent;
1108         break;
1109 
1110       default:
1111         success = false;
1112         LOGW("Unhandled msg ID %" PRIu32, info->msgId);
1113     }
1114   }
1115   return success;
1116 }
1117 
1118 /**
1119  * Decodes only msg_id and timestamp defined in sns_client_event and converts
1120  * the timestamp to nanoseconds.
1121  */
decodeMsgIdAndTime(pb_istream_t * stream,uint32_t * msgId,uint64_t * timeNs)1122 bool decodeMsgIdAndTime(pb_istream_t *stream, uint32_t *msgId,
1123                         uint64_t *timeNs) {
1124   sns_client_event_msg_sns_client_event event = {};
1125 
1126   bool success = pb_decode(
1127       stream, sns_client_event_msg_sns_client_event_fields, &event);
1128   if (!success) {
1129     LOG_NANOPB_ERROR(stream);
1130   } else {
1131     *msgId = event.msg_id;
1132     *timeNs = getNanosecondsFromQTimerTicks(event.timestamp);
1133   }
1134   return success;
1135 }
1136 
1137 /**
1138  * Decodes pb-encoded message
1139  */
decodeSnsClientEventMsg(pb_istream_t * stream,const pb_field_t * field,void ** arg)1140 bool decodeSnsClientEventMsg(pb_istream_t *stream, const pb_field_t *field,
1141                              void **arg) {
1142   // Make a copy for data decoding.
1143   pb_istream_t streamCpy = *stream;
1144 
1145   auto *info = static_cast<SeeInfoArg *>(*arg);
1146   bool success = decodeMsgIdAndTime(stream, &info->msgId, &info->data->timeNs);
1147 
1148   if (success && !info->decodeMsgIdOnly) {
1149     sns_client_event_msg_sns_client_event event = {};
1150 
1151     // Payload callback must be assigned if and only if we want to decode beyond
1152     // msg ID.
1153     success = assignPayloadCallback(info, &event.payload);
1154     if (!success) {
1155       LOGE("No pb callback assigned");
1156     } else {
1157       success = pb_decode(&streamCpy,
1158                           sns_client_event_msg_sns_client_event_fields, &event);
1159       if (!success) {
1160         LOG_NANOPB_ERROR(&streamCpy);
1161       }
1162     }
1163   }
1164 
1165   // Increment sample count only after sensor event decoding.
1166   if (success
1167       && (info->msgId == SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_EVENT
1168           || info->msgId == SNS_PROXIMITY_MSGID_SNS_PROXIMITY_EVENT)) {
1169     info->data->sampleIndex++;
1170   }
1171   return success;
1172 }
1173 
1174 /**
1175  * Obtain the SensorType from the list of registered SensorInfos.
1176  */
getSensorTypeFromSensorInfo(sns_client * client,const sns_std_suid & suid,const DynamicVector<SeeHelper::SensorInfo> & sensorInfos)1177 SensorType getSensorTypeFromSensorInfo(
1178     sns_client *client, const sns_std_suid& suid,
1179     const DynamicVector<SeeHelper::SensorInfo>& sensorInfos) {
1180   bool suidFound = false;
1181   SensorType otherType;
1182   for (const auto& sensorInfo : sensorInfos) {
1183     if (suidsMatch(sensorInfo.suid, suid)) {
1184       suidFound = true;
1185       if (sensorInfo.client == client) {
1186         return sensorInfo.sensorType;
1187       }
1188       otherType = sensorInfo.sensorType;
1189     }
1190   }
1191 
1192   if (suidFound) {
1193     LOGE("Unmatched client: %p, SUID 0x%016" PRIx64 " %016" PRIx64,
1194              client, suid.suid_high, suid.suid_low);
1195     // TODO: remove after b/79993302 is resolved.
1196     for (const auto& sensorInfo : sensorInfos) {
1197       LOGE("  %p, 0x%016" PRIx64 " %016" PRIx64,
1198            sensorInfo.client,
1199            sensorInfo.suid.suid_high, sensorInfo.suid.suid_low);
1200     }
1201 
1202     // Return SensorType in the other sns_client that matches the SUID as a
1203     // backup plan.
1204     return otherType;
1205   }
1206   return SensorType::Unknown;
1207 }
1208 
1209 /**
1210  * Allocate event memory according to SensorType and the number of samples.
1211  */
allocateEvent(SensorType sensorType,size_t numSamples)1212 void *allocateEvent(SensorType sensorType, size_t numSamples) {
1213   SensorSampleType sampleType = getSensorSampleTypeFromSensorType(sensorType);
1214   size_t sampleSize = 0;
1215   switch (sampleType) {
1216     case SensorSampleType::ThreeAxis:
1217       sampleSize = sizeof(
1218           chreSensorThreeAxisData::chreSensorThreeAxisSampleData);
1219       break;
1220 
1221     case SensorSampleType::Float:
1222       sampleSize = sizeof(
1223           chreSensorFloatData::chreSensorFloatSampleData);
1224       break;
1225 
1226     case SensorSampleType::Byte:
1227       sampleSize = sizeof(
1228           chreSensorByteData::chreSensorByteSampleData);
1229       break;
1230 
1231     case SensorSampleType::Occurrence:
1232       sampleSize = sizeof(
1233           chreSensorOccurrenceData::chreSensorOccurrenceSampleData);
1234       break;
1235 
1236 #ifdef CHREX_SENSOR_SUPPORT
1237     case SensorSampleType::Vendor0:
1238       sampleSize = sizeof(chrexSensorVendor0SampleData);
1239       break;
1240 
1241     case SensorSampleType::Vendor1:
1242       sampleSize = sizeof(chrexSensorVendor1SampleData);
1243       break;
1244 
1245     case SensorSampleType::Vendor2:
1246       sampleSize = sizeof(chrexSensorVendor2SampleData);
1247       break;
1248 #endif  // CHREX_SENSOR_SUPPORT
1249 
1250     default:
1251       LOGE("Unhandled SensorSampleType for SensorType %" PRIu8,
1252            static_cast<uint8_t>(sensorType));
1253   }
1254 
1255   size_t memorySize = (sampleType == SensorSampleType::Unknown)
1256       ? 0 : (sizeof(chreSensorDataHeader) + numSamples * sampleSize);
1257   void *event = (memorySize == 0) ? nullptr : memoryAlloc(memorySize);
1258 
1259   if (event == nullptr && memorySize != 0) {
1260     LOG_OOM();
1261   }
1262   return event;
1263 }
1264 
1265 // Allocates the sensor event memory and partially populates the header.
prepareSensorEvent(SeeInfoArg & info)1266 bool prepareSensorEvent(SeeInfoArg& info) {
1267   bool success = false;
1268 
1269   UniquePtr<uint8_t> buf(static_cast<uint8 *>(
1270       allocateEvent(info.data->sensorType, info.data->sampleIndex)));
1271   info.data->event = std::move(buf);
1272 
1273   if (!info.data->event.isNull()) {
1274     success = true;
1275 
1276     info.data->prevTimeNs = 0;
1277 
1278     auto *header = reinterpret_cast<chreSensorDataHeader *>(
1279         info.data->event.get());
1280     memset(header->reserved, 0, sizeof(header->reserved));
1281     header->sensorHandle = getSensorHandleFromSensorType(
1282         info.data->sensorType);
1283     header->readingCount = info.data->sampleIndex;
1284 
1285     // Protect against out of bounds access in data decoding.
1286     info.data->totalSamples = info.data->sampleIndex;
1287 
1288     // Reset sampleIndex only after memory has been allocated and header
1289     // populated.
1290     info.data->sampleIndex = 0;
1291   }
1292   return success;
1293 }
1294 
1295 }  // anonymous namespace
1296 
1297 const SeeHelper::SnsClientApi SeeHelper::kDefaultApi = {
1298   .sns_client_init   = sns_client_init,
1299   .sns_client_deinit = sns_client_deinit,
1300   .sns_client_send   = sns_client_send,
1301 };
1302 
~SeeHelper()1303 SeeHelper::~SeeHelper() {
1304   for (auto *client : mSeeClients) {
1305     int status = mSnsClientApi->sns_client_deinit(client);
1306     if (status != 0) {
1307       LOGE("Failed to release sensor client: %d", status);
1308     }
1309   }
1310 }
1311 
handleSnsClientEventMsg(sns_client * client,const void * payload,size_t payloadLen)1312 void SeeHelper::handleSnsClientEventMsg(
1313     sns_client *client, const void *payload, size_t payloadLen) {
1314   CHRE_ASSERT(payload);
1315 
1316   pb_istream_t stream = pb_istream_from_buffer(
1317       static_cast<const pb_byte_t *>(payload), payloadLen);
1318 
1319   // Make a copy of the stream for sensor data decoding.
1320   pb_istream_t streamCpy = stream;
1321 
1322   struct DecodeData {
1323     SeeSyncArg syncArg = {};
1324     SeeDataArg dataArg = {};
1325     SeeInfoArg info = {};
1326     sns_client_event_msg event = {};
1327   };
1328   auto data = MakeUnique<DecodeData>();
1329 
1330   if (data.isNull()) {
1331     LOG_OOM();
1332   } else {
1333     // Only initialize fields that are not accessed in the main CHRE thread.
1334     data->info.client = client;
1335     data->info.sync = &data->syncArg;
1336     data->info.data = &data->dataArg;
1337     data->info.decodeMsgIdOnly = true;
1338     data->info.remoteProcSuid = &mRemoteProcSuid;
1339     data->info.calInfo = &mCalInfo[0];
1340     data->event.events.funcs.decode = decodeSnsClientEventMsg;
1341     data->event.events.arg = &data->info;
1342 
1343     // Decode only SUID and MSG ID to help further decode.
1344     if (!pb_decode(&stream, sns_client_event_msg_fields, &data->event)) {
1345       LOG_NANOPB_ERROR(&stream);
1346     } else {
1347       data->info.suid = data->event.suid;
1348       data->info.decodeMsgIdOnly = false;
1349       data->info.data->cal = getCalDataFromSuid(data->info.suid);
1350       data->info.data->sensorType = getSensorTypeFromSensorInfo(
1351           data->info.client, data->info.suid, mSensorInfos);
1352 
1353       mMutex.lock();
1354       bool synchronizedDecode = mWaitingOnInd;
1355       if (!synchronizedDecode) {
1356         // Early unlock, we're not going to use anything from the main thread.
1357         mMutex.unlock();
1358       } else {
1359         // Populate fields set by the main thread.
1360         data->info.sync->syncData = mSyncData;
1361         data->info.sync->syncDataType = mSyncDataType;
1362         data->info.sync->syncSuid = mSyncSuid;
1363       }
1364 
1365       if (data->info.data->sampleIndex > 0) {
1366         if (data->info.data->sensorType == SensorType::Unknown) {
1367           LOGE("Unhandled sensor data SUID 0x%016" PRIx64 " %016" PRIx64,
1368                data->info.suid.suid_high, data->info.suid.suid_low);
1369         } else if (!prepareSensorEvent(data->info)) {
1370           LOGE("Failed to prepare sensor event");
1371         }
1372       }
1373 
1374       if (!pb_decode(&streamCpy, sns_client_event_msg_fields, &data->event)) {
1375         LOG_NANOPB_ERROR(&streamCpy);
1376       } else if (synchronizedDecode && data->info.sync->syncIndFound) {
1377         mWaitingOnInd = false;
1378         mCond.notify_one();
1379       } else {
1380         if (data->info.data->isHostWakeSuspendEvent) {
1381           mCbIf->onHostWakeSuspendEvent(data->info.data->isHostAwake);
1382         }
1383         if (!data->info.data->event.isNull()) {
1384           mCbIf->onSensorDataEvent(
1385               data->info.data->sensorType, std::move(data->info.data->event));
1386         }
1387         if (!data->info.data->status.isNull()) {
1388           if (data->info.data->sensorType == SensorType::Unknown) {
1389             LOGE("Unhandled sensor status SUID 0x%016" PRIx64 " %016" PRIx64,
1390                  data->info.suid.suid_high, data->info.suid.suid_low);
1391           } else {
1392             mCbIf->onSamplingStatusUpdate(std::move(data->info.data->status));
1393           }
1394         }
1395       }
1396 
1397       if (synchronizedDecode) {
1398         mMutex.unlock();
1399       }
1400     }
1401   }
1402 }
1403 
handleSeeResp(uint32_t txnId,sns_std_error error)1404 void SeeHelper::handleSeeResp(uint32_t txnId, sns_std_error error) {
1405   LockGuard<Mutex> lock(mMutex);
1406   if (mWaitingOnResp && txnId == mCurrentTxnId) {
1407     mRespError = error;
1408     mWaitingOnResp = false;
1409     mCond.notify_one();
1410   }
1411 }
1412 
findSuidSync(const char * dataType,DynamicVector<sns_std_suid> * suids,uint8_t minNumSuids,uint32_t maxRetries,Milliseconds retryDelay)1413 bool SeeHelper::findSuidSync(const char *dataType,
1414                              DynamicVector<sns_std_suid> *suids,
1415                              uint8_t minNumSuids, uint32_t maxRetries,
1416                              Milliseconds retryDelay) {
1417   CHRE_ASSERT(suids != nullptr);
1418   CHRE_ASSERT(minNumSuids > 0);
1419 
1420   bool success = false;
1421   if (mSeeClients.empty()) {
1422     LOGE("Sensor client wasn't initialized");
1423   } else {
1424     UniquePtr<pb_byte_t> msg;
1425     size_t msgLen;
1426     if (encodeSnsSuidReq(dataType, &msg, &msgLen)) {
1427       // Sensor client service may come up before SEE sensors are enumerated. A
1428       // max dwell time is set and retries are performed as currently there's no
1429       // message indicating that SEE intialization is complete.
1430       uint32_t trialCount = 0;
1431       do {
1432         suids->clear();
1433         if (++trialCount > 1) {
1434           timer_sleep(retryDelay.getMilliseconds(), T_MSEC,
1435                       true /* non_deferrable */);
1436         }
1437 
1438         // Ignore failures from sendReq, we'll retry anyways (up to maxRetries)
1439         sendReq(sns_suid_sensor_init_default,
1440                 suids, dataType,
1441                 SNS_SUID_MSGID_SNS_SUID_REQ, msg.get(), msgLen,
1442                 false /* batchValid */, 0 /* batchPeriodUs */,
1443                 false /* passive */, true /* waitForIndication */);
1444       } while (suids->size() < minNumSuids && trialCount < maxRetries);
1445 
1446       success = (suids->size() >= minNumSuids);
1447       if (!success) {
1448         mHaveTimedOutOnSuidLookup = true;
1449       }
1450       if (trialCount > 1) {
1451         LOGD("Waited %" PRIu32 " ms for %s (found: %d)",
1452              static_cast<uint32_t>(trialCount * retryDelay.getMilliseconds()),
1453              dataType, success);
1454       }
1455     }
1456   }
1457 
1458   return success;
1459 }
1460 
getAttributesSync(const sns_std_suid & suid,SeeAttributes * attr)1461 bool SeeHelper::getAttributesSync(const sns_std_suid& suid,
1462                                   SeeAttributes *attr) {
1463   CHRE_ASSERT(attr);
1464   bool success = false;
1465 
1466   if (mSeeClients.empty()) {
1467     LOGE("Sensor client wasn't initialized");
1468   } else {
1469     UniquePtr<pb_byte_t> msg;
1470     size_t msgLen;
1471     success = encodeSnsStdAttrReq(&msg, &msgLen);
1472 
1473     if (success) {
1474       success = sendReq(suid, attr, nullptr /* syncDataType */,
1475                         SNS_STD_MSGID_SNS_STD_ATTR_REQ, msg.get(), msgLen,
1476                         false /* batchValid */, 0 /* batchPeriodUs */,
1477                         false /* passive */, true /* waitForIndication */);
1478     }
1479   }
1480   return success;
1481 }
1482 
init(SeeHelperCallbackInterface * cbIf,Microseconds timeout)1483 bool SeeHelper::init(SeeHelperCallbackInterface *cbIf, Microseconds timeout) {
1484   CHRE_ASSERT(cbIf);
1485 
1486   mCbIf = cbIf;
1487   sns_client *client;
1488 
1489   // Initialize cal/remote_proc_state sensors before making sensor data request.
1490   return (waitForService(&client, timeout)
1491           && mSeeClients.push_back(client)
1492           && initCalSensors()
1493           && initRemoteProcSensor());
1494 }
1495 
makeRequest(const SeeSensorRequest & request)1496 bool SeeHelper::makeRequest(const SeeSensorRequest& request) {
1497   bool success = false;
1498 
1499   const SensorInfo *sensorInfo = getSensorInfo(request.sensorType);
1500   if (sensorInfo == nullptr) {
1501     LOGE("SensorType %" PRIu8 " hasn't been registered",
1502          static_cast<uint8_t>(request.sensorType));
1503   } else {
1504     uint32_t msgId;
1505     UniquePtr<pb_byte_t> msg;
1506     size_t msgLen = 0;
1507 
1508     if (!request.enable) {
1509       // An empty message
1510       msgId = SNS_CLIENT_MSGID_SNS_CLIENT_DISABLE_REQ;
1511       success = true;
1512     } else if (sensorTypeIsContinuous(request.sensorType)) {
1513       msgId = SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG;
1514       success = encodeSnsStdSensorConfig(request, &msg, &msgLen);
1515     } else {
1516       msgId = SNS_STD_SENSOR_MSGID_SNS_STD_ON_CHANGE_CONFIG;
1517       // No sample rate needed to configure on-change or one-shot sensors.
1518       success = true;
1519     }
1520 
1521     if (success) {
1522       success = sendReq(sensorInfo->client, sensorInfo->suid,
1523                         nullptr /* syncData */, nullptr /* syncDataType */,
1524                         msgId, msg.get(), msgLen,
1525                         true /* batchValid */, request.batchPeriodUs,
1526                         request.passive, false /* waitForIndication */);
1527     }
1528   }
1529   return success;
1530 }
1531 
getCalSuidFromSensorType(SensorType sensorType) const1532 const sns_std_suid& SeeHelper::getCalSuidFromSensorType(
1533     SensorType sensorType) const {
1534   static sns_std_suid suid = sns_suid_sensor_init_zero;
1535 
1536   size_t calIndex = getCalIndexFromSensorType(sensorType);
1537   if (calIndex < kNumSeeCalSensors && mCalInfo[calIndex].suid.has_value()) {
1538     suid = mCalInfo[calIndex].suid.value();
1539   }
1540   return suid;
1541 }
1542 
1543 /**
1544  * Sends a request to SEE and waits for the response.
1545  */
sendSeeReqSync(sns_client * client,sns_client_request_msg * req,Nanoseconds timeoutResp)1546 bool SeeHelper::sendSeeReqSync(
1547     sns_client *client, sns_client_request_msg *req, Nanoseconds timeoutResp) {
1548   CHRE_ASSERT(client);
1549   CHRE_ASSERT(req);
1550   bool success = false;
1551 
1552   auto *cbData = memoryAlloc<SeeRespCbData>();
1553   if (cbData == nullptr) {
1554     LOG_OOM();
1555   } else {
1556     cbData->seeHelper = this;
1557 
1558     {
1559       LockGuard<Mutex> lock(mMutex);
1560       CHRE_ASSERT(!mWaitingOnResp);
1561       mWaitingOnResp = true;
1562       cbData->txnId = ++mCurrentTxnId;
1563     }
1564 
1565     int status = mSnsClientApi->sns_client_send(
1566         client, req, SeeHelper::seeRespCb, cbData);
1567     if (status != 0) {
1568       LOGE("Error sending SEE request %d", status);
1569       memoryFree(cbData);
1570     }
1571 
1572     {
1573       LockGuard<Mutex> lock(mMutex);
1574 
1575       if (status == 0) {
1576         bool waitSuccess = true;
1577 
1578         while (mWaitingOnResp && waitSuccess) {
1579           waitSuccess = mCond.wait_for(mMutex, timeoutResp);
1580         }
1581 
1582         if (!waitSuccess) {
1583           LOGE("SEE resp timed out after %" PRIu64 " ms",
1584                Milliseconds(timeoutResp).getMilliseconds());
1585         } else if (mRespError != SNS_STD_ERROR_NO_ERROR) {
1586           LOGE("SEE txn ID %" PRIu32 " failed with error %d",
1587                mCurrentTxnId, mRespError);
1588         } else {
1589           success = true;
1590         }
1591       }
1592       mWaitingOnResp = false;
1593     }
1594   }
1595   return success;
1596 }
1597 
sendReq(sns_client * client,const sns_std_suid & suid,void * syncData,const char * syncDataType,uint32_t msgId,void * payload,size_t payloadLen,bool batchValid,uint32_t batchPeriodUs,bool passive,bool waitForIndication,Nanoseconds timeoutResp,Nanoseconds timeoutInd)1598 bool SeeHelper::sendReq(
1599     sns_client *client, const sns_std_suid& suid,
1600     void *syncData, const char *syncDataType,
1601     uint32_t msgId, void *payload, size_t payloadLen,
1602     bool batchValid, uint32_t batchPeriodUs, bool passive,
1603     bool waitForIndication, Nanoseconds timeoutResp, Nanoseconds timeoutInd) {
1604   UniquePtr<sns_client_request_msg> msg;
1605   SeeBufArg data;
1606   bool success = false;
1607 
1608   if (prepSnsClientReq(suid, msgId, payload, payloadLen, batchValid,
1609                        batchPeriodUs, passive, &msg, &data)) {
1610     if (waitForIndication) {
1611       prepareWaitForInd(suid, syncData, syncDataType);
1612     }
1613 
1614     success = sendSeeReqSync(client, msg.get(), timeoutResp);
1615 
1616     if (waitForIndication) {
1617       success = waitForInd(success, timeoutInd);
1618     }
1619   }
1620   return success;
1621 }
1622 
prepareWaitForInd(const sns_std_suid & suid,void * syncData,const char * syncDataType)1623 void SeeHelper::prepareWaitForInd(const sns_std_suid& suid, void *syncData,
1624                                   const char *syncDataType) {
1625   LockGuard<Mutex> lock(mMutex);
1626   CHRE_ASSERT(!mWaitingOnInd);
1627   mWaitingOnInd = true;
1628 
1629   // Specify members needed for a sync call.
1630   mSyncSuid = suid;
1631   mSyncData = syncData;
1632   mSyncDataType = syncDataType;
1633 }
1634 
waitForInd(bool reqSent,Nanoseconds timeoutInd)1635 bool SeeHelper::waitForInd(bool reqSent, Nanoseconds timeoutInd) {
1636   bool success = reqSent;
1637 
1638   LockGuard<Mutex> lock(mMutex);
1639   CHRE_ASSERT(!mWaitingOnResp);
1640   if (reqSent) {
1641     bool waitSuccess = true;
1642 
1643     while (mWaitingOnInd && waitSuccess) {
1644       waitSuccess = mCond.wait_for(mMutex, timeoutInd);
1645     }
1646 
1647     if (!waitSuccess) {
1648       LOGE("SEE indication timed out after %" PRIu64 " ms",
1649            Milliseconds(timeoutInd).getMilliseconds());
1650       success = false;
1651     }
1652   }
1653   mWaitingOnInd = false;
1654 
1655   // Reset members needed for a sync call.
1656   mSyncSuid = sns_suid_sensor_init_zero;
1657   mSyncData = nullptr;
1658   mSyncDataType = nullptr;
1659 
1660   return success;
1661 }
1662 
seeIndCb(sns_client * client,void * msg,uint32_t msgLen,void * cbData)1663 void SeeHelper::seeIndCb(
1664     sns_client *client, void *msg, uint32_t msgLen, void *cbData) {
1665   auto *obj = static_cast<SeeHelper *>(cbData);
1666   obj->handleSnsClientEventMsg(client, msg, msgLen);
1667 }
1668 
seeRespCb(sns_client * client,sns_std_error error,void * cbData)1669 void SeeHelper::seeRespCb(sns_client *client, sns_std_error error,
1670                               void *cbData) {
1671   auto *respCbData = static_cast<SeeRespCbData *>(cbData);
1672   respCbData->seeHelper->handleSeeResp(respCbData->txnId, error);
1673   memoryFree(cbData);
1674 }
1675 
registerSensor(SensorType sensorType,const sns_std_suid & suid,bool * prevRegistered)1676 bool SeeHelper::registerSensor(
1677     SensorType sensorType, const sns_std_suid& suid, bool *prevRegistered) {
1678   CHRE_ASSERT(sensorType != SensorType::Unknown);
1679   CHRE_ASSERT(prevRegistered != nullptr);
1680   bool success = false;
1681 
1682   // Check whether the SUID/SensorType pair has been previously registered.
1683   // Also count how many other SensorTypes the SUID has been registered with.
1684   *prevRegistered = false;
1685   size_t suidRegCount = 0;
1686   for (const auto& sensorInfo : mSensorInfos) {
1687     if (suidsMatch(suid, sensorInfo.suid)) {
1688       suidRegCount++;
1689       if (sensorInfo.sensorType == sensorType) {
1690         *prevRegistered = true;
1691       }
1692     }
1693   }
1694 
1695   // Initialize another SEE client if the SUID has been previously
1696   // registered with more SensorTypes than the number of SEE clients can
1697   // disambiguate.
1698   bool clientAvailable = true;
1699   if (mSeeClients.size() <= suidRegCount) {
1700     sns_client *client;
1701     clientAvailable = waitForService(&client);
1702     if (clientAvailable) {
1703       clientAvailable = mSeeClients.push_back(client);
1704     }
1705   }
1706 
1707   // Add a new entry only if this SUID/SensorType pair hasn't been registered.
1708   if (!*prevRegistered && clientAvailable) {
1709     SensorInfo sensorInfo = {
1710       .suid = suid,
1711       .sensorType = sensorType,
1712       .client = mSeeClients[suidRegCount],
1713     };
1714     success = mSensorInfos.push_back(sensorInfo);
1715   }
1716   return success;
1717 }
1718 
sensorIsRegistered(SensorType sensorType) const1719 bool SeeHelper::sensorIsRegistered(SensorType sensorType) const {
1720   return (getSensorInfo(sensorType) != nullptr);
1721 }
1722 
waitForService(sns_client ** client,Microseconds timeout)1723 bool SeeHelper::waitForService(sns_client **client,
1724                                Microseconds timeout) {
1725   CHRE_ASSERT(client);
1726 
1727   // TODO: add error_cb and error_cb_data.
1728   int status = mSnsClientApi->sns_client_init(
1729       client, timeout.getMilliseconds(),
1730       SeeHelper::seeIndCb, this /* ind_cb_data */,
1731       nullptr /* error_cb */, nullptr /* error_cb_data */);
1732 
1733   bool success = (status == 0);
1734   if (!success) {
1735     LOGE("Failed to initialize the sensor client: %d", status);
1736   }
1737   return success;
1738 }
1739 
initCalSensors()1740 bool SeeHelper::initCalSensors() {
1741   bool success = true;
1742 
1743   // Zero out mCalInfo to avoid accidental suid and data match.
1744   memset(mCalInfo, 0, sizeof(mCalInfo));
1745 
1746   const char *kCalTypes[] = {
1747     "accel_cal",
1748     "gyro_cal",
1749     "mag_cal",
1750   };
1751 
1752   // Find the cal sensor's SUID, assign it to mCalInfo, and make cal sensor data
1753   // request.
1754   DynamicVector<sns_std_suid> suids;
1755   for (size_t i = 0; i < ARRAY_SIZE(kCalTypes); i++) {
1756     const char *calType = kCalTypes[i];
1757     if (!findSuidSync(calType, &suids)) {
1758       success = false;
1759       LOGE("Failed to find sensor '%s'", calType);
1760     } else {
1761       size_t index = getCalIndexFromDataType(calType);
1762       if (index >= kNumSeeCalSensors) {
1763         success = false;
1764         LOGE("Cal sensor '%s' index out of bounds", calType);
1765       } else {
1766         mCalInfo[index].suid = suids[0];
1767 
1768         if (!sendReq(suids[0], nullptr /* syncData */,
1769                      nullptr /* syncDataType */,
1770                      SNS_STD_SENSOR_MSGID_SNS_STD_ON_CHANGE_CONFIG,
1771                      nullptr /* msg */, 0 /* msgLen */,
1772                      false /* batchValid */, 0 /* batchPeriodUs */,
1773                      false /* passive */, false /* waitForIndication */)) {
1774           success = false;
1775           LOGE("Failed to request '%s' data", calType);
1776         }
1777       }
1778     }
1779   }
1780 
1781   return success;
1782 }
1783 
initRemoteProcSensor()1784 bool SeeHelper::initRemoteProcSensor() {
1785   bool success = false;
1786 
1787   const char *kRemoteProcType = "remote_proc_state";
1788   DynamicVector<sns_std_suid> suids;
1789   if (!findSuidSync(kRemoteProcType, &suids)) {
1790     LOGE("Failed to find sensor '%s'", kRemoteProcType);
1791   } else {
1792     mRemoteProcSuid = suids[0];
1793 
1794     uint32_t msgId = SNS_REMOTE_PROC_STATE_MSGID_SNS_REMOTE_PROC_STATE_CONFIG;
1795     constexpr size_t kBufferSize = sns_remote_proc_state_config_size;
1796     pb_byte_t msgBuffer[kBufferSize];
1797     size_t msgLen;
1798     if (encodeSnsRemoteProcSensorConfig(msgBuffer, kBufferSize, &msgLen,
1799                                         SNS_STD_CLIENT_PROCESSOR_APSS)) {
1800       success = sendReq(mRemoteProcSuid.value(),
1801                         nullptr /* syncData */, nullptr /* syncDataType */,
1802                         msgId, msgBuffer, msgLen,
1803                         false /* batchValid */, 0 /* batchPeriodUs */,
1804                         false /* passive */, false /* waitForIndication */);
1805       if (!success) {
1806         LOGE("Failed to request '%s' config", kRemoteProcType);
1807       }
1808     }
1809   }
1810 
1811   return success;
1812 }
1813 
getCalDataFromSuid(const sns_std_suid & suid)1814 SeeCalData *SeeHelper::getCalDataFromSuid(const sns_std_suid& suid) {
1815   size_t calIndex = getCalIndexFromSuid(suid, mCalInfo);
1816   return (calIndex < kNumSeeCalSensors) ? &mCalInfo[calIndex].cal : nullptr;
1817 }
1818 
getSensorInfo(SensorType sensorType) const1819 const SeeHelper::SensorInfo *SeeHelper::getSensorInfo(
1820     SensorType sensorType) const {
1821   for (const auto& sensorInfo : mSensorInfos) {
1822     if (sensorInfo.sensorType == sensorType) {
1823       return &sensorInfo;
1824     }
1825   }
1826   return nullptr;
1827 }
1828 
1829 }  // namespace chre
1830