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