platform_sensor.cc revision 90db64e2ff34e67d967abf755c9dc2dd9a715079
138bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol/*
238bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * Copyright (C) 2016 The Android Open Source Project
338bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol *
438bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * Licensed under the Apache License, Version 2.0 (the "License");
538bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * you may not use this file except in compliance with the License.
638bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * You may obtain a copy of the License at
738bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol *
838bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol *      http://www.apache.org/licenses/LICENSE-2.0
938bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol *
1038bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * Unless required by applicable law or agreed to in writing, software
1138bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * distributed under the License is distributed on an "AS IS" BASIS,
1238bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1338bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * See the License for the specific language governing permissions and
1438bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * limitations under the License.
1538bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol */
1638bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
1748fda6e1eedf6ba80ae7596fc7676f8318a1e88eMeng-hsuan Chung#include <algorithm>
18cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol#include <cinttypes>
19cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
2038bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignolextern "C" {
2138bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
2283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol#include "fixed_point.h"
2338bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol#include "qmi_client.h"
2438bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol#include "sns_smgr_api_v01.h"
2501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung#include "sns_smgr_internal_api_v02.h"
2683a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol#include "timetick.h"
2738bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
2838bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol}  // extern "C"
2938bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
3083a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol#include "chre_api/chre/sensor.h"
31c807971625839bf4689435f24b6cacbf7dbb3de9Andrew Rossignol#include "chre/core/event_loop_manager.h"
323e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung#include "chre/platform/assert.h"
3338bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol#include "chre/platform/fatal_error.h"
3438bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol#include "chre/platform/log.h"
350d94eb2fcf599754d9a1087c3292ab6ac6495de6Andrew Rossignol#include "chre/platform/platform_sensor.h"
360d94eb2fcf599754d9a1087c3292ab6ac6495de6Andrew Rossignol#include "chre/platform/slpi/platform_sensor_util.h"
3780b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
3801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungnamespace chre {
3980b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignolnamespace {
4080b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
4101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung//! The timeout for QMI messages in milliseconds.
4201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungconstexpr uint32_t kQmiTimeoutMs = 1000;
4301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
4401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungconstexpr float kMicroTeslaPerGauss = 100.0f;
4501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
4601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung//! The QMI sensor service client handle.
4701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungqmi_client_type gPlatformSensorServiceQmiClientHandle = nullptr;
4801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
4901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung//! The QMI sensor internal service client handle.
5001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungqmi_client_type gPlatformSensorInternalServiceQmiClientHandle = nullptr;
5180b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
5283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol//! A sensor report indication for deserializing sensor sample indications
5383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol//! into. This global instance is used to avoid thrashy use of the heap by
5483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol//! allocating and freeing this on the heap for every new sensor sample. This
5583a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol//! relies on the assumption that the QMI callback is not reentrant.
563e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chungsns_smgr_buffering_ind_msg_v01 gSmgrBufferingIndMsg;
5783a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
5801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung//! A struct to store the sensor monitor status indication results.
5901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungstruct SensorStatus {
6001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  uint8_t sensorId;
6101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  uint8_t numClients;
6201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung};
6338bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
6401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung//! A vector that tracks the number clients of each supported sensorId.
6501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan ChungDynamicVector<SensorStatus> gSensorStatusMonitor;
669c8f6eb9f3429b0b8369e546ce2493b6c8829839Meng-hsuan Chung
6780b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol/**
68ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Converts a sensorId, dataType and calType as provided by SMGR to a
69ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * SensorType as used by platform-independent CHRE code. This is useful in
70ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * sensor discovery.
7183a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *
7283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param sensorId The sensorID as provided by the SMGR request for sensor info.
7383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param dataType The dataType for the sesnor as provided by the SMGR request
7483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *                 for sensor info.
75ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
76ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @return Returns the platform-independent sensor type or Unknown if no
7783a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *         match is found.
7883a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol */
79ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan ChungSensorType getSensorTypeFromSensorId(uint8_t sensorId, uint8_t dataType,
80ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung                                     uint8_t calType) {
81cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  // Here be dragons. These constants below are defined in
82cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  // sns_smgr_common_v01.h. Refer to the section labelled "Define sensor
83cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  // identifier" for more details. This function relies on the ordering of
84cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  // constants provided by their API. Do not change these values without care.
85cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  // You have been warned!
86cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  if (dataType == SNS_SMGR_DATA_TYPE_PRIMARY_V01) {
87cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    if (sensorId >= SNS_SMGR_ID_ACCEL_V01
88cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        && sensorId < SNS_SMGR_ID_GYRO_V01) {
89ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      if (calType == SNS_SMGR_CAL_SEL_FULL_CAL_V01) {
90ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::Accelerometer;
91ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      } else if (calType == SNS_SMGR_CAL_SEL_FACTORY_CAL_V01) {
92ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::UncalibratedAccelerometer;
93ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      }
94cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    } else if (sensorId >= SNS_SMGR_ID_GYRO_V01
95cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        && sensorId < SNS_SMGR_ID_MAG_V01) {
96ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      if (calType == SNS_SMGR_CAL_SEL_FULL_CAL_V01) {
97ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::Gyroscope;
98ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      } else if (calType == SNS_SMGR_CAL_SEL_FACTORY_CAL_V01) {
99ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::UncalibratedGyroscope;
100ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      }
101cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    } else if (sensorId >= SNS_SMGR_ID_MAG_V01
102cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        && sensorId < SNS_SMGR_ID_PRESSURE_V01) {
103ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      if (calType == SNS_SMGR_CAL_SEL_FULL_CAL_V01) {
104ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::GeomagneticField;
105ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      } else if (calType == SNS_SMGR_CAL_SEL_FACTORY_CAL_V01) {
106ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::UncalibratedGeomagneticField;
107ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      }
108cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    } else if (sensorId >= SNS_SMGR_ID_PRESSURE_V01
109cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        && sensorId < SNS_SMGR_ID_PROX_LIGHT_V01) {
110cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      return SensorType::Pressure;
111cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    } else if (sensorId >= SNS_SMGR_ID_PROX_LIGHT_V01
112cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        && sensorId < SNS_SMGR_ID_HUMIDITY_V01) {
113cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      return SensorType::Proximity;
114cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    }
115cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  } else if (dataType == SNS_SMGR_DATA_TYPE_SECONDARY_V01) {
116ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    if (sensorId >= SNS_SMGR_ID_ACCEL_V01
117ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        && sensorId < SNS_SMGR_ID_GYRO_V01) {
118ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      return SensorType::AccelerometerTemperature;
119ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    } else if (sensorId >= SNS_SMGR_ID_GYRO_V01
120ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        && sensorId < SNS_SMGR_ID_MAG_V01) {
121ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      return SensorType::GyroscopeTemperature;
122ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    } else if ((sensorId >= SNS_SMGR_ID_PROX_LIGHT_V01
123ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        && sensorId < SNS_SMGR_ID_HUMIDITY_V01)
124cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        || (sensorId >= SNS_SMGR_ID_ULTRA_VIOLET_V01
125cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol            && sensorId < SNS_SMGR_ID_OBJECT_TEMP_V01)) {
126cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      return SensorType::Light;
127cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    }
128cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  }
129cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
130cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  return SensorType::Unknown;
131cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol}
132cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
133cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol/**
134ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Converts a reportId as provided by SMGR to a SensorType.
135ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
136ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param reportId The reportID as provided by the SMGR buffering index.
137ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @return Returns the sensorType that corresponds to the reportId.
138ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
139ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan ChungSensorType getSensorTypeFromReportId(uint8_t reportId) {
140ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  SensorType sensorType;
141ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  if (reportId < static_cast<uint8_t>(SensorType::SENSOR_TYPE_COUNT)) {
142ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorType = static_cast<SensorType>(reportId);
143ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  } else {
144ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorType = SensorType::Unknown;
145ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  }
146ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  return sensorType;
147ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
148ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
149ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
150ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Converts a PlatformSensor to a unique report ID through SensorType. This is
151ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * useful in making sensor request.
152ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
153ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param sensorId The sensorID as provided by the SMGR request for sensor info.
154ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param dataType The dataType for the sesnor as provided by the SMGR request
155ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *                 for sensor info.
156ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
157ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @return Returns a unique report ID that is based on SensorType.
158ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
159ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chunguint8_t getReportId(uint8_t sensorId, uint8_t dataType, uint8_t calType) {
160ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  SensorType sensorType = getSensorTypeFromSensorId(
161ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      sensorId, dataType, calType);
162ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
163ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  CHRE_ASSERT_LOG(sensorType != SensorType::Unknown,
164ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung                  "sensorId %" PRIu8 ", dataType %" PRIu8 ", calType %" PRIu8,
165ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung                  sensorId, dataType, calType);
166ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  return static_cast<uint8_t>(sensorType);
167ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
168ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
169ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
170ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Checks whether the corresponding sensor is a sencondary temperature sensor.
171ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
172ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param reportId The reportID as provided by the SMGR buffering index.
173ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @return true if the sensor is a secondary temperature sensor.
174ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
175ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungbool isSecondaryTemperature(uint8_t reportId) {
176ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  SensorType sensorType = getSensorTypeFromReportId(reportId);
177ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  return (sensorType == SensorType::AccelerometerTemperature
178ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung          || sensorType == SensorType::GyroscopeTemperature);
179ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
180ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
181ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
182ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Verifies whether the buffering index's report ID matches the expected
183ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * indices length.
184ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
185ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @return true if it's a valid pair of indices length and report ID.
186ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
187ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungbool isValidIndicesLength() {
188ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  return ((gSmgrBufferingIndMsg.Indices_len == 1
189ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung           && !isSecondaryTemperature(gSmgrBufferingIndMsg.ReportId))
190ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung          || (gSmgrBufferingIndMsg.Indices_len == 2
191ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung              && isSecondaryTemperature(gSmgrBufferingIndMsg.ReportId)));
192ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
193ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
194ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
195ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Adds a Platform sensor to the sensor list.
196ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
197e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung * @param sensorInfo The sensorInfo as provided by the SMGR.
198ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
199ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param sensor The sensor list.
200ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
201e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chungvoid addPlatformSensor(const sns_smgr_sensor_datatype_info_s_v01& sensorInfo,
20248fda6e1eedf6ba80ae7596fc7676f8318a1e88eMeng-hsuan Chung                       uint8_t calType,
20348fda6e1eedf6ba80ae7596fc7676f8318a1e88eMeng-hsuan Chung                       DynamicVector<PlatformSensor> *sensors) {
204e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung  PlatformSensor platformSensor(static_cast<uint64_t>(
205e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung      Seconds(1).toRawNanoseconds() / sensorInfo.MaxSampleRate));
206e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung  platformSensor.sensorId = sensorInfo.SensorID;
207e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung  platformSensor.dataType = sensorInfo.DataType;
208ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  platformSensor.calType = calType;
20948fda6e1eedf6ba80ae7596fc7676f8318a1e88eMeng-hsuan Chung  size_t bytesToCopy = std::min(sizeof(platformSensor.sensorName) - 1,
21048fda6e1eedf6ba80ae7596fc7676f8318a1e88eMeng-hsuan Chung                                static_cast<size_t>(sensorInfo.SensorName_len));
21148fda6e1eedf6ba80ae7596fc7676f8318a1e88eMeng-hsuan Chung  memcpy(platformSensor.sensorName, sensorInfo.SensorName, bytesToCopy);
21248fda6e1eedf6ba80ae7596fc7676f8318a1e88eMeng-hsuan Chung  platformSensor.sensorName[bytesToCopy] = '\0';
213ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  if (!sensors->push_back(std::move(platformSensor))) {
214ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    FATAL_ERROR("Failed to allocate new sensor: out of memory");
215ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  }
216ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
217ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
218ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
21983a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * Converts SMGR ticks to nanoseconds as a uint64_t.
22083a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *
22183a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param ticks The number of ticks.
22283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @return The number of nanoseconds represented by the ticks value.
22383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol */
22483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignoluint64_t getNanosecondsFromSmgrTicks(uint32_t ticks) {
22583a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  return (ticks * Seconds(1).toRawNanoseconds())
22683a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol      / TIMETICK_NOMINAL_FREQ_HZ;
22783a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol}
22883a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
229c807971625839bf4689435f24b6cacbf7dbb3de9Andrew Rossignolvoid smgrSensorDataEventFree(uint16_t eventType, void *eventData) {
230c807971625839bf4689435f24b6cacbf7dbb3de9Andrew Rossignol  // Events are allocated using the simple memoryAlloc/memoryFree platform
231c807971625839bf4689435f24b6cacbf7dbb3de9Andrew Rossignol  // functions.
232c807971625839bf4689435f24b6cacbf7dbb3de9Andrew Rossignol  // TODO: Consider using a MemoryPool.
233c807971625839bf4689435f24b6cacbf7dbb3de9Andrew Rossignol  memoryFree(eventData);
234cea64a899fafc0e75dc0e63dbe699ca5679564adMeng-hsuan Chung
235cea64a899fafc0e75dc0e63dbe699ca5679564adMeng-hsuan Chung  // Remove all requests if it's a one-shot sensor and only after data has been
236cea64a899fafc0e75dc0e63dbe699ca5679564adMeng-hsuan Chung  // delivered to all clients.
237cea64a899fafc0e75dc0e63dbe699ca5679564adMeng-hsuan Chung  SensorType sensorType = getSensorTypeForSampleEventType(eventType);
238cea64a899fafc0e75dc0e63dbe699ca5679564adMeng-hsuan Chung  if (sensorTypeIsOneShot(sensorType)) {
239cea64a899fafc0e75dc0e63dbe699ca5679564adMeng-hsuan Chung    EventLoopManagerSingleton::get()->getSensorRequestManager()
240cea64a899fafc0e75dc0e63dbe699ca5679564adMeng-hsuan Chung        .removeAllRequests(sensorType);
241cea64a899fafc0e75dc0e63dbe699ca5679564adMeng-hsuan Chung  }
242c807971625839bf4689435f24b6cacbf7dbb3de9Andrew Rossignol}
243c807971625839bf4689435f24b6cacbf7dbb3de9Andrew Rossignol
24483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol/**
245bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung * Populate the header
246bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung */
247ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungvoid populateSensorDataHeader(
248ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    SensorType sensorType, chreSensorDataHeader *header,
249ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
2503e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung  uint64_t baseTimestamp = getNanosecondsFromSmgrTicks(
251ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      sensorIndex.FirstSampleTimestamp);
252bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung  memset(header->reserved, 0, sizeof(header->reserved));
2533e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung  header->baseTimestamp = baseTimestamp;
254bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung  header->sensorHandle = getSensorHandleFromSensorType(sensorType);
255ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  header->readingCount = sensorIndex.SampleCount;
256bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung}
257bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
258bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung/**
259bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung * Populate three-axis event data.
260bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung */
261ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungvoid populateThreeAxisEvent(
262ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    SensorType sensorType, chreSensorThreeAxisData *data,
263ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
264ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  populateSensorDataHeader(sensorType, &data->header, sensorIndex);
2653e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
266ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  for (size_t i = 0; i < sensorIndex.SampleCount; i++) {
2673e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    const sns_smgr_buffering_sample_s_v01& sensorData =
268ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        gSmgrBufferingIndMsg.Samples[i + sensorIndex.FirstSampleIdx];
2693e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
2703e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    // TimeStampOffset has max value of < 2 sec so it will not overflow here.
2713e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    data->readings[i].timestampDelta =
2723e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung        getNanosecondsFromSmgrTicks(sensorData.TimeStampOffset);
2733e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
2743e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    // Convert from SMGR's NED coordinate to Android coordinate.
2753e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    data->readings[i].x = FX_FIXTOFLT_Q16(sensorData.Data[1]);
2763e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    data->readings[i].y = FX_FIXTOFLT_Q16(sensorData.Data[0]);
2773e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    data->readings[i].z = -FX_FIXTOFLT_Q16(sensorData.Data[2]);
2783e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
2793e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    // Convert from Gauss to micro Tesla
280ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    if (sensorType == SensorType::GeomagneticField
281ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        || sensorType == SensorType::UncalibratedGeomagneticField) {
2823e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      data->readings[i].x *= kMicroTeslaPerGauss;
2833e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      data->readings[i].y *= kMicroTeslaPerGauss;
2843e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      data->readings[i].z *= kMicroTeslaPerGauss;
2853e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    }
2869c8f6eb9f3429b0b8369e546ce2493b6c8829839Meng-hsuan Chung  }
287bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung}
288bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
289bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung/**
290bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung * Populate float event data.
291bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung */
292ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungvoid populateFloatEvent(
293ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    SensorType sensorType, chreSensorFloatData *data,
294ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
295ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  populateSensorDataHeader(sensorType, &data->header, sensorIndex);
2963e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
297ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  for (size_t i = 0; i < sensorIndex.SampleCount; i++) {
2983e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    const sns_smgr_buffering_sample_s_v01& sensorData =
299ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        gSmgrBufferingIndMsg.Samples[i + sensorIndex.FirstSampleIdx];
3003e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
3013e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    // TimeStampOffset has max value of < 2 sec so it will not overflow.
3023e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    data->readings[i].timestampDelta =
3033e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung        getNanosecondsFromSmgrTicks(sensorData.TimeStampOffset);
3043e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    data->readings[i].value = FX_FIXTOFLT_Q16(sensorData.Data[0]);
3053e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung  }
306bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung}
307bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
308bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung/**
30990db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung * Populate byte event data.
31090db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung */
31190db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chungvoid populateByteEvent(
31290db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    SensorType sensorType, chreSensorByteData *data,
31390db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
31490db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung  populateSensorDataHeader(sensorType, &data->header, sensorIndex);
31590db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung
31690db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung  for (size_t i = 0; i < sensorIndex.SampleCount; i++) {
31790db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    const sns_smgr_buffering_sample_s_v01& sensorData =
31890db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung        gSmgrBufferingIndMsg.Samples[i + sensorIndex.FirstSampleIdx];
31990db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung
32090db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    // TimeStampOffset has max value of < 2 sec so it will not overflow.
32190db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    data->readings[i].timestampDelta =
32290db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung        getNanosecondsFromSmgrTicks(sensorData.TimeStampOffset);
32390db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    // Zero out fields invalid and padding0.
32490db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    data->readings[i].value = 0;
32590db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    // SMGR reports 1 in Q16 for near, and 0 for far.
32690db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    data->readings[i].isNear = sensorData.Data[0] ? 1 : 0;
32790db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung  }
32890db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung}
32990db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung
33090db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung/**
331bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung * Allocate event memory according to SensorType and populate event readings.
332bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung */
333ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungvoid *allocateAndPopulateEvent(
334ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    SensorType sensorType,
335ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
336bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung  SensorSampleType sampleType = getSensorSampleTypeFromSensorType(sensorType);
3373e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung  size_t memorySize = sizeof(chreSensorDataHeader);
338bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung  switch (sampleType) {
339bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung    case SensorSampleType::ThreeAxis: {
340ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      memorySize += sensorIndex.SampleCount *
3413e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung          sizeof(chreSensorThreeAxisData::chreSensorThreeAxisSampleData);
3423e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      auto *event =
3433e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung          static_cast<chreSensorThreeAxisData *>(memoryAlloc(memorySize));
344bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      if (event != nullptr) {
345ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        populateThreeAxisEvent(sensorType, event, sensorIndex);
346bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      }
347bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      return event;
348bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung    }
349bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
350bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung    case SensorSampleType::Float: {
351ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      memorySize += sensorIndex.SampleCount *
3523e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung          sizeof(chreSensorFloatData::chreSensorFloatSampleData);
3533e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      auto *event =
3543e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung          static_cast<chreSensorFloatData *>(memoryAlloc(memorySize));
355bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      if (event != nullptr) {
356ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        populateFloatEvent(sensorType, event, sensorIndex);
357bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      }
358bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      return event;
359bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung    }
360bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
36190db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    case SensorSampleType::Byte: {
36290db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung      memorySize += sensorIndex.SampleCount *
36390db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung          sizeof(chreSensorByteData::chreSensorByteSampleData);
36490db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung      auto *event =
36590db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung          static_cast<chreSensorByteData *>(memoryAlloc(memorySize));
36690db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung      if (event != nullptr) {
36790db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung        populateByteEvent(sensorType, event, sensorIndex);
36890db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung      }
36990db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung      return event;
37090db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    }
37190db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung
372bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung    default:
373bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      LOGW("Unhandled sensor data %" PRIu8, sensorType);
374bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      return nullptr;
375bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung  }
376bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung}
377bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
378bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung/**
37901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * Handles sensor data provided by the SMGR framework.
38083a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *
38183a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param userHandle The userHandle is used by the QMI decode function.
38283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param buffer The buffer to decode sensor data from.
38383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param bufferLength The size of the buffer to decode.
38483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol */
38583a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignolvoid handleSensorDataIndication(void *userHandle, void *buffer,
38683a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol                                unsigned int bufferLength) {
38783a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  int status = qmi_client_message_decode(
3883e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      userHandle, QMI_IDL_INDICATION, SNS_SMGR_BUFFERING_IND_V01, buffer,
3893e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      bufferLength, &gSmgrBufferingIndMsg,
3903e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      sizeof(sns_smgr_buffering_ind_msg_v01));
39183a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  if (status != QMI_NO_ERR) {
39283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol    LOGE("Error parsing sensor data indication %d", status);
39301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  } else {
39401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    // We only requested one sensor per request except for a secondary
395e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung    // temperature sensor.
39601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    bool validReport = isValidIndicesLength();
39701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    CHRE_ASSERT_LOG(validReport,
39801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                    "Got buffering indication from %" PRIu32
39901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                    " sensors with report ID %" PRIu8,
40001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                    gSmgrBufferingIndMsg.Indices_len,
40101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                    gSmgrBufferingIndMsg.ReportId);
40201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    if (validReport) {
40301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      // Identify the index for the desired sensor. It is always 0 except
40401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      // possibly for a secondary temperature sensor.
40501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      uint32_t index = 0;
40601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      if (isSecondaryTemperature(gSmgrBufferingIndMsg.ReportId)) {
40701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        index = (gSmgrBufferingIndMsg.Indices[0].DataType
40801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                 == SNS_SMGR_DATA_TYPE_SECONDARY_V01) ? 0 : 1;
40901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      }
41001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      const sns_smgr_buffering_sample_index_s_v01& sensorIndex =
41101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung          gSmgrBufferingIndMsg.Indices[index];
41201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
41301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      // Use ReportID to identify sensors as
41401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      // gSmgrBufferingIndMsg.Samples[i].Flags are not populated.
41501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      SensorType sensorType = getSensorTypeFromReportId(
41601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung          gSmgrBufferingIndMsg.ReportId);
41701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      if (sensorType == SensorType::Unknown) {
41801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        LOGW("Received sensor sample for unknown sensor %" PRIu8 " %" PRIu8,
41901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung             sensorIndex.SensorId, sensorIndex.DataType);
42083a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol      } else {
42101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        void *eventData = allocateAndPopulateEvent(sensorType, sensorIndex);
42201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        if (eventData == nullptr) {
42301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung          LOGW("Dropping event due to allocation failure");
42401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        } else {
42501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung          EventLoopManagerSingleton::get()->postEvent(
42601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung              getSampleEventTypeForSensorType(sensorType), eventData,
42701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung              smgrSensorDataEventFree);
42801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        }
42983a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol      }
430e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung    }  // if (validReport)
43183a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  }
43283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol}
43383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
43483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol/**
43583a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * This callback is invoked by the QMI framework when an asynchronous message is
43683a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * delivered. Unhandled messages are logged. The signature is defined by the QMI
43783a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * library.
43883a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *
43983a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param userHandle The userHandle is used by the QMI library.
44083a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param messageId The type of the message to decode.
44183a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param buffer The buffer to decode.
44283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param bufferLength The length of the buffer to decode.
44383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param callbackData Data that is provided as a context to this callback. This
44483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *                     is not used in this context.
44583a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol */
44601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungvoid platformSensorServiceQmiIndicationCallback(void *userHandle,
44701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                                                unsigned int messageId,
44801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                                                void *buffer,
44901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                                                unsigned int bufferLength,
45001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                                                void *callbackData) {
45183a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  switch (messageId) {
4523e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    case SNS_SMGR_BUFFERING_IND_V01:
45383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol      handleSensorDataIndication(userHandle, buffer, bufferLength);
45483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol      break;
45583a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol    default:
45601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      LOGW("Received unhandled sensor service message: 0x%x", messageId);
45783a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol      break;
45883a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  };
45983a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol}
46083a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
46101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chunguint8_t getNumClients(uint8_t sensorId) {
46201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  for (size_t i = 0; i < gSensorStatusMonitor.size(); i++) {
46301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    if (gSensorStatusMonitor[i].sensorId == sensorId) {
46401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      return gSensorStatusMonitor[i].numClients;
46501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    }
46683a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  }
46701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  return 0;
46801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
46983a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
47001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungvoid setNumClients(uint8_t sensorId, uint8_t numClients) {
47101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  for (size_t i = 0; i < gSensorStatusMonitor.size(); i++) {
47201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    if (gSensorStatusMonitor[i].sensorId == sensorId) {
47301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      gSensorStatusMonitor[i].numClients = numClients;
47401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    }
47501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
47601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
47701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
47801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung/**
47901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * Handles sensor status provided by the SMGR framework.
48001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung *
48101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * @param userHandle The userHandle is used by the QMI decode function.
48201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * @param buffer The buffer to decode sensor data from.
48301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * @param bufferLength The size of the buffer to decode.
48401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung */
48501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungvoid handleSensorStatusMonitorIndication(void *userHandle, void *buffer,
48601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                                         unsigned int bufferLength) {
48701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  sns_smgr_sensor_status_monitor_ind_msg_v02 smgrMonitorIndMsg;
48801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
48901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  int status = qmi_client_message_decode(
49001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      userHandle, QMI_IDL_INDICATION, SNS_SMGR_SENSOR_STATUS_MONITOR_IND_V02,
49101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      buffer, bufferLength, &smgrMonitorIndMsg, sizeof(smgrMonitorIndMsg));
49283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  if (status != QMI_NO_ERR) {
49301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    LOGE("Error parsing sensor status monitor indication %d", status);
49401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  } else {
49501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    uint8_t numClients = getNumClients(smgrMonitorIndMsg.sensor_id);
49601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    if (numClients != smgrMonitorIndMsg.num_clients) {
49701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      LOGD("Status: id %" PRIu64 ", num lients: curr %" PRIu8 " new %" PRIu8,
49801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung           smgrMonitorIndMsg.sensor_id, numClients,
49901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung           smgrMonitorIndMsg.num_clients);
50001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      setNumClients(smgrMonitorIndMsg.sensor_id,
50101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                    smgrMonitorIndMsg.num_clients);
50201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
50301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      //TODO: add onNumClientsChange()
50401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    }
50583a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  }
50683a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol}
50783a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
50801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung/**
50901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * This callback is invoked by the QMI framework when an asynchronous message is
51001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * delivered. Unhandled messages are logged. The signature is defined by the QMI
51101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * library.
51201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung *
51301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * @param userHandle The userHandle is used by the QMI library.
51401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * @param messageId The type of the message to decode.
51501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * @param buffer The buffer to decode.
51601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * @param bufferLength The length of the buffer to decode.
51701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * @param callbackData Data that is provided as a context to this callback. This
51801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung *                     is not used in this context.
51901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung */
52001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungvoid platformSensorInternalServiceQmiIndicationCallback(void *userHandle,
52101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    unsigned int messageId, void *buffer, unsigned int bufferLength,
52201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    void *callbackData) {
52301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  switch (messageId) {
52401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    case SNS_SMGR_SENSOR_STATUS_MONITOR_IND_V02:
52501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      handleSensorStatusMonitorIndication(userHandle, buffer, bufferLength);
52601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      break;
52701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    default:
52801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      LOGW("Received unhandled sensor internal service message: 0x%x",
52901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung           messageId);
53001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      break;
53101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  };
53201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
53301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
53401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungvoid setSensorStatusMonitor(uint8_t sensorId, bool enable) {
53501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  sns_smgr_sensor_status_monitor_req_msg_v02 monitorRequest;
53601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  sns_smgr_sensor_status_monitor_resp_msg_v02 monitorResponse;
53701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  monitorRequest.sensor_id = sensorId;
53801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  monitorRequest.registering = enable ? TRUE : FALSE;
53901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
54001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  qmi_client_error_type status = qmi_client_send_msg_sync(
54101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      gPlatformSensorInternalServiceQmiClientHandle,
54201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      SNS_SMGR_SENSOR_STATUS_MONITOR_REQ_V02,
54301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      &monitorRequest, sizeof(monitorRequest),
54401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      &monitorResponse, sizeof(monitorResponse), kQmiTimeoutMs);
54501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
54601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  if (status != QMI_NO_ERR) {
54701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    LOGE("Error setting sensor status monitor: %d", status);
54801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  } else if (monitorResponse.resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
54901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    LOGE("Sensor status monitor request failed with error: %" PRIu8
55001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung         " sensor ID %" PRIu8 " enable %d",
55101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung         monitorResponse.resp.sns_err_t, sensorId, enable);
55201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
55383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol}
55483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
55583a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol/**
556cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol * Requests the sensors for a given sensor ID and appends them to the provided
557cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol * list of sensors. If an error occurs, false is returned.
558cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol *
559cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol * @param sensorId The sensor ID to request sensor info for.
560cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol * @param sensors The list of sensors to append newly found sensors to.
561cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol * @return Returns false if an error occurs.
562cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol */
563cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignolbool getSensorsForSensorId(uint8_t sensorId,
564cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol                           DynamicVector<PlatformSensor> *sensors) {
565cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  sns_smgr_single_sensor_info_req_msg_v01 sensorInfoRequest;
566cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  sns_smgr_single_sensor_info_resp_msg_v01 sensorInfoResponse;
567cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
568cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  sensorInfoRequest.SensorID = sensorId;
569cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
570cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  qmi_client_error_type status = qmi_client_send_msg_sync(
57101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      gPlatformSensorServiceQmiClientHandle, SNS_SMGR_SINGLE_SENSOR_INFO_REQ_V01,
572cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      &sensorInfoRequest, sizeof(sns_smgr_single_sensor_info_req_msg_v01),
573cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      &sensorInfoResponse, sizeof(sns_smgr_single_sensor_info_resp_msg_v01),
574cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      kQmiTimeoutMs);
575cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
576cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  bool success = false;
577cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  if (status != QMI_NO_ERR) {
578cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    LOGE("Error requesting single sensor info: %d", status);
579cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  } else if (sensorInfoResponse.Resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
580cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    LOGE("Single sensor info request failed with error: %d",
581cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol         sensorInfoResponse.Resp.sns_err_t);
582cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  } else {
58301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    bool isSensorIdSupported = false;
584cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    const sns_smgr_sensor_info_s_v01& sensorInfoList =
585cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        sensorInfoResponse.SensorInfo;
586cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    for (uint32_t i = 0; i < sensorInfoList.data_type_info_len; i++) {
587e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung      const sns_smgr_sensor_datatype_info_s_v01& sensorInfo =
588e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung          sensorInfoList.data_type_info[i];
589ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      LOGD("SensorID %" PRIu8 ", DataType %" PRIu8 ", MaxRate %" PRIu16
590ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung           "Hz, SensorName %s",
591e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung           sensorInfo.SensorID, sensorInfo.DataType,
592e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung           sensorInfo.MaxSampleRate, sensorInfo.SensorName);
593ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
594ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      SensorType sensorType = getSensorTypeFromSensorId(
595e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung          sensorInfo.SensorID, sensorInfo.DataType,
596ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung          SNS_SMGR_CAL_SEL_FULL_CAL_V01);
597cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      if (sensorType != SensorType::Unknown) {
59801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        isSensorIdSupported = true;
599e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung        addPlatformSensor(sensorInfo, SNS_SMGR_CAL_SEL_FULL_CAL_V01, sensors);
600ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
601ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        // Add an uncalibrated version if defined.
602ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        SensorType uncalibratedType = getSensorTypeFromSensorId(
603e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung            sensorInfo.SensorID, sensorInfo.DataType,
604ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung            SNS_SMGR_CAL_SEL_FACTORY_CAL_V01);
605ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        if (sensorType != uncalibratedType) {
606e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung          addPlatformSensor(sensorInfo, SNS_SMGR_CAL_SEL_FACTORY_CAL_V01,
607e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung                            sensors);
608cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        }
609cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      }
610cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    }
611cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
61201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    // If CHRE supports sensors with this sensor ID, enable its status monitor.
61301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    if (isSensorIdSupported) {
61401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      // Initialize monitor status before making a QMI request.
61501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      SensorStatus sensorStatus;
61601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      sensorStatus.sensorId = sensorId;
61701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      sensorStatus.numClients = 0;
61801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      gSensorStatusMonitor.push_back(sensorStatus);
619cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
62001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      setSensorStatusMonitor(sensorId, true);
621cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    }
62201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    success = true;
62338bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol  }
624cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
625cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  return success;
62638bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol}
62738bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
62880b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol/**
62980b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol * Converts a SensorMode into an SMGR request action. When the net request for
63080b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol * a sensor is considered to be active an add operation is required for the
63180b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol * SMGR request. When the sensor becomes inactive the request is deleted.
63280b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol *
63380b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol * @param mode The sensor mode.
63480b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol * @return Returns the SMGR request action given the sensor mode.
63580b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol */
63680b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignoluint8_t getSmgrRequestActionForMode(SensorMode mode) {
63780b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  if (sensorModeIsActive(mode)) {
6383e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    return SNS_SMGR_BUFFERING_ACTION_ADD_V01;
63980b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  } else {
6403e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    return SNS_SMGR_BUFFERING_ACTION_DELETE_V01;
64180b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  }
64280b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol}
64380b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
644ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
645ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Populates a sns_smgr_buffering_req_msg_v01 struct to request sensor data.
646ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
647ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param request The new request to set this sensor to.
648ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param sensorId The sensorID as provided by the SMGR request for sensor info.
649ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param dataType The dataType for the sesnor as provided by the SMGR request
650ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *                 for sensor info.
651ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
652ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param sensorDataRequest The pointer to the data request to be populated.
653ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
654ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungvoid populateSensorRequest(
655ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    const SensorRequest& request, uint8_t sensorId, uint8_t dataType,
656ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    uint8_t calType, sns_smgr_buffering_req_msg_v01 *sensorRequest) {
65780b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  // Zero the fields in the request. All mandatory and unused fields are
65880b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  // specified to be set to false or zero so this is safe.
659ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  memset(sensorRequest, 0, sizeof(*sensorRequest));
66080b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
66180b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  // Build the request for one sensor at the requested rate. An add action for a
66280b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  // ReportID that is already in use causes a replacement of the last request.
663ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->ReportId = getReportId(sensorId, dataType, calType);
664ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Action = getSmgrRequestActionForMode(request.getMode());
6653e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung  Nanoseconds batchingInterval =
6663e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      (request.getLatency() > request.getInterval()) ?
6673e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      request.getLatency() : request.getInterval();
668ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->ReportRate = intervalToSmgrQ16ReportRate(batchingInterval);
669ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Item_len = 1; // One sensor per request if possible.
670ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Item[0].SensorId = sensorId;
671ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Item[0].DataType = dataType;
672ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Item[0].Decimation = SNS_SMGR_DECIMATION_RECENT_SAMPLE_V01;
673ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Item[0].Calibration = calType;
674ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Item[0].SamplingRate =
6753e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      intervalToSmgrSamplingRate(request.getInterval());
67680b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
677ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  // Add a dummy primary sensor to accompany a secondary temperature sensor.
678ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  // This is requred by the SMGR. The primary sensor is requested with the same
679ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  // (low) rate and the same latency, whose response data will be ignored.
680ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  if (isSecondaryTemperature(sensorRequest->ReportId)) {
681ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorRequest->Item_len = 2;
682ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorRequest->Item[1].SensorId = sensorId;
683ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorRequest->Item[1].DataType = SNS_SMGR_DATA_TYPE_PRIMARY_V01;
684ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorRequest->Item[1].Decimation = SNS_SMGR_DECIMATION_RECENT_SAMPLE_V01;
685ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorRequest->Item[1].Calibration = SNS_SMGR_CAL_SEL_FULL_CAL_V01;
686ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorRequest->Item[1].SamplingRate = sensorRequest->Item[0].SamplingRate;
687ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  }
688ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
689ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
69001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}  // anonymous namespace
69101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
69201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungvoid PlatformSensor::init() {
69301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  // sns_smgr_api_v01
69401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  qmi_idl_service_object_type sensorServiceObject =
69501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      SNS_SMGR_SVC_get_service_object_v01();
69601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  if (sensorServiceObject == nullptr) {
69701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    FATAL_ERROR("Failed to obtain the SNS SMGR service instance");
69801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
69901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
70001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  qmi_client_os_params sensorContextOsParams;
70101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  qmi_client_error_type status = qmi_client_init_instance(sensorServiceObject,
70201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      QMI_CLIENT_INSTANCE_ANY, &platformSensorServiceQmiIndicationCallback,
70301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      nullptr, &sensorContextOsParams, kQmiTimeoutMs,
70401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      &gPlatformSensorServiceQmiClientHandle);
70501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  if (status != QMI_NO_ERR) {
70601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    FATAL_ERROR("Failed to initialize the sensor service QMI client: %d",
70701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                status);
70801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
70901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
71001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  // sns_smgr_interal_api_v02
71101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  sensorServiceObject = SNS_SMGR_INTERNAL_SVC_get_service_object_v02();
71201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  if (sensorServiceObject == nullptr) {
71301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    FATAL_ERROR("Failed to obtain the SNS SMGR internal service instance");
71401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
71501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
71601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  status = qmi_client_init_instance(sensorServiceObject,
71701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      QMI_CLIENT_INSTANCE_ANY,
71801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      &platformSensorInternalServiceQmiIndicationCallback, nullptr,
71901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      &sensorContextOsParams, kQmiTimeoutMs,
72001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      &gPlatformSensorInternalServiceQmiClientHandle);
72101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  if (status != QMI_NO_ERR) {
72201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    FATAL_ERROR("Failed to initialize the sensor internal service QMI client: "
72301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung                "%d", status);
72401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
72501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
72601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
72701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungvoid PlatformSensor::deinit() {
72801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  qmi_client_release(&gPlatformSensorServiceQmiClientHandle);
72901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  gPlatformSensorServiceQmiClientHandle = nullptr;
73001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
73101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  // Removing all sensor status monitor requests. Releaseing a QMI client also
73201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  // releases all of its subscriptions.
73301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  gSensorStatusMonitor.clear();
73401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
73501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  qmi_client_release(&gPlatformSensorInternalServiceQmiClientHandle);
73601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  gPlatformSensorInternalServiceQmiClientHandle = nullptr;
73701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
73801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
73901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungbool PlatformSensor::getSensors(DynamicVector<PlatformSensor> *sensors) {
74001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  CHRE_ASSERT(sensors);
74101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
74201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  sns_smgr_all_sensor_info_req_msg_v01 sensorListRequest;
74301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  sns_smgr_all_sensor_info_resp_msg_v01 sensorListResponse;
74401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
74501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  qmi_client_error_type status = qmi_client_send_msg_sync(
74601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      gPlatformSensorServiceQmiClientHandle, SNS_SMGR_ALL_SENSOR_INFO_REQ_V01,
74701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      &sensorListRequest, sizeof(sns_smgr_all_sensor_info_req_msg_v01),
74801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      &sensorListResponse, sizeof(sns_smgr_all_sensor_info_resp_msg_v01),
74901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      kQmiTimeoutMs);
75001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
75101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  bool success = false;
75201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  if (status != QMI_NO_ERR) {
75301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    LOGE("Error requesting sensor list: %d", status);
75401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  } else if (sensorListResponse.Resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
75501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    LOGE("Sensor list lequest failed with error: %d",
75601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung         sensorListResponse.Resp.sns_err_t);
75701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  } else {
75801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    success = true;
75901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    for (uint32_t i = 0; i < sensorListResponse.SensorInfo_len; i++) {
76001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      uint8_t sensorId = sensorListResponse.SensorInfo[i].SensorID;
76101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      if (!getSensorsForSensorId(sensorId, sensors)) {
76201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        success = false;
76301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        break;
76401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      }
76501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    }
76601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
76701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
76801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  return success;
76901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
77001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
771ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungbool PlatformSensor::setRequest(const SensorRequest& request) {
772ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  // Allocate request and response for the sensor request.
773ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  auto *sensorRequest = memoryAlloc<sns_smgr_buffering_req_msg_v01>();
774ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  auto *sensorResponse = memoryAlloc<sns_smgr_buffering_resp_msg_v01>();
775ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
77680b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  bool success = false;
777ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  if (sensorRequest == nullptr || sensorResponse == nullptr) {
778ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    LOGE("Failed to allocated sensor request/response: out of memory");
77980b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  } else {
780ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    populateSensorRequest(request, this->sensorId, this->dataType,
781ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung                          this->calType, sensorRequest);
782ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
783ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    qmi_client_error_type status = qmi_client_send_msg_sync(
78401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        gPlatformSensorServiceQmiClientHandle, SNS_SMGR_BUFFERING_REQ_V01,
785ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        sensorRequest, sizeof(*sensorRequest),
786ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        sensorResponse, sizeof(*sensorResponse),
787ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        kQmiTimeoutMs);
788ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
789ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    if (status != QMI_NO_ERR) {
790ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      LOGE("Error requesting sensor data: %d", status);
791ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    } else if (sensorResponse->Resp.sns_result_t != SNS_RESULT_SUCCESS_V01
792ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        || (sensorResponse->AckNak != SNS_SMGR_RESPONSE_ACK_SUCCESS_V01
793ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung            && sensorResponse->AckNak != SNS_SMGR_RESPONSE_ACK_MODIFIED_V01)) {
794ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      LOGE("Sensor data request failed with error: %d, AckNak: %d",
795ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung           sensorResponse->Resp.sns_err_t, sensorResponse->AckNak);
79680b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol    } else {
797ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      success = true;
79880b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol    }
79980b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  }
80080b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
801ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  memoryFree(sensorRequest);
802ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  memoryFree(sensorResponse);
80380b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  return success;
804f546f4c27e66dc4ea868e660cebac9ba0c31fad9Andrew Rossignol}
805f546f4c27e66dc4ea868e660cebac9ba0c31fad9Andrew Rossignol
806cb8312e5ce53430576e2343e4863af84676c93adAndrew RossignolSensorType PlatformSensor::getSensorType() const {
807ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  return getSensorTypeFromSensorId(this->sensorId, this->dataType,
808ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung                                   this->calType);
809cb8312e5ce53430576e2343e4863af84676c93adAndrew Rossignol}
810cb8312e5ce53430576e2343e4863af84676c93adAndrew Rossignol
81138bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol}  // namespace chre
812