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