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