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