> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 QSH 客户端 API 开发应用程序

`SessionClient` 示例应用程序展示了如何使用 QSH 客户端 API 开发应用程序。默认情况下，此示例应用程序构建在设备上的 `/usr/bin` 目录中。有关完整的代码示例，请参阅 `<workspace>/build-qcom-wayland/workspace/sources/sensinghub/sensing-hub/examples/SessionClient/SessionClient.cpp` 文件。

下图显示了流式传输加速度计传感器的调用流程以及 QSH 客户端 API 的使用方法。

<div className="flex flex-col items-center gap-2">
  <img src="https://mintcdn.com/qualcomm-prod/h7j64QujhJHkLxyj/Technologies/Sensors/media/qcs6490/callflow-to-stream-a-given-sensor.svg?fit=max&auto=format&n=h7j64QujhJHkLxyj&q=85&s=004f6a8839bff969d1db8103484f5a58" alt="图：流式传输指定传感器的调用流程" width="801" height="683" data-path="Technologies/Sensors/media/qcs6490/callflow-to-stream-a-given-sensor.svg" />

  <p className="text-sm text-gray-700">图：流式传输指定传感器的调用流程</p>
</div>

在此示例中，客户端应用程序可以针对 SUID 查询、属性查询和流式传输活动使用不同的传感器会话。它也可以对所有活动使用同一个会话；但是，必须妥善处理同步。

客户端应用程序可以向 aDSP 发送各种请求，如下所示：

1. SUID 查询，检索指定传感器的 SUID：

   a. 通过使用新的 `sessionFactory()` 类调用 `getSession()` API 来创建 SUID 接口。请求 SUID 是任何用例中获取所请求数据类型 SUID 的第一个也是最重要的请求。

   ```
   /* 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; 
   }
   ```

   b. 通过调用 `open()` API 打开已创建的会话接口。

   ```
   /* Open the suidSession */ 
     int ret = suidSession->open(); 
     if(-1 == ret){ 
         printf("failed to open ISession for uid query"); 
         return false; 
   }
   ```

   c. 通过调用 `setCallBacks()` API 设置回调，并处理 SUID 活动的响应、事件或错误。

   ```
   /* 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");
   ```

   d. 通过调用 `sendRequest()` API，创建并发送针对指定数据类型 SUID 的 Pb 编码请求消息。

   ```
   /* 
      * 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<mutex> respLock(respMutex); 
      ret = suidSession->sendRequest(uid, pb_req_msg_encoded); 
      if(0 != ret){ 
         printf("Error in sending uid discovery request"); 
         return false; 
   }
   ```

   e. 在收到所请求数据类型的 SUID 事件后，通过调用 `close()` API 关闭会话并将其删除。

   ```
   /* Close and delete the session once SUIDs are received */ 
      suidSession->close(); 
      delete suidSession; 
      delete factory;
   ```

2. 属性请求，检索指定传感器的属性：

   a. 通过使用新的 `sessionFactory()` 类调用 `getSession()` 来创建属性接口会话。请求属性对于获取任何用例中所请求数据类型的能力非常重要。

   ```
   /* 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; 
      }
   ```

   b. 通过调用 `open()` API 打开已创建的会话接口。

   ```
   /* open the attributeSession session */ 
     int ret = attributeSession->open(); 
     if(-1 == ret){ 
         printf("failed to open ISession for attribute query"); 
         return false;
   ```

   c. 通过调用 `setCallBacks()` 设置回调，并处理属性活动的响应、事件或错误。

   ```
   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");
   ```

   d. 通过调用 `sendRequest()` API，创建并发送针对指定数据类型属性的 Pb 编码配置请求。

   ```
   /* 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<mutex> respLock(respMutex); 
      ret = attributeSession->sendRequest(uid, pb_req_msg_encoded);
   ```

   e. 在收到所请求数据类型的属性事件后，通过调用 `close()` API 关闭会话。

   ```
   /* close and delete the session once all attributes are received */ 
      attributeSession->close(); 
      delete attributeSession; 
      delete factory;
   ```

3. 传感器流式传输，流式传输传感器并接收数据事件：

   a. 通过使用新的 `sessionFactory()` 类调用 `getSession()` 来创建用于流式传输传感器的接口会话。在这里，请求传感器数据是任何用例中所请求数据类型的最后阶段。

   ```
   ``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; 
   }
   ```

   b. 通过调用 `open()` API 打开已创建的会话接口。

   ```
   /* open the streamingSession session */ 
      int ret = streamingSession->open(); 
      if(-1 == ret){ 
         printf("failed to open ISession for attribute query"); 
         return false;
   ```

   c. 通过调用 `setCallBacks()` 设置回调，并处理流式传输活动的响应、事件或错误。

   ```
   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");
   ```

   d. 通过调用 `sendRequest()` API，创建并发送针对指定数据类型传感器流式传输的 Pb 编码配置请求，最终启用所请求的传感器。

   ```
   /* 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<mutex> respLock(respMutex); 
      ret = streamingSession->sendRequest(uid, pb_req_msg_encoded);
   ```

   e. 在事件回调中处理样本，并等待指定的测试持续时间。

   ```
      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);
      }
   ```

4. 停止传感器流式传输客户端，通过发送禁用请求来停止流式传输：

   a. 调用 `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);
   ```

   b. 在收到所请求数据类型的流式传输事件后，通过调用 `close()` API 关闭会话。

   ```
   /* close and delete the streamingSession */ 
      streamingSession->close(); 
      delete streamingSession; 
      delete factory;
   ```

以下代码片段显示了 `SessionClient` 示例应用程序的输出。它以 10 Hz 的采样率和 2 秒的批处理周期启用加速度计传感器，持续 10 秒，并打印接收到的传感器事件。

```
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],
```

有关常见问题的故障排查，请参阅"调试"。

有关更多信息，请参阅 [QSH 直接通道 API 工作流](https://docs.qualcomm.com/doc/80-80023-7A/topic/qsh_direct_channel_api_workflow.html)。
