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