# Samples The following samples explain the end-to-end use case of QSH with API usage, which enables you to effectively configure sensors for your deployment needs. ## QSH client API workflow Sensor application clients interact with the QSH available on the low-power processor. The QSH-exposed APIs are called QSH client APIs for applications. The following figure shows the detailed breakdown and usage of the QSH client APIs: Page-1 Application Application libSensingHubSession libSensingHubSession getSession getSession ISession* ISession* Open Open success/fail success/fail setCallBacks setCallBacks success/fail success/fail sendRequest sendRequest success/fail success/fail sensorEvent sensorEvent close() close() Application Application libSensingHubSession libSensingHubSession delete ISession* delete ISession* opt opt loop loop [perSUID] [perSUID] [sensorEvent] [sensorEvent] QSH client API workflow - **getSession** To interact with the QSH, the sensor application client must create an interface session by invoking the `getSession()` API as shown in the figure. 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 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 is established, the 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. Additionally, the `setCallback()` and `sendRequest()` APIs are invoked once for a given SUID. ### Messages The following flow is observed for all the 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 sends this response message immediately upon receipt of the request. - A minimal amount of processing is performed on the request. The client manager determines if the `sns_client_request_msg` message is appropriately encoded and the destination SUID is available. 3. Receives one or more events of `sns_client_event_msg` message type. - The event messages are received within the event callback function, as specified in the `setCallback` API. - Each message contains a SUID. - An event message may 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 on 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. The client manager responsibilities are: - **Translating incoming requests**: The client manager receives incoming requests and translates them into a format that the QSH can understand. The translation involves converting the requests into specific request messages. - **Translating outgoing indications**: When the client manager receives event messages from QSH, the client manager translates the event messages into the outgoing indications. The translation ensures that the messages are in a format that is understandable outside the QSH. - **Guaranteeing batching options**: If a client specifies certain batching options, then the client manager is responsible to ensure that these options are met. It checks that the data is grouped and sent in the way the client has specified. For more information on the client manager, see the `/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 consider this ID as generated randomly upon boot. Clients do not assume that the ID repeats or derives any information from the number itself. 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 as well. 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. - **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 numerical identifier for the encoded request contained in the `sns_std_request::payload` message. For example, a sensor may support an enable streaming request message, and an initiated data flush request. The formats of these two messages are different, and this field indicates the destination sensor on 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. So, in simple terms, the `sns_client_request_msg` message is like a special envelope that carries requests to the right sensor and tells it which to do. > > > For example, > > - **Message types** — there are two types of messages: > > - `SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG`: Used for > standard streaming request from a client to a sensor. > - `SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_EVENT`: Used to denote a > standard sensor event from a data source sensor. > - **Request** — is the package of information that the client sends > to the sensor. It contains all the details that the sensor must do > its job. 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. > - **Resampler configuration** — is used when the client wants to > change the rate at which the sensor samples the data. The > following are the two ways to do the resampler configuration: > > - `SNS_RESAMPLER_RATE_FIXED`: The client wants data at a > specific rate. For example, if the client wishes 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 wishes 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** — is 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 > as a delta between the current value and the last reported > value, and compared as a percentage of the last reported value, > where the percentage is 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** — specifies how the system behaves when > the processor is suspended. > > - `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 is suspended. > > - `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 does not have the > opportunity to accrue in the buffer. > - `SNS_STD_DELIVERY_NO_WAKEUP`: Sends events only when the > client processor is not suspended; otherwise, batches the > data until the flush period. After the target processor > exits suspend, all 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 are not wake-up capable. They are only sent if any > other wake-up capable events are present. > > > > For more information, see the `/build-qcom-wayland/workspace/sources/sensinghub/sensing-hub/apis/proto/sns_client.proto` file. - **Batching**: Within the `sns_client_request_msg::sns_std_request` message, the client can specify how and when it receives the requested data. `sns_std_request` 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` in microseconds. All events generated since the last timer expiration are saved until the next timer has fired. This period is interpreted as a maximum period specified by the client. Events may be delivered to the client at a faster rate (smaller batch period) in some concurrency scenarios. A client may 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 whose unit is in microseconds. This field provides a hint to the client manager or physical sensor regarding how much historical data must be batched if the data is not sent to the client. In other words, the client manager may drop the data that is 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`, that is, 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 may be 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`. `sns_client_event_msg` message has several fields: - SUID: Associated with the data source event. If a client sends requests to multiple SUIDs on a single connection, then this message contains 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 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 referred in `sns_client_request_msg::sns_std_request::payload` and `sns_client_event_msg::sns_client_event::payload` messages. These message fields 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. In addition, every sensor publishes its list of `.proto` files as a part of its attributes. For more information, see [Table : Sensor attribute](https://docs.qualcomm.com/doc/80-70017-7/topic/samples.html#table-n14-1hh-p1c-monicapa-03-01-24-940-43-733). - **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 request and event messages. They may 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**: Any client can send a set of Qualcomm-defined standardized 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 its list of attributes. It returns an event with an `SNS_STD_MSGID_SNS_STD_ATTR_EVENT` ID that contains a list of all the published attributes, see [Table : Sensor attribute](https://docs.qualcomm.com/doc/80-70017-7/topic/samples.html#table-n14-1hh-p1c-monicapa-03-01-24-940-43-733). Clients can also register for notification when a new or updated attribute is published. - `sns_std_attr_req` has the following field: - `register_updates`: If set to True, the client receives notifications whenever there is a change in sensor attributes through `sns_std_attr_event`. - `sns_std_attr_event` has the following field: - `attributes`: List of 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 command 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 to flush the physical FIFO, 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, 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/instance or the framework. For more information, see the `/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 may instead choose to define your own request and event messages. - `SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG`: Request message that enables streaming for: - 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 enables streaming for an on-change type sensor, for example, proximity, ambient\_light, and step\_detect. - `SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_PHYSICAL_CONFIG_EVENT`: Event sent by all the physical sensors upon processing a client request. It indicates what data stream clients must expect, for example, the rate at which the sensor produces samples. - `SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_EVENT`: Data sample produced by the sensor. For more information, see the `sns_std_sensor.proto` file. - **SUID lookup sensor**: Clients may 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 they receive a list of all SUIDs whose sensors provide data of type *accel*. Additionally, if the client want to receive notifications when a new match is found, they 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: 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 may have one sensor configured to be default through the registry.



>
>
>

    >
  • If the default_only field is set to True and:


      >
    • 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


    • >
    • A default for the data type is not explicitly configured, then the SUID of the first sensor with the matching data type is sent through the SUID event


    • >

    >

  • >
  • If the default_only field is set to False, then all the sensors with the matching data type are sent as and when they become available.


  • >
| > > > For more information, see the sns_suid.proto file and example code. - **Sensor attributes**: Every sensor publishes a list of attributes, representing each attribute with a numerical 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 | Mandatory? | 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 |

  • 64‑bit integer value represented as major[31:16].minor[15:8].revision[7:0], denoting the sensor version.


  • Example in hexadecimal: major: 0x0002 minor: 0x00 revision: 0x36.


  • DRIVER_VERSION 0x00020036.


| | 5 | `SNS_STD_SENSOR_ATTRID_API` | Yes | String | List of the `.proto` filenames used by this sensor; more `.proto` dependencies may be specified as imports within the same proto file 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 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 | An array of strings defines 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 DRI or IBI:



>
>
>

    >
  • True = DRI


  • >
  • False = IBI


  • >
| | 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 |

  • The size (in bytes) of the data event (protocol-buffer-encoded) produced by this sensor.


  • For physical and virtual sensors, this value refers to the size of their sensor sample


  • Used by the HAL for maximum batching capacity determination.


| | 16 | `SNS_STD_SENSOR_ATTRID_STREAM_TYPE` | Yes | Integer | Denotes type of streaming supported by the sensor:



>
>
>

    >
  • 0 = continuous periodic sampling


  • >
  • 1 = on-change


  • >
  • 2 = single output (one-shot)


  • >
| | 17 | `SNS_STD_SENSOR_ATTRID_DYNAMIC` | No | Boolean | Specifies if this sensor is dynamic (connected/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.



>
>
>

    >
  • 0 = sensor hardware is on the display side


  • >
  • 1 = sensor hardware is on the keyboard side


  • >
  • 2 = sensor hardware is mounted on an external device


  • >
| | 21 | `SNS_STD_SENSOR_ATTRID_PHYSICAL_SENSOR` | No | Boolean |

  • True, if physical sensor.


  • False, if virtual sensor.


| | 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 requirement specification. | | 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.


Dedicated internal clients must use these higher data rates, as they may impact system performance. | | 26 | `SNS_STD_SENSOR_ATTRID_PASSIVE_REQUEST` | No | Boolean | True if the sensor supports passive requests, false otherwise. If a sensor does not support passive requests, then all requests must be treated as active. | | 29 | `SNS_STD_SENSOR_ATTRID_TRANSPORT_MTU_SIZE` | No | Integers | MTU size for a transport sensor, in bytes. | | 30 | `SNS_STD_SENSOR_ATTRID_HLOS_INCOMPATIBLE` | No | Boolean | True if the sensor is not 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 ``sns_std_type.proto` file | > > > For more information, see the sns_std_sensor.proto file and example code. Proto files are at the `/etc/sensors/proto/` location on the device. ## QSH sample client call flow and usage of QSH client APIs with QSH A sample application named `SessionClient` is provided as a reference to demonstrate the QSH client API usage. This sample application is built by default in the `/usr/bin` directory on the device. For complete sample code, see the `/build-qcom-wayland/workspace/sources/sensinghub/sensing-hub/examples/SessionClient/SessionClient.cpp` file. The following figure shows the call flow for streaming the accelerometer sensor and the usage of the QSH client APIs. Page-1 Application Application libSensingHubSession libSensingHubSession getSession getSession ISession* ISession* get SUID using ISession* get SUID using ISession* SUID SUID get Attributes using ISession* get Attributes using ISession* Attributes Attributes sensorEvents sensorEvents Application Application libSensingHubSession libSensingHubSession delete ISession* delete ISession* opt opt [refer QSH Interface] [refer QSH Interface] opt opt [refer QSH Interface] [refer QSH Interface] opt opt [refer QSH Interface] [refer QSH Interface] Start Streaming using SUID Start Streaming using SUID Call flow to stream a given sensor In this example, different sensor sessions are used for the SUID query, attribute query, and streaming activity. The same session can be used for all the activities; however, synchronization must be handled appropriately. 1. **SUID query** retrieves SUIDs for the specified sensor: 1. Create an interface for SUID by calling the `getSession()` API with the new `sessionFactory()` class. Requesting the SUID is the first and important request to get SUID of the requested data type for any use case. /* Create a new ISession for UID discovery */ sessionFactory* factory = new sessionFactory(); if(nullptr == factory){ printf("failed to create factory instance"); return false; } ISession* suidSession = factory->getSession(); if(nullptr == suidSession){ printf("failed to create uid session"); return false; } Copy to clipboard 2. Open a created session interface by calling the `open()` API. /* Open the suidSession */ int ret = suidSession->open(); if(-1 == ret){ printf("failed to open ISession for uid query"); return false; } Copy to clipboard 3. Set callbacks by calling the `setCallBacks()` API and handling the response/event/error for the SUID activity. /* Set callbacks for the session for 'uid' */ ret = suidSession->setCallBacks(uid, suidResp, nullptr, suidEvent); if(-1 == ret) printf("all callbacks are null, no need to register it"); Copy to clipboard 4. Create and send a pb-encoded request message for SUID of a given data type by calling the `sendRequest()` API. /* * Create SUID request message * (Please refer sns_client.proto and sns_suid.proto for more details) * */ string pb_req_encoded = ""; sns_suid_req pb_suid_req; pb_suid_req.set_data_type(sensorName); pb_suid_req.set_register_updates(true); sns_client_request_msg pb_req_msg; pb_req_msg.set_msg_id(SNS_SUID_MSGID_SNS_SUID_REQ); .. string pb_req_msg_encoded; pb_req_msg.SerializeToString(&pb_req_msg_encoded); /* send proto encoded message to sensing-hub using the opened session */ unique_lock respLock(respMutex); ret = suidSession->sendRequest(uid, pb_req_msg_encoded); if(0 != ret){ printf("Error in sending uid discovery request"); return false; } Copy to clipboard 5. Close the session by calling the `close()` API and delete it after the SUID events for the requested data type are received. /* Close and delete the session once suids are received */ suidSession->close(); delete suidSession; delete factory; Copy to clipboard 2. **Attribute request** retrieves attributes for the specified sensor: 1. Create an interface session for an attribute by calling `getSession()` with the new `sessionFactory()` class. Requesting the attributes is important to get the capabilities of the requested data type for any use case. /* Create a new ISession for attribute query */ sessionFactory* factory = new sessionFactory(); if(nullptr == factory){ printf("failed to create factory instance"); return false; } ISession* attributeSession = factory->getSession(); if(nullptr == attributeSession){ printf("failed to create attribute session"); return false; } Copy to clipboard 2. Open a created session interface by calling the `open()` API. /* open the attributeSession session */ int ret = attributeSession->open(); if(-1 == ret){ printf("failed to open ISession for attribute query"); return false; Copy to clipboard 3. Set callbacks by calling `setCallBacks()` and handling the response/event/error for the attribute activity. for (const suid& uid : suidList) { /* set callbacks for the session for 'uid' */ int ret = attributeSession->setCallBacks(uid, attributeResp, nullptr, attributeEvent); if(-1 == ret) printf("all callbacks are null, no need to register it"); Copy to clipboard 4. Create and send a pb-encoded configuration request for an attribute of a given data type by calling the `sendRequest()` API. /* create pb-encoded config request message to be sent for attribute query */ sns_client_request_msg pb_req_msg; pb_req_msg.set_msg_id(SNS_STD_MSGID_SNS_STD_ATTR_REQ); pb_req_msg.mutable_request()->clear_payload(); pb_req_msg.mutable_suid()->set_suid_high(uid.high); .. .. /* send proto encoded message to sensing-hub using the opened session */ unique_lock respLock(respMutex); ret = attributeSession->sendRequest(uid, pb_req_msg_encoded); Copy to clipboard 5. Close the session by calling the `close()` API after the attribute events for the requested data type is received. /* close and delete the session once all attributes are received */ attributeSession->close(); delete attributeSession; delete factory; Copy to clipboard 3. **Sensor streaming** streams the sensor and receives the data events: 1. Create an interface session for streaming the sensor by calling the `getSession()` with the new `sessionFactory()` class. Here, requesting the sensor data is the final stage of a requested data type for any use case. sessionFactory()class. /* create a new ISession for streaming activity */ sessionFactory* factory = new sessionFactory(); if(nullptr == factory){ printf("failed to create factory instance"); return false; } ISession* streamingSession = factory->getSession(); if(nullptr == streamingSession){ printf("failed to create streaming session"); return false; } Copy to clipboard 2. Open a created session interface by calling the `open()` API. /* open the streamingSession session */ int ret = streamingSession->open(); if(-1 == ret){ printf("failed to open ISession for attribute query"); return false; Copy to clipboard 3. Set callbacks by calling `setCallBacks()` and handling the response/event/error for streaming the activity. for (const suid& uid : suidList){ /* set callbacks for the session for 'uid' */ int ret = streamingSession->setCallBacks(uid, dataResp, dataError, dataEvent); if(-1 == ret) printf("all callbacks are null, no need to register it"); Copy to clipboard 4. Create and send a pb-encoded configuration request for streaming the sensor of a given data type by calling the `sendRequest()` API, which eventually enables the requested sensor. /* create pb-encoded config request message to be sent for streaming request */ string pb_req_encoded = ""; sns_std_sensor_config pb_stream_cfg; pb_stream_cfg.set_sample_rate(sampleRate); pb_stream_cfg.SerializeToString(&pb_req_encoded); sns_client_request_msg pb_req_msg; pb_req_msg.mutable_request()->mutable_batching()->set_batch_period(batchPeriod); pb_req_msg.set_msg_id(SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG); .. .. /* send proto encoded message to sensing-hub using the opened session */ unique_lock respLock(respMutex); ret = streamingSession->sendRequest(uid, pb_req_msg_encoded); Copy to clipboard 5. Handle samples in the event callbacks and wait for the specified duration of the test. void handle_event_cb(const uint8_t *data, size_t size, uint64_t time_stamp){ if(true == deletion_started){ printf("\nEvent coming when deletion of qmi connection started"); return; } sns_client_event_msg pb_event_msg; /* Parse the pb encoded event */ pb_event_msg.ParseFromArray(data, size); /* Iterate over all events in the message */ for (int i = 0; i < pb_event_msg.events_size(); i++) { auto& pb_event = pb_event_msg.events(i); Copy to clipboard 6. Stop streaming the activity by sending a disable request by calling the `sendRequest()` API. pb_req_msg.set_msg_id(SNS_CLIENT_MSGID_SNS_CLIENT_DISABLE_REQ); pb_req_msg.mutable_suid()->set_suid_high(uid.high); pb_req_msg.mutable_suid()->set_suid_low(uid.low); .. .. /* send disable request to sensing-hub */ int ret = streamingSession->sendRequest(uid, pb_req_msg_encoded); Copy to clipboard 7. Close the session by calling the `close()` API after the streaming events for the requested data type is received. /* close and delete the streamingSession */ streamingSession->close(); delete streamingSession; delete factory; Copy to clipboard The following snippet shows the `SessionClient` sample application output. It enables an accelerometer sensor with 10 Hz sample rate and a 2-second batch period for 10 sec, and prints the received sensor events. root@qcm6490:~# SessionClient Streaming configuration is as follows : Sensor name : accel Sample rate : 10 Hz Batch period : 2 sec Test duration : 10 sec SUID discovery response received. Received SUIDs for accel, number of suids received = 1 SUID received - suid_low=6360260105974108950 suid_high=7037810611998542250 Sensor suid list created requesting attributes for - suid_low=6360260105974108950 suid_high=7037810611998542250 Attribute query response received. Attributes for - suid_low=6360260105974108950 suid_high=7037810611998542250 are : attribute count 0 and values are: attr_id: 16 sint: 0 attribute count 1 and values are: attr_id: 9 sint: 50sint: 240sint: 240 attribute count 2 and values are: attr_id: 12 std: LPM std: NORMAL std: HIGH_PERF attribute count 3 and values are: attr_id: 5 std: sns_accel.proto attribute count 4 and values are: attr_id: 0 std: icm4x6xx attribute count 5 and values are: attr_id: 1 std: TDK-Invensense attribute count 6 and values are: attr_id: 26 boolean 1 attribute count 7 and values are: attr_id: 17 boolean 0 attribute count 8 and values are: attr_id: 10 sint: 6 attribute count 9 and values are: attr_id: 15 sint: 16 attribute count 10 and values are: attr_id: 21 boolean 1 attribute count 11 and values are: attr_id: 22 sint: 3sint: 2sint: 1 attribute count 12 and values are: attr_id: 2 std: accel attribute count 13 and values are: attr_id: 4 sint: 82179 attribute count 14 and values are: attr_id: 13 boolean 1 attribute count 15 and values are: attr_id: 14 boolean 0 attribute count 16 and values are: attr_id: 18 sint: 0 attribute count 17 and values are: attr_id: 20 flt: 0.000000 flt: 0.000000 flt: 0.000000 flt: 0.000000 flt: 0.000000 flt: 0.000000flt: 0.000000 flt: 0.000000 flt: 0.000000 flt: 0.000000 flt: 0.000000 flt: 0.000000 attribute count 18 and values are: attr_id: 19 sint: 0 attribute count 19 and values are: attr_id: 11 attribute count 20 and values are: attr_id: 7 flt: 0.000019 flt: 0.000037 flt: 0.000075 flt: 0.000150 flt: 0.000299 attribute count 21 and values are: attr_id: 24 attribute count 22 and values are: attr_id: 23 flt: 0.000299 attribute count 23 and values are: attr_id: 6 flt: 12.500000 flt: 25.000000 flt: 50.000000 flt: 100.000000 flt: 200.000000 flt: 500.000000 attribute count 24 and values are: attr_id: 25 flt: 1000.000000 flt: 2000.000000 attribute count 25 and values are: attr_id: 8 sint: 80 attribute count 26 and values are: attr_id: 3 boolean 1 Attributes for all suids received Streaming started sending request for - suid_low=6360260105974108950 suid_high=7037810611998542250 Data request response received. Received re-configuration event Cal event packet received Received Samples: [0.347159], [-0.181959], [9.450213], Received Samples: [0.102951], [-0.183156], [9.545981], Received Samples: [0.096965], [-0.189142], [9.550770], Received Samples: [0.092177], [-0.192733], [9.541193], Received Samples: [0.090980], [-0.183156], [9.555558], Received Samples: [0.093374], [-0.185551], [9.555558], Received Samples: [0.108936], [-0.184354], [9.541193], Received Samples: [0.098162], [-0.185551], [9.565135], Received Samples: [0.095768], [-0.185551], [9.550770], Received Samples: [0.100556], [-0.193930], [9.550770], Received Samples: [0.092177], [-0.186748], [9.550770], Received Samples: [0.094571], [-0.199916], [9.541193], Received Samples: [0.105345], [-0.199916], [9.550770], Received Samples: [0.098162], [-0.185551], [9.550770], Copy to clipboard See [Debug](https://docs.qualcomm.com/doc/80-70017-7/topic/debug.html#debug), for troubleshooting common issues. For more information, see [Samples > QSH direct channel API workflow](https://docs.qualcomm.com/bundle/resource/topics/80-70017-7A/samples.html#qsh_direct_channel_api_workflow.html) in [Qualcomm Linux Sensors Guide - Addendum](https://docs.qualcomm.com/bundle/resource/topics/80-70017-7A/overview.html). This information is available to licensed users with authorized access. ## QSH sample algorithm and integration with QSH For more information, see [Samples > QSH sample algorithm and integration with QSH](https://docs.qualcomm.com/bundle/resource/topics/80-70017-7A/samples.html#developing_custom_algorithm_and_integrating_with_qualcomm_sensing_hub.html) in [Qualcomm Linux Sensors Guide - Addendum](https://docs.qualcomm.com/bundle/resource/topics/80-70017-7A/overview.html). This information is available to licensed users with authorized access. Note [Qualcomm Linux Sensors Guide - Addendum](https://docs.qualcomm.com/bundle/resource/topics/80-70017-7A/overview.html) is accessible only to the licensed users. Last Published: Dec 24, 2024 [Previous Topic Software](https://docs.qualcomm.com/bundle/publicresource/80-70017-7/topics/software.md) [Next Topic Tools](https://docs.qualcomm.com/bundle/publicresource/80-70017-7/topics/test_tools.md)