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