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