# Develop sensors

This section describes how client applications interact with the QSH framework. It further explains the development and integration process for sensor drivers and sensor algorithms within the QSH framework. Additionally, it covers procedures for sensor calibration.

## Qualcomm sensing hub client API workflow

The Qualcomm sensing hub (QSH)-exposed APIs are called QSH client APIs for
applications. The client applications interact with the QSH framework available on the
low-power processor. The following figure shows the detailed breakdown and
usage of the QSH client APIs:

<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="768" height="801.47" viewbox="0 0 768 801.47" aria-label="Figure : QSH client API workflow">
  <defs>
    <style>.svg-1 .cls-1 { letter-spacing: 0em }
.svg-1 .cls-2,.svg-1 .cls-3,.svg-1 .cls-4 { font-family: Roboto-Bold, Roboto; font-weight: 700 }
.svg-1 .cls-2,.svg-1 .cls-4,.svg-1 .cls-5 { font-size: 15px }
.svg-1 .cls-2,.svg-1 .cls-6 { letter-spacing: .06em }
.svg-1 .cls-7,.svg-1 .cls-8,.svg-1 .cls-9,.svg-1 .cls-10,.svg-1 .cls-11 { stroke-miterlimit: 10 }
.svg-1 .cls-7,.svg-1 .cls-8,.svg-1 .cls-11 { stroke: #000 }
.svg-1 .cls-7,.svg-1 .cls-10,.svg-1 .cls-11 { fill: none }
.svg-1 .cls-3 { font-size: 16px }
.svg-1 .cls-12 { letter-spacing: -.01em }
.svg-1 .cls-13 { font-size: 18.58px }
.svg-1 .cls-13,.svg-1 .cls-5 { font-family: Roboto-Regular, Roboto }
.svg-1 .cls-14 { letter-spacing: .05em }
.svg-1 .cls-8 { fill: #fff; stroke-width: 2px }
.svg-1 .cls-9 { stroke: #d2d7e1 }
.svg-1 .cls-9,.svg-1 .cls-15 { fill: #fafafa }
.svg-1 .cls-10 { stroke: #7c8aa3; stroke-width: 1.5px }
.svg-1 .cls-11 { stroke-dasharray: 4.98 4.98 }
.svg-1 .cls-16 { letter-spacing: .05em }
.svg-1 .cls-17 { letter-spacing: 0em }</style>
  </defs>
  <rect class="cls-9" x="9.27" y="8.38" width="749.47" height="784.62" rx="2.21" ry="2.21"></rect>
  <text class="cls-2" transform="translate(103.97 286.25)"><tspan x="0" y="0">[perSUID]</tspan></text>
  <text class="cls-4" transform="translate(107.6 462.31)"><tspan class="cls-6" x="0" y="0">[sensor</tspan><tspan class="cls-16" x="56.35" y="0">E</tspan><tspan class="cls-14" x="65.5" y="0">v</tspan><tspan class="cls-6" x="73.89" y="0">ent]</tspan></text>
  <text class="cls-3" transform="translate(46.79 286.85)"><tspan x="0" y="0">Opt</tspan></text>
  <rect class="cls-10" x="29.91" y="267.21" width="712.67" height="260.91" rx="1.91" ry="1.91"></rect>
  <rect class="cls-10" x="47.4" y="443.57" width="677.68" height="68.38" rx=".95" ry=".95"></rect>
  <polyline class="cls-10" points="94.92 267.21 94.92 287.73 84.6 298.05 29.91 298.05"></polyline>
  <text class="cls-3" transform="translate(57.57 462.91)"><tspan x="0" y="0">loop</tspan></text>
  <polyline class="cls-10" points="99.91 443.57 99.91 463.03 91.52 473.35 47.07 473.35"></polyline>
  <rect class="cls-8" x="152.26" y="19.37" width="144.4" height="49.54" rx="4.13" ry="4.13"></rect>
  <rect class="cls-8" x="514.16" y="19.37" width="228.42" height="49.54" rx="5.19" ry="5.19"></rect>
  <line class="cls-7" x1="224.46" y1="68.9" x2="224.46" y2="727.66"></line>
  <line class="cls-7" x1="628.36" y1="68.9" x2="628.36" y2="727.66"></line>
  <text class="cls-13" transform="translate(177.85 48.96)"><tspan x="0" y="0">Application</tspan></text>
  <text class="cls-13" transform="translate(536.07 48.96)"><tspan x="0" y="0">libSensingHubSession</tspan></text>
  <rect class="cls-8" x="152.26" y="727.66" width="144.4" height="49.54" rx="4.13" ry="4.13"></rect>
  <rect class="cls-8" x="514.16" y="727.66" width="228.42" height="49.54" rx="5.19" ry="5.19"></rect>
  <text class="cls-13" transform="translate(177.85 757.25)"><tspan x="0" y="0">Application</tspan></text>
  <text class="cls-13" transform="translate(536.07 757.25)"><tspan x="0" y="0">libSensingHubSession</tspan></text>
  <g>
    <line class="cls-7" x1="224.46" y1="112.63" x2="622.62" y2="112.63"></line>
    <polygon points="621.46 116.62 628.36 112.63 621.46 108.64 621.46 116.62"></polygon>
  </g>
  <g>
    <line class="cls-7" x1="224.46" y1="202.12" x2="622.62" y2="202.12"></line>
    <polygon points="621.46 206.11 628.36 202.12 621.46 198.14 621.46 206.11"></polygon>
  </g>
  <g>
    <line class="cls-7" x1="224.46" y1="556.68" x2="622.62" y2="556.68"></line>
    <polygon points="621.46 560.67 628.36 556.68 621.46 552.69 621.46 560.67"></polygon>
  </g>
  <g>
    <line class="cls-7" x1="224.46" y1="291.62" x2="622.62" y2="291.62"></line>
    <polygon points="621.46 295.61 628.36 291.62 621.46 287.63 621.46 295.61"></polygon>
  </g>
  <g>
    <line class="cls-7" x1="224.46" y1="381.12" x2="622.62" y2="381.12"></line>
    <polygon points="621.46 385.11 628.36 381.12 621.46 377.13 621.46 385.11"></polygon>
  </g>
  <g>
    <line class="cls-7" x1="230.2" y1="157.38" x2="232.7" y2="157.38"></line>
    <line class="cls-11" x1="237.68" y1="157.38" x2="623.38" y2="157.38"></line>
    <line class="cls-7" x1="625.86" y1="157.38" x2="628.36" y2="157.38"></line>
    <polygon points="231.37 161.37 224.46 157.38 231.37 153.39 231.37 161.37"></polygon>
  </g>
  <g>
    <line class="cls-7" x1="230.2" y1="246.87" x2="232.7" y2="246.87"></line>
    <line class="cls-11" x1="237.68" y1="246.87" x2="623.38" y2="246.87"></line>
    <line class="cls-7" x1="625.86" y1="246.87" x2="628.36" y2="246.87"></line>
    <polygon points="231.37 250.86 224.46 246.87 231.37 242.88 231.37 250.86"></polygon>
  </g>
  <g>
    <line class="cls-7" x1="230.2" y1="336.37" x2="232.7" y2="336.37"></line>
    <line class="cls-11" x1="237.68" y1="336.37" x2="623.38" y2="336.37"></line>
    <line class="cls-7" x1="625.86" y1="336.37" x2="628.36" y2="336.37"></line>
    <polygon points="231.37 340.36 224.46 336.37 231.37 332.38 231.37 340.36"></polygon>
  </g>
  <g>
    <line class="cls-7" x1="230.2" y1="425.87" x2="232.7" y2="425.87"></line>
    <line class="cls-11" x1="237.68" y1="425.87" x2="623.38" y2="425.87"></line>
    <line class="cls-7" x1="625.86" y1="425.87" x2="628.36" y2="425.87"></line>
    <polygon points="231.37 429.86 224.46 425.87 231.37 421.88 231.37 429.86"></polygon>
  </g>
  <g>
    <line class="cls-7" x1="230.2" y1="477.76" x2="232.7" y2="477.76"></line>
    <line class="cls-11" x1="237.68" y1="477.76" x2="623.38" y2="477.76"></line>
    <line class="cls-7" x1="625.86" y1="477.76" x2="628.36" y2="477.76"></line>
    <polygon points="231.37 481.75 224.46 477.76 231.37 473.77 231.37 481.75"></polygon>
  </g>
  <g>
    <line class="cls-7" x1="230.2" y1="601.43" x2="232.7" y2="601.43"></line>
    <line class="cls-11" x1="237.68" y1="601.43" x2="623.38" y2="601.43"></line>
    <line class="cls-7" x1="625.86" y1="601.43" x2="628.36" y2="601.43"></line>
    <polygon points="231.37 605.42 224.46 601.43 231.37 597.44 231.37 605.42"></polygon>
  </g>
  <g>
    <path class="cls-7" d="M224.46,646.18h66.78c11.02,0,19.95,8.93,19.95,19.95h0c0,11.02-8.93,19.95-19.95,19.95h-59.6"></path>
    <polygon points="233.1 681.09 224.46 686.08 233.1 691.07 233.1 681.09"></polygon>
  </g>
  <rect class="cls-15" x="385" y="103.06" width="82.83" height="19.14"></rect>
  <rect class="cls-15" x="387.87" y="147.8" width="77.1" height="19.14"></rect>
  <rect class="cls-15" x="399.56" y="192.55" width="53.71" height="19.14"></rect>
  <rect class="cls-15" x="380.3" y="237.3" width="92.23" height="19.14"></rect>
  <rect class="cls-15" x="378.23" y="282.05" width="96.36" height="19.14"></rect>
  <rect class="cls-15" x="382.02" y="326.8" width="88.79" height="19.14"></rect>
  <rect class="cls-15" x="378.23" y="371.55" width="96.36" height="19.14"></rect>
  <rect class="cls-15" x="382.02" y="416.3" width="88.79" height="19.14"></rect>
  <rect class="cls-15" x="380.3" y="468.19" width="92.23" height="19.14"></rect>
  <rect class="cls-15" x="399.91" y="547.11" width="53.02" height="19.14"></rect>
  <text class="cls-5" transform="translate(389.39 116.85)"><tspan x="0" y="0">getSession</tspan></text>
  <text class="cls-5" transform="translate(395.33 161.6)"><tspan x="0" y="0">Isession*</tspan></text>
  <text class="cls-5" transform="translate(408.94 206.35)"><tspan x="0" y="0">Open</tspan></text>
  <text class="cls-5" transform="translate(402.42 560.9)"><tspan x="0" y="0">Close()</tspan></text>
  <text class="cls-5" transform="translate(383.18 295.84)"><tspan x="0" y="0">setCallBacks</tspan></text>
  <text class="cls-5" transform="translate(382.93 385.34)"><tspan x="0" y="0">sendRequest</tspan></text>
  <text class="cls-5" transform="translate(385.44 251.1)"><tspan x="0" y="0">success/fail</tspan></text>
  <text class="cls-5" transform="translate(385.44 340.59)"><tspan x="0" y="0">success/fail</tspan></text>
  <text class="cls-5" transform="translate(385.44 430.09)"><tspan x="0" y="0">success/fail</tspan></text>
  <text class="cls-5" transform="translate(385.44 481.98)"><tspan x="0" y="0">sensor</tspan><tspan class="cls-12" x="45.32" y="0">E</tspan><tspan class="cls-1" x="53.66" y="0">v</tspan><tspan class="cls-17" x="60.83" y="0">ent</tspan></text>
  <text class="cls-5" transform="translate(109.72 649.57)"><tspan x="0" y="0">delete ISession*</tspan></text>
</svg>

**Figure: QSH client API workflow**

The following list describes the QSH client APIs:

- `getSession()`: To interact with the QSH, the sensor application client must create
an interface session by invoking the `getSession()` API. Successful creation of the interface session returns an
`ISession*` object to the client.
- `open()`, `close()`, `setCallback()`, and `sendRequest()`: The interface created using the `getSession()` API operates on a
*once\_per\_session* basis. This interface allows the client application to
use the QSH client APIs, such as `open()`, `close()`,
`setCallback()`, and `sendRequest()`, until the session is
explicitly deleted using the `close()` and `delete()` APIs.

    After the interface session establishes, the client application or the
client code can open a sensor session by calling the `open()` API.
Similar to `getSession()`, the `open()` API is also invoked on a
*once\_per\_session* basis. The `setCallback()` and
`sendRequest()` APIs are invoked once for a specified SUID.

### Messages

The sensor client applications sends and receives the following request and response messages:

1. Sends a `sns_client_request_msg` request message through the
`sendRequest()` API.

    - The sole field of this message is the payload, which is an opaque
byte array. This field is populated with the protocol
buffer-encoded `sns_client_request_msg` message.
2. Receives a `sns_client_resp_msg` response message.

    - The client manager determines if the `sns_client_request_msg`
message is appropriately encoded and the destination SUID is
available. A minimal amount of processing is performed on the request.
    - The client manager sends this response message immediately after receiving the request.
3. Receives one or more events of `sns_client_event_msg` message type.

    - The event callback function receives the event messages, as specified in the `setCallback` API.
    - Each event message has a SUID.
    - An event message can contain one or more logical sensor samples
that are all encoded in the single `sns_client_event_msg`
message.

### Protocol buffers

The QSH client request and event messages are opaque memory buffers that
contain the protocol buffer-encoded messages. Clients can generate these
messages in several programming languages and then copy the encoded byte
stream into a `sns_client_request_msg` message. Similarly, clients can
copy the encoded message from within the `sns_client_report_ind_msg`
message and decode it separately.

For more information about protocol buffers, see
[Protocol-buffers](https://developers.google.com/protocol-buffers/)
and [nanopb](https://github.com/nanopb/nanopb).

### Client manager

The sensor client manager, housed within the QSH, oversees all
communication processes and performs the following responsibilities:

#### Translate incoming requests

> 
> 
> The client manager receives incoming
> requests and translates them to a format that the QSH can
> understand. The translation involves converting the requests into
> specific request messages.

#### Translate outgoing indications

> 
> 
> After receiving the event messages from QSH, the client manager translates the
> event messages into outgoing indications. The translation ensures
> that the messages are in a format that’s understandable outside the
> QSH.

#### Ensure batching options

> 
> 
> If a client specifies certain
> batching options, then the client manager ensures
> that these options are met. It checks that the data is grouped and
> sent in the way the client has specified.
> 
> 
> For more information about the client manager, see the
> `<workspace>/build-qcom-wayland/workspace/sources/sensinghub/sensing-hub/apis/proto/sns_client.proto`
> file.

#### SUID

> 
> 
> The SUID is an integer that uniquely identifies a single
> sensor available from the QSH. Clients treat this ID as a randomly generated
> value during boot. Clients don’t assume that the ID repeats or
> derives any information from the number itself. The client manager reads the SUID from the request and routes the request to the sensor identified by the SUID.
> 
> 
> For example, if there are two gravity algorithms available from the
> QSH, then each has its own unique SUID. This unique ID assignment is
> true for physical sensors too. If the hardware for a physical
> sensor model is present many times on the device, then each has its
> own SUID.
> 
> 
> For a complete list of sensors available on the system, the client
> can send a request to the SUID sensor. For more information, see [Table : Platform sensors](https://docs.qualcomm.com/doc/80-80021-7/topic/architecture.html#table-platform-sensors).

#### Client requests

> 
> 
> All incoming requests to the client manager use
> `sns_client_request_msg` as the outermost protocol buffer message.
> This message has the following fields:
> 
> - SUID: Serves as the destination address of the request message.
> Send all request messages to a valid SUID for processing;
> otherwise, the client manager rejects them.
> - msg\_id: A numeric identifier for the encoded request contained
> in the `sns_std_request::payload` message.
> 
> 
>     For example, a sensor can support request messages to enable streaming and initiate
> a data flush request. The formats of these two messages are
> different, and this field indicates the destination sensor about how
> to interpret the request. Message IDs are always unique among all
> messages supported by a sensor. However, two different sensors may
> use a particular ID for different message types. For example, the following are two types of messages:
> 
>     - `SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG`: Denotes
> standard streaming request from a client to a sensor.
>     - `SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_EVENT`: Denotes a
> standard sensor event from a data source sensor.
> - Request: It’s the information package that the client sends to the sensor. It has all the details required by the sensor. The `sns_std_request::payload` field corresponds to the message ID and has the sensor-specific configuration. For more information, see the sensor-specific proto file.
> - Resampler configuration: It’s used when the client wants to
> change the rate at which the sensor samples the data. Use the
> following options for resampler configuration:
> 
>     - `SNS_RESAMPLER_RATE_FIXED`: The client wants data at a
> specific rate. For example, if the client wants to get data at
> 200 Hz, whereas the physical sensor supports streaming at
> 240 Hz, then the samples are interpolated to 200 Hz.
>     - `SNS_RESAMPLER_RATE_MINIMUM`: The client wants data at a
> certain least rate. For example, if the client wants to get
> data at 200 Hz, whereas the physical sensor supports streaming
> at 240 Hz, then the samples are sent at 240 Hz.
> - Threshold configuration: It’s used when the client wants the
> data only when certain conditions are met. There are four types of
> conditions:
> 
>     - `SNS_THRESHOLD_TYPE_RELATIVE_VALUE` provides thresholding as
> a delta between the current value and the last reported value
> that exceeds above the configured threshold.
>     - `SNS_THRESHOLD_TYPE_RELATIVE_PERCENT` provides thresholding based on the difference between the current value and the last reported value. It’s a percentage of the last reported value, with the percentage representing the configured threshold.
>     - `SNS_THRESHOLD_TYPE_ABSOLUTE` provides thresholding of the
> current value against a fixed configured threshold value.
>     - `SNS_THRESHOLD_TYPE_ANGLE` provides a thresholding of the
> angle between the current and the last reported quaternion for
> the quaternion sensors (in radians).
> - Suspend configuration: It specifies how the system behaves when
> the processor suspends.
> 
>     - `client_proc_type` is the processor where the client is
> located. If any client on this processor asks for a flush (a
> complete send out of data), all clients on that processor get a
> flush of data.
>     - `delivery_type` is about whether to send events while the
> processor suspends.
> 
>         - `SNS_STD_DELIVERY_WAKEUP`: Sends events whenever they
> become available (at sample rate or batch period). If a
> `batch_period` larger than the system capacity is
> requested, all the data is sent upon capacity exhaustion.
> With this option, the `flush_period` is effectively
> ignored, as unsent batched data that doesn’t have the
> opportunity to accrue in the buffer.
>         - `SNS_STD_DELIVERY_NO_WAKEUP`: Sends events only when the
> client processor isn’t suspended; otherwise, batches the
> data until the flush period. After the target processor
> exits suspend, all the pending events are sent.
>     - `nowakeup_msg_ids` is a list of message IDs for which the
> client processor must not be woken up. The message IDs
> mentioned aren’t wake-up capable. They’re only sent if any
> other wake-up capable events are present.
> 
> 
> 
>     For more information, see the `<workspace>/build-qcom-wayland/workspace/sources/sensinghub/sensing-hub/apis/proto/sns_client.proto` file. Here, `<workspace>` specifies your working directory.

#### Batching

> 
> 
> Within the `sns_client_request_msg::sns_std_request`
> message, the client can specify how and when it receives the
> requested data. The `sns_std_request` message has the following fields:
> 
> - `batching::batch_period`: An unsigned integer value that denotes
> the batch time in microseconds. A client can assume that a timer
> is registered for the given `batch_period`. All
> events generated since the last timer expiration are saved until
> the next timer is fired. This period is interpreted as the maximum
> period specified by the client. Events are delivered to the
> client at a faster rate (smaller batch period) in some concurrency
> scenarios. A client can send a flush request at any time to
> instruct the client manager to send all the batched data. By
> default, batching is disabled.
> - `batching::flush_period`: An unsigned integer value measured in microseconds. This field provides a hint to the client
> manager or physical sensor regarding the quantity of historical data that must
> be batched if the data is not sent to the client. In other words,
> the client manager can drop data that’s older than the
> `flush_period` in microseconds. The effective flush period can
> be smaller due to the system memory constraints or larger in
> concurrency cases. This field is optional and if not set, defaults
> to `batch_period`, where, only a single batch of data is
> maintained. If this field is set, then the `flush_period` must
> be greater than or equal to `batch_period`.
> - `batching::flush_only`: If set to `True`, the client manager sends
> events only upon a client-initiated flush. Otherwise, it continues
> batching until `flush_period` is reached (at which time,
> batching continues, but the oldest data are dropped).
> - `batching::max_batch`: If set to `True`, it directs the sensor to
> operate at maximum batching capacity. If a request has both
> `flush_only = true` and `max_batch = true`, then
> `flush_only` takes precedence.

#### Client event

> 
> 
> All outgoing indications from the client manager
> use `sns_client_event_msg` as the outermost protocol buffer-encoded
> message, within the payload field of `sns_client_report_ind_msg`. The `sns_client_event_msg` message has several fields:
> 
> - SUID: it’s associated with the data source event. If a client sends
> requests to many SUIDs on a single connection, then this
> message has only the events for one SUID. Events from other
> SUIDs are delivered in separate indication messages.
> - `events::msg_id`: Uniquely identifies the associated event
> message.
> - `events::timestamp`: The timestamp associated with this event
> in the QTimer clock ticks. For most events, the sensor sets the
> timestamp, which refers to the time when the physical sample was
> created in the sensor hardware. For events generated by the
> framework (such as configuration updates or error events), this
> timestamp refers to the time at which the event was created.
> - `events::payload`: Dynamic length payload, containing the actual
> data/event from the sensor. Decode this payload separately using
> the sensor-specific proto buffer.

#### Message payloads

> 
> 
> The sensor-specific request or event is
> referenced in `sns_client_request_msg::sns_std_request::payload` and
> `sns_client_event_msg::sns_client_event::payload` messages. These
> message fields can contain a protocol buffer-encoded message with fields
> specific to that message ID or may be empty and have no fields.
> 
> 
> Clients use the `proto` file associated with the sensor to which
> they communicate. Each sensor type has a corresponding `proto`
> file. For example, `sns_accel.proto` describes how to enable an
> accelerometer stream. Every sensor publishes its list of
> `proto` files as a part of its attributes. For more information, see [Sensor attribute](https://docs.qualcomm.com/doc/80-80021-7/topic/develop_sensors.html#table-sensor-attribute).
> 
> - Data types: Each sensor advertises a data type attribute. Each
> data type is associated with a unique set of `proto` files
> that make up the sensor-specific API for that sensor. All sensors
> of the same type must support a minimum set of requests and event
> messages. They can define and use more optional messages that are
> specific to that sensor implementation. Each sensor publishes a
> complete list of `proto` files as part of its attributes.
> - Standardized messages: A client can send a set of standardized Qualcomm-defined messages to any sensor. These
> messages are defined in the `sns_std.proto` file.
> 
>     - `SNS_STD_MSGID_SNS_STD_ATTR_REQ`: Queries a sensor for the
> list of attributes. It returns an event with an
> `SNS_STD_MSGID_SNS_STD_ATTR_EVENT` ID that has a list of
> all the published attributes, see [Sensor attribute](https://docs.qualcomm.com/doc/80-80021-7/topic/develop_sensors.html#table-sensor-attribute). Clients can also register for notification when a new or
> updated attribute is published.
> 
>         - The `sns_std_attr_req` has the `register_updates` field. If set to `True`, the client receives notifications whenever there is a change in the sensor attributes through `sns_std_attr_event`.
>         - The `sns_std_attr_event` has the `attributes` field, which lists all the attributes published by a sensor sent in response to `sns_std_attr_req`, or on an attribute change to a registered sensor.
>     - `SNS_STD_MSGID_SNS_STD_FLUSH_REQ`: Forces all the batch data
> from this sensor to be immediately sent to the client. This
> request message forces the applicable hardware and software buffers on
> the system to flush all the data present.
> 
> 
>         For example, sending this request to an accelerometer sensor
> causes the physical first-in-first-out (FIFO) flush, as well as any samples
> currently held by the client manager. If the flush request is
> to an algorithm, such as a game rotation vector (GRV), which
> internally uses accelerometer and gyroscope data, then both the
> accelerometer and gyroscope hardware FIFOs are flushed.
>     - `SNS_CLIENT_MSGID_SNS_CLIENT_DISABLE_REQ`: Disables the
> active request for this sensor. For example, the client sends a
> `SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG` message to the
> accelerometer sensor to enable streaming. Later, sending a
> `DISABLE_REQ` cancels the streaming request, and
> accelerometer streaming ceases for this client.
>     - `SNS_STD_MSGID_SNS_STD_FLUSH–EVENT`: Response to a flush
> request. It indicates no further events corresponding to the
> flush request.
>     - `SNS_STD_MSGID_SNS_STD_ERROR–EVENT`: An error event generated
> by a sensor, sensor instance, or the framework.
> 
> 
>         For more information, see the
> `<workspace>/build-qcom-wayland/workspace/sources/sensinghub/sensing-hub/apis/proto/sns_client.proto`
> file.
> - Standardized sensor messages: The messages described in the
> client request are applicable to all the sensors. In addition to
> the messages described in the client request, you can use
> Qualcomm-recommended standardized messages. These recommendations
> are optional, and you can instead choose to define your own
> request and event messages.
> 
>     - `SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG`: Request message
> that allows streaming for the following:
> 
>         - Any physical sensor, for example, accelerometer, gyroscope,
> and magnetometer.
>         - Some algorithms, for example, rotation vector, gravity, and
> linear acceleration.
>     - `SNS_STD_SENSOR_MSGID_SNS_STD_ON_CHANGE_CONFIG`: Request
> message that allows streaming for an on-change type sensor.
> For example, proximity, ambient light, and step detect sensors.
>     - `SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_PHYSICAL_CONFIG_EVENT`:
> Event sent by all the physical sensors after processing a client
> request. It indicates the data stream client’s expectation, such as
> the rate at which the sensor produces samples.
>     - `SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_EVENT`: Data sample
> produced by the sensor, as per the client request.
> 
> 
> 
>     For more information, see the `sns_std_sensor.proto` file.
> - SUID lookup sensor: Clients can query the SUID lookup sensor
> for the list of SUIDs associated with a specific data type. The
> `sns_suid_req` message specifies a data type, and the client
> receives all matching SUIDs. An empty data type string results in
> the receipt of the list of all SUIDs on the system.
> 
> 
>     For example, if a client specifies *accel* as the data type, then
> the client receives a list of all SUIDs whose sensors provide data of
> type *accel*. Additionally, if the client wants to receive
> notifications for a new match, then the client can indicate it
> through the `register_updates` field. The `sns_suid_req`
> message can be followed up by an attribute request
> (`sns_std_attr_req`) by the client to decide which of the
> available *accel* sensors are appropriate for this client.
> 
> 
>     The SUID lookup sensor has its own SUID, which is constant and is
> published in a `sns_suid.proto` file (making it unique among all
> other sensors).
> 
> 
>     The `sns_suid_req` message has the following fields. For more information, see the `sns_suid.proto` file and example code.
> 
> 
> 
> Table : SUID request
> 
> 
>     | Field | Mandatory or optional | Data type | Description |
>     | --- | --- | --- | --- |
>     | `data_type` | Mandatory | String | Data type of the sensor for which SUID is to be queried. |
>     | `register_updates` | Optional | Boolean | Register for updates to the list of SUIDs advertising the `data_type` field. |
>     | `default_only` | Optional | Boolean | Each data type can have one sensor configured to be default through the registry.<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>If the <code class="docutils literal notranslate"><span class="pre">default_only</span></code> field is set to True and:</p><ul><br>> <li><p>A default for the data type is explicitly configured, then only the SUID of the default sensor is sent through the SUID event when available.</p></li><br>> <li><p>A default for the data type isn’t explicitly configured, then the SUID of the first sensor with the matching data type is sent through the SUID event.</p></li><br>> </ul><br>> </li><br>> <li><p>If the <code class="docutils literal notranslate"><span class="pre">default_only</span></code> field is set to False, then all the sensors with the matching data type are sent as and when they become available.</p></li><br>> </ul> |

#### Sensor attributes

> 
> 
> Every sensor publishes a list of attributes,
> representing each attribute with a numeric identifier. These
> attributes provide information regarding the sensor capabilities and
> the range of values that it accepts as an input. The following table lists a few important attributes:

> 
> 
> > 
> > 
> > Table : Sensor attribute
> > 
> > 
> > | Attribute ID | Attribute name | Required? | Data type | Description |
> > | --- | --- | --- | --- | --- |
> > | 0 | `SNS_STD_SENSOR_ATTRID_NAME` | Yes | String | Human-readable sensor name. |
> > | 1 | `SNS_STD_SENSOR_ATTRID_VENDOR` | Yes | String | Human-readable vendor name. |
> > | 2 | `SNS_STD_SENSOR_ATTRID_TYPE` | Yes | String | The data type used by this sensor, as defined in the sensor proto file. |
> > | 3 | `SNS_STD_SENSOR_ATTRID_AVAILABLE` | Yes | Boolean | Indicates whether this sensor is available for the clients or not. |
> > | 4 | `SNS_STD_SENSOR_ATTRID_VERSION` | Yes | Integer | <ul class="simple"><br><li><p>64‑bit integer value represented as <code class="docutils literal notranslate"><span class="pre">major[31:16].minor[15:8].revision[7:0]</span></code>, denoting the sensor version.</p></li><br><li><p>Example in hexadecimal: major: 0x0002 minor: 0x00 revision: 0x36.</p></li><br><li><p>DRIVER_VERSION 0x00020036.</p></li><br></ul> |
> > | 5 | `SNS_STD_SENSOR_ATTRID_API` | Yes | String | List of the `proto` filenames used by this sensor; more `proto` dependencies are specified as imports within the same proto file, which is used primarily for the test automation. |
> > | 6 | `SNS_STD_SENSOR_ATTRID_RATES` | No | Float | List of sample rates supported by the sensor. |
> > | 7 | `SNS_STD_SENSOR_ATTRID_RESOLUTIONS` | No | Float | List of sample resolutions supported by the sensor. |
> > | 8 | `SNS_STD_SENSOR_ATTRID_FIFO_SIZE` | No | Integer | Supported FIFO depth (in the number of samples). |
> > | 9 | `SNS_STD_SENSOR_ATTRID_ACTIVE_CURRENT` | No | Integer | Array of active currents in µA. |
> > | 10 | `SNS_STD_SENSOR_ATTRID_SLEEP_CURRENT` | No | Integer | Inactive current in µA. |
> > | 11 | `SNS_STD_SENSOR_ATTRID_RANGES` | No | Float | Supported operating ranges by the sensor. |
> > | 12 | `SNS_STD_SENSOR_ATTRID_OP_MODES` | No | String | Defines the operating modes supported by the sensor. For example, [LPM, HIGH\_PERF, NORMAL, OFF]. |
> > | 13 | `SNS_STD_SENSOR_ATTRID_DRI` | No | Boolean | Denotes whether the sensor supports the data ready interrupt (DRI) or in-band interrupt (IBI):<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>True = DRI</p></li><br>> <li><p>False = IBI</p></li><br>> </ul> |
> > | 14 | `SNS_STD_SENSOR_ATTRID_STREAM_SYNC` | No | Boolean | Denotes whether a sensor supports synchronized streaming. |
> > | 15 | `SNS_STD_SENSOR_ATTRID_EVENT_SIZE` | No | Integer | <ul class="simple"><br><li><p>The size (in bytes) of the data event (protocol-buffer-encoded) produced by this sensor.</p></li><br><li><p>For physical and virtual sensors, this value refers to the size of their sensor sample</p></li><br><li><p>Used by the hardware abstraction layer (HAL) for maximum batching capacity determination.</p></li><br></ul> |
> > | 16 | `SNS_STD_SENSOR_ATTRID_STREAM_TYPE` | Yes | Integer | Denotes the streaming type supported by the sensor:<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>0 = continuous periodic sampling</p></li><br>> <li><p>1 = on-change</p></li><br>> <li><p>2 = single output (one-shot)</p></li><br>> </ul> |
> > | 17 | `SNS_STD_SENSOR_ATTRID_DYNAMIC` | No | Boolean | Specifies if this sensor is dynamic (connected or disconnected at runtime). |
> > | 18 | `SNS_STD_SENSOR_ATTRID_HW_ID` | No | Integer | Differentiates multiple sensors of the same hardware. |
> > | 19 | `SNS_STD_SENSOR_ATTRID_RIGID_BODY` | No | Integer | The rigid body on which the sensor is placed.<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>0 = sensor hardware is on the display side</p></li><br>> <li><p>1 = sensor hardware is on the keyboard side</p></li><br>> <li><p>2 = sensor hardware is mounted on an external device</p></li><br>> </ul> |
> > | 21 | `SNS_STD_SENSOR_ATTRID_PHYSICAL_SENSOR` | No | Boolean | <ul class="simple"><br><li><p><code class="docutils literal notranslate"><span class="pre">True</span></code>, if physical sensor.</p></li><br><li><p><code class="docutils literal notranslate"><span class="pre">False</span></code>, if virtual sensor.</p></li><br></ul> |
> > | 22 | `SNS_STD_SENSOR_ATTRID_PHYSICAL_SENSOR_TESTS` | No | Integer | List of supported physical sensor tests using enum values in `sns_physical_sensor_test_type`. |
> > | 23 | `SNS_STD_SENSOR_ATTRID_SELECTED_RESOLUTION` | No | Float | Measurement resolution for each dynamic range value. |
> > | 24 | `SNS_STD_SENSOR_ATTRID_SELECTED_RANGE` | No | Float[2] | Dynamic range options supported by the sensor. For the default option, see the sensor hardware requirement specification from vendor. |
> > | 25 | `SNS_STD_SENSOR_ATTRID_ADDITIONAL_LOW_LATENCY_RATES` | No | Float | List of additional sample rates for low-latency operation, in Hz. These sample rates are for dedicated low-latency clients, extending the list of rates published in the `SNS_STD_SENSOR_ATTRID_RATES` attribute.<br><br><br>Dedicated internal clients must use these higher data rates, as they can impact system performance. |
> > | 26 | `SNS_STD_SENSOR_ATTRID_PASSIVE_REQUEST` | No | Boolean | `True` if the sensor supports passive requests, otherwise `False`. If a sensor doesn’t support passive requests, then all the requests must be treated as active. |
> > | 29 | `SNS_STD_SENSOR_ATTRID_TRANSPORT_MTU_SIZE` | No | Integers | Maximum transmission unit (MTU) size for a transport sensor, in bytes. |
> > | 30 | `SNS_STD_SENSOR_ATTRID_HLOS_INCOMPATIBLE` | No | Boolean | `True` if the sensor isn’t compatible with the high-level operating system (HLOS) specification for the supported data type. |
> > | 31 | `SNS_STD_SENSOR_ATTRID_SERIAL_NUM` | No | String | Sensor serial number. |
> > | 32 | `SNS_STD_SENSOR_ATTRID_TECH_USED` | No | Integer array | List of technologies used. For more information, see `sns_tech` in the `sns_std_type.proto` file. |
> 
> 
> 
> For more information, see the `sns_std_sensor.proto` file and example code. Proto files are in the  `/etc/sensors/proto/` directory on the device.

**Next steps**

- [Develop applications using the QSH client APIs](https://docs.qualcomm.com/doc/80-80021-7/topic/develop_app.html)
- [Configure sensors](https://docs.qualcomm.com/doc/80-80021-7/topic/develop_app.html#configure-sensors)
- [Develop and integrate sensor drivers](https://docs.qualcomm.com/doc/80-80021-7/topic/develop_app.html#develop-and-integrate-sensor-drivers)
- [Develop and integrate custom sensor algorithms](https://docs.qualcomm.com/doc/80-80021-7/topic/develop_app.html#develop-and-integrate-custom-sensor-algorithms)
- [Calibrate sensors](https://docs.qualcomm.com/doc/80-80021-7/topic/calibrate.html)

Last Published: Mar 13, 2026

[Previous Topic
Bring up sensors](https://docs.qualcomm.com/bundle/publicresource/80-80021-7/topics/bringup_sensors.md) [Next Topic
Develop applications using the QSH client APIs](https://docs.qualcomm.com/bundle/publicresource/80-80021-7/topics/develop_app.md)