# Samples

Source: [https://docs.qualcomm.com/doc/80-70014-7/topic/samples.html](https://docs.qualcomm.com/doc/80-70014-7/topic/samples.html)

The following samples explain the end-to-end use case of QSH with API usage.

## QSH client APIs workflow

Source: [https://docs.qualcomm.com/doc/80-70014-7/topic/samples.html](https://docs.qualcomm.com/doc/80-70014-7/topic/samples.html)

Sensor application clients interact with the QSH, which is located 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.
Figure : QSH client API workflow
                
                <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by Microsoft Visio, SVG Export qsh-client-api-workflow.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="4.97917in" height="5.63542in" viewbox="0 0 358.5 405.75" xml:space="preserve" color-interpolation-filters="sRGB" class="st14"><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-1 .st1 { fill: #f7f8fa; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.75 }
.svg-1 .st2 { fill: #f7f8fa; stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st3 { fill: #000000; font-family: Arial; font-size: 1.00001em }
.svg-1 .st4 { stroke: #000000; stroke-dasharray: 7, 5; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st5 { marker-end: url("#mrkr5-20"); stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st6 { fill: #000000; fill-opacity: 1; stroke: #000000; stroke-opacity: 1; stroke-width: 0.28409090909091 }
.svg-1 .st7 { fill: #ffffff; stroke: none; stroke-linecap: butt; stroke-width: 7.2 }
.svg-1 .st8 { fill: #000000; font-family: Arial; font-size: 0.833336em }
.svg-1 .st9 { marker-start: url("#mrkr5-28"); stroke: #000000; stroke-dasharray: 7, 5; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st10 { fill: none; stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st11 { marker-end: url("#mrkr5-20"); stroke: #000000; stroke-linecap: butt; stroke-width: 1 }
.svg-1 .st12 { fill: none; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.75 }
.svg-1 .st13 { fill: #000000; font-family: Arial; font-size: 0.666664em }
.svg-1 .st14 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<defs id="Markers">	<g id="lend5">		<path d="M 2 1 L 0 0 L 1.98117 -0.993387 C 1.67173 -0.364515 1.67301 0.372641 1.98465 1.00043 " style="stroke:none"></path>	</g>	<marker id="mrkr5-20" class="st6" v:arrowtype="5" v:arrowsize="2" v:setback="6.16" refx="-6.16" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend5" transform="scale(-3.52,-3.52) "></use>	</marker>	<marker id="mrkr5-28" class="st6" v:arrowtype="5" v:arrowsize="2" v:setback="5.8" refx="5.8" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend5" transform="scale(3.52) "></use>	</marker></defs><g v:mid="0" v:index="1" v:groupcontext="foregroundPage">	<title>Page-1</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="19" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<g id="shape30-1" v:mid="30" v:groupcontext="shape" transform="translate(18.375,-18.375)">		<title></title>		<rect x="0" y="36.75" width="321.75" height="369" class="st1"></rect>	</g>	<g id="shape2-3" v:mid="2" v:groupcontext="shape" transform="translate(73.25,-356.75)">		<title></title>		<desc>Application</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="42.75" cy="392.25" width="85.5" height="27"></v:textrect>		<rect x="0" y="378.75" width="85.5" height="27" class="st2"></rect>		<text x="13.4" y="395.85" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Application</text>		</g>	<g id="shape4-6" v:mid="4" v:groupcontext="shape" transform="translate(202.625,-356.75)">		<title></title>		<desc>libSensingHubSession</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="66.375" cy="392.25" width="132.75" height="27"></v:textrect>		<rect x="0" y="378.75" width="132.75" height="27" class="st2"></rect>		<text x="6.34" y="395.85" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>libSensingHubSession</text>		</g>	<g id="shape5-9" v:mid="5" v:groupcontext="shape" transform="translate(520.625,49) rotate(90)">		<title></title>		<path d="M0 405.75 L306.07 405.75" class="st4"></path>	</g>	<g id="shape6-12" v:mid="6" v:groupcontext="shape" transform="translate(674.75,49) rotate(90)">		<title></title>		<path d="M0 405.75 L305.85 405.75" class="st4"></path>	</g>	<g id="shape7-15" v:mid="7" v:groupcontext="shape" transform="translate(114.875,-338.75)">		<title></title>		<desc>getSession</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="405.75" width="154.13" height="0"></v:textrect>		<path d="M0 405.75 L147.96 405.75" class="st5"></path>		<rect v:rectcontext="textBkgnd" x="52.3235" y="399.75" width="49.4783" height="12.0001" class="st7"></rect>		<text x="52.32" y="408.75" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>getSession</text>		</g>	<g id="shape8-23" v:mid="8" v:groupcontext="shape" transform="translate(114.875,-320.75)">		<title></title>		<desc>ISession*</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="405.75" width="154.13" height="0"></v:textrect>		<path d="M5.8 405.75 L6.16 405.75 L154.12 405.75" class="st9"></path>		<rect v:rectcontext="textBkgnd" x="55.9391" y="399.75" width="42.2468" height="12.0001" class="st7"></rect>		<text x="55.94" y="408.75" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>ISession*</text>		</g>	<g id="shape9-31" v:mid="9" v:groupcontext="shape" transform="translate(114.875,-302.75)">		<title></title>		<desc>Open</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="405.75" width="154.13" height="0"></v:textrect>		<path d="M0 405.75 L147.96 405.75" class="st5"></path>		<rect v:rectcontext="textBkgnd" x="64.8311" y="399.75" width="24.463" height="12.0001" class="st7"></rect>		<text x="64.83" y="408.75" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Open</text>		</g>	<g id="shape10-38" v:mid="10" v:groupcontext="shape" transform="translate(114.875,-284.75)">		<title></title>		<desc>success/fail</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="405.75" width="154.13" height="0"></v:textrect>		<path d="M5.8 405.75 L6.16 405.75 L154.12 405.75" class="st9"></path>		<rect v:rectcontext="textBkgnd" x="51.2196" y="399.75" width="51.6857" height="12.0001" class="st7"></rect>		<text x="51.22" y="408.75" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>success/fail</text>		</g>	<g id="shape11-45" v:mid="11" v:groupcontext="shape" transform="translate(23.75,-131.75)">		<title></title>		<rect x="0" y="263.438" width="310.5" height="142.312" class="st10"></rect>	</g>	<g id="shape12-47" v:mid="12" v:groupcontext="shape" transform="translate(114.875,-253.25)">		<title></title>		<desc>setCallBacks</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="405.75" width="154.13" height="0"></v:textrect>		<path d="M0 405.75 L147.96 405.75" class="st5"></path>		<rect v:rectcontext="textBkgnd" x="48.1632" y="399.75" width="57.7988" height="12.0001" class="st7"></rect>		<text x="48.16" y="408.75" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>setCallBacks</text>		</g>	<g id="shape13-54" v:mid="13" v:groupcontext="shape" transform="translate(114.875,-237.5)">		<title></title>		<desc>success/fail</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="405.75" width="154.13" height="0"></v:textrect>		<path d="M5.8 405.75 L6.16 405.75 L154.12 405.75" class="st9"></path>		<rect v:rectcontext="textBkgnd" x="51.2196" y="399.75" width="51.6857" height="12.0001" class="st7"></rect>		<text x="51.22" y="408.75" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>success/fail</text>		</g>	<g id="shape14-61" v:mid="14" v:groupcontext="shape" transform="translate(114.875,-212.75)">		<title></title>		<desc>sendRequest</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="405.75" width="154.13" height="0"></v:textrect>		<path d="M0 405.75 L147.96 405.75" class="st5"></path>		<rect v:rectcontext="textBkgnd" x="47.5969" y="399.75" width="58.9312" height="12.0001" class="st7"></rect>		<text x="47.6" y="408.75" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>sendRequest</text>		</g>	<g id="shape15-68" v:mid="15" v:groupcontext="shape" transform="translate(114.875,-197)">		<title></title>		<desc>success/fail</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="405.75" width="154.13" height="0"></v:textrect>		<path d="M5.8 405.75 L6.16 405.75 L154.12 405.75" class="st9"></path>		<rect v:rectcontext="textBkgnd" x="51.2196" y="399.75" width="51.6857" height="12.0001" class="st7"></rect>		<text x="51.22" y="408.75" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>success/fail</text>		</g>	<g id="shape16-75" v:mid="16" v:groupcontext="shape" transform="translate(32.25,-140.75)">		<title></title>		<rect x="0" y="360.75" width="288.5" height="45" class="st10"></rect>	</g>	<g id="shape17-77" v:mid="17" v:groupcontext="shape" transform="translate(114.875,-156.5)">		<title></title>		<desc>sensorEvent</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="405.75" width="154.13" height="0"></v:textrect>		<path d="M5.8 405.75 L6.16 405.75 L154.12 405.75" class="st9"></path>		<rect v:rectcontext="textBkgnd" x="49.2693" y="399.75" width="55.5867" height="12.0001" class="st7"></rect>		<text x="49.27" y="408.75" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>sensorEvent</text>		</g>	<g id="shape18-84" v:mid="18" v:groupcontext="shape" transform="translate(114.875,-113.75)">		<title></title>		<desc>close()</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="405.75" width="154.13" height="0"></v:textrect>		<path d="M0 405.75 L147.96 405.75" class="st5"></path>		<rect v:rectcontext="textBkgnd" x="62.0601" y="399.75" width="30.005" height="12.0001" class="st7"></rect>		<text x="62.06" y="408.75" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>close()</text>		</g>	<g id="shape19-91" v:mid="19" v:groupcontext="shape" transform="translate(114.875,-95.75)">		<title></title>		<path d="M5.8 405.75 L6.16 405.75 L154.12 405.75" class="st9"></path>	</g>	<g id="shape20-96" v:mid="20" v:groupcontext="shape" transform="translate(114.875,-77.75)">		<title></title>		<v:userdefs>			<v:ud v:nameu="TextPos" v:val="VT0(2):26"></v:ud>			<v:ud v:nameu="Scale" v:val="VT0(1):26"></v:ud>			<v:ud v:nameu="AntiScale" v:val="VT0(1):26"></v:ud>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>			<v:ud v:nameu="msvDisableCustomConnectionPoints" v:prompt="" v:val="VT0(1):5"></v:ud>		</v:userdefs>		<path d="M0 405.75 L31.95 405.75 A6.75 6.75 0 0 1 38.7 412.5 L38.7 412.5 A6.75 6.75 0 0 1 31.95 419.25 L6.16 419.25" class="st11"></path>	</g>	<g id="shape21-101" v:mid="21" v:groupcontext="shape" transform="translate(72.125,-23.75)">		<title></title>		<desc>Application</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="42.75" cy="392.25" width="85.5" height="27"></v:textrect>		<rect x="0" y="378.75" width="85.5" height="27" class="st2"></rect>		<text x="13.4" y="395.85" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Application</text>		</g>	<g id="shape22-104" v:mid="22" v:groupcontext="shape" transform="translate(202.625,-23.75)">		<title></title>		<desc>libSensingHubSession</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="66.375" cy="392.25" width="132.75" height="27"></v:textrect>		<rect x="0" y="378.75" width="132.75" height="27" class="st2"></rect>		<text x="6.34" y="395.85" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>libSensingHubSession</text>		</g>	<g id="shape23-107" v:mid="23" v:groupcontext="shape" transform="translate(29.375,-72.125)">		<title></title>		<desc>delete ISession*</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="41.625" cy="400.687" width="83.25" height="10.125"></v:textrect>		<rect x="0" y="395.625" width="83.25" height="10.125" class="st12"></rect>		<text x="5.49" y="403.69" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>delete ISession*</text>		</g>	<g id="shape26-110" v:mid="26" v:groupcontext="shape" transform="translate(23.75,537.437) scale(1,-1)">		<title></title>		<desc>opt</desc>		<v:userdefs>			<v:ud v:nameu="CTypeTopLeftSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CTypeTopRightSnip" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CTypeBotLeftSnip" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CTypeBotRightSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockHoriz" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockVert" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockDiag" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="TopLeftOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.15):1"></v:ud>			<v:ud v:nameu="BotLeftOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="BotRightOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="visVersion" v:prompt="" v:val="VT0(15):26"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.08203125):1"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="12.375" cy="399.844" width="24.75" height="11.8125"></v:textrect>		<path d="M0 405.75 L24.75 405.75 L24.75 399.84 L18.84 393.94 L0 393.94 L0 405.75 Z" class="st2"></path>		<text x="6.81" y="-397.44" transform="scale(1,-1)" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>opt</text>		</g>	<g id="shape27-113" v:mid="27" v:groupcontext="shape" transform="translate(32.25,626.25) scale(1,-1)">		<title></title>		<desc>loop</desc>		<v:userdefs>			<v:ud v:nameu="CTypeTopLeftSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CTypeTopRightSnip" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CTypeBotLeftSnip" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CTypeBotRightSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockHoriz" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockVert" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockDiag" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="TopLeftOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.15):1"></v:ud>			<v:ud v:nameu="BotLeftOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="BotRightOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="visVersion" v:prompt="" v:val="VT0(15):26"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.087890625):1"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="14.625" cy="399.422" width="29.25" height="12.6562"></v:textrect>		<path d="M0 405.75 L29.25 405.75 L29.25 399.42 L22.92 393.09 L0 393.09 L0 405.75 Z" class="st2"></path>		<text x="7.06" y="-397.02" transform="scale(1,-1)" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>loop</text>		</g>	<g id="shape28-116" v:mid="28" v:groupcontext="shape" transform="translate(50.5,-262.25)">		<title></title>		<desc>[perSUID]</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="22.25" cy="400.687" width="44.51" height="10.125"></v:textrect>		<rect x="0" y="395.625" width="44.5" height="10.125" class="st12"></rect>		<text x="4.69" y="403.09" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>[perSUID]</text>		</g>	<g id="shape29-119" v:mid="29" v:groupcontext="shape" transform="translate(59.25,-173.859)">		<title></title>		<desc>[sensorEvent]</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="29.25" cy="400.687" width="58.5" height="10.125"></v:textrect>		<rect x="0" y="395.625" width="58.5" height="10.125" class="st12"></rect>		<text x="4.79" y="403.09" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>[sensorEvent]</text>		</g></g>
</svg>

- **getSessions**

    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 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 establishes, the application or the client code
                        can open a sensor session by calling the `open()` API. It is
                        important to note that 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 properly 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 indication 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, the protocol
                buffer-encoded messages are placed inside them. 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 [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) and [https://github.com/nanopb/nanopb](https://github.com/nanopb/nanopb).

### Client manager

The client manager for the sensors, which is located on the QSH, is in-charge of all
                communications. The responsibilities of the client manager are as follows:

- **Translating incoming requests**: The client manager takes 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 can be understood 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 that the client has
                        specified.
    For more information on 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 consider this ID as generated randomly upon
                        boot and make no assumptions regarding repeatability, nor do they obtain 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. All
                                request messages must be sent 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 what 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**is about 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
                                        `<workspace>/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. This payload must be decoded
                                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-70014-7/topic/samples.html#qsh_client_apis__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-70014-7/topic/samples.html#qsh_client_apis__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 gets notified when there is a
                                                  change in the attributes of a sensor using
                                                  `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
                                                  `<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, Qualcomm has defined a set
                                of standardized messages recommended for use by the sensor
                                developers. 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*. The client can also specify using
                                        `register_updates`, whether to register for
                                    notifications when a new match occurs. 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<br>                                                  be queried |
        | `register_updates` | Optional | Boolean | Register for updates to the list of SUIDs<br>                                                  advertising the `data_type`<br>                                                  field |
        | `default_only` | Optional | Boolean | Each data type may have one sensor configured<br>                                                  to be *default* through the registry.<br><br><br>                                                  <br><ul class="ul" id="qsh_client_apis__ul_fly_t3d_51c_monicapa_03-18-24-1744-55-67"><br>                                                  <li class="li">If the <code class="ph codeph">default_only</code>field is<br>                                                  set to True and:<ul class="ul" id="qsh_client_apis__ul_p3k_kxp_n1c_monicapa_02-24-24-1032-28-71"><br>                                                  <li class="li">a default for the data type is explicitly<br>                                                  configured, then only the SUID of the default<br>                                                  sensor is sent through the SUID event when<br>                                                  available</li><br><br>                                                  <li class="li">a default for the data type is not explicitly<br>                                                  configured, then the SUID of the first sensor with<br>                                                  the matching data type is sent through the SUID<br>                                                  event</li><br><br>                                                  </ul><br></li><br><br>                                                  <li class="li"><br>                                                  <p class="p">If the <code class="ph codeph">default_only</code> field is<br>                                                  set to False, then all the sensors with the<br>                                                  matching data type are sent as and when they<br>                                                  become available.</p><br><br>                                                  </li><br><br>                                                  </ul> |

        For more information, see the
                                        `sns_suid.proto` file and example code.
- **Sensor attributes**: Every sensor publishes a list of attributes, where
                        each attribute is represented by 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 | Data type used by this sensor, as defined in the<br>                                            sensor proto file. |
    | 3 | `SNS_STD_SENSOR_ATTRID_AVAILABLE` | Yes | Boolean | Indicates whether this sensor is available for the<br>                                                clients or not. |
    | 4 | `SNS_STD_SENSOR_ATTRID_VERSION` | Yes | Integer | <ul class="ul" id="qsh_client_apis__ul_jrl_ksw_p1c_monicapa_03-03-24-1237-45-279"><br>                                                <li class="li">64‑bit integer value represented as<br>                                                  major[31:16].minor[15:8].revision[7:0], denoting<br>                                                  the sensor version.</li><br><br>                                                <li class="li">Example in hexadecimal: major: 0x0002 minor:<br>                                                  0x00 revision:0x36.</li><br><br>                                                <li class="li">DRIVER_VERSION 0x00020036.</li><br><br>                                            </ul> |
    | 5 | `SNS_STD_SENSOR_ATTRID_API` | Yes | String | List of the `.proto` filenames used by<br>                                                this sensor; more `.proto`<br>                                                dependencies may be specified as imports within the<br>                                                same proto file used primarily for the test<br>                                                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<br>                                                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 defining operating modes<br>                                                supported by the sensor.<br><br><br>                                            <br>For example, [LPM, HIGH\_PERF, NORMAL, OFF]. |
    | 13 | `SNS_STD_SENSOR_ATTRID_DRI` | No | Boolean | Denotes whether the sensor supports the DRI or<br>                                                  IBI:<ul class="ul" id="qsh_client_apis__ul_krr_4jh_r1c_monicapa_03-08-24-1337-17-768"><br>                                                  <li class="li">True = DRI</li><br><br>                                                  <li class="li">False = IBI</li><br><br>                                                </ul> |
    | 14 | `SNS_STD_SENSOR_ATTRID_STREAM_SYNC` | No | Boolean | Denotes whether a sensor supports synchronized<br>                                            streaming. |
    | 15 | `SNS_STD_SENSOR_ATTRID_EVENT_SIZE` | No | Integer | <ul class="ul" id="qsh_client_apis__ul_cx4_5sw_p1c_monicapa_03-03-24-1240-43-216"><br>                                                <li class="li">The size (in bytes) of the data event<br>                                                  (protocol-buffer-encoded) produced by this<br>                                                  sensor.</li><br><br>                                                <li class="li">For physical and virtual sensors, this value<br>                                                  refers to the size of their sensor sample</li><br><br>                                                <li class="li">Used by the HAL for maximum batching capacity<br>                                                  determination.</li><br><br>                                            </ul> |
    | 16 | `SNS_STD_SENSOR_ATTRID_STREAM_TYPE` | Yes | Integer | Denotes type of streaming supported by the<br>                                                sensor:<br><ul class="ul" id="qsh_client_apis__ul_rt4_xsw_p1c_monicapa_03-03-24-1241-35-856"><br>                                                <li class="li">0 = Continuous periodic sampling</li><br><br>                                                <li class="li">1 = On-change</li><br><br>                                                <li class="li">2 = Single output (one-shot)</li><br><br>                                            </ul> |
    | 17 | `SNS_STD_SENSOR_ATTRID_DYNAMIC` | No | Boolean | Specifies if this sensor is dynamic<br>                                            (connected/disconnected at runtime). |
    | 18 | `SNS_STD_SENSOR_ATTRID_HW_ID` | No | Integer | Differentiates multiple sensors of the same<br>                                            hardware. |
    | 19 | `SNS_STD_SENSOR_ATTRID_RIGID_BODY` | No | Integer | The rigid body on which the sensor is placed.<br><ul class="ul" id="qsh_client_apis__ul_xy2_1tw_p1c_monicapa_03-03-24-1242-21-959"><br>                                                <li class="li">0 = Sensor hardware is on the display side</li><br><br>                                                <li class="li">1 = Sensor hardware is on the keyboard side</li><br><br>                                                <li class="li">2 = Sensor hardware is mounted on an external<br>                                                  device</li><br><br>                                            </ul> |
    | 21 | `SNS_STD_SENSOR_ATTRID_PHYSICAL_SENSOR` | No | Boolean | <ul class="ul" id="qsh_client_apis__ul_nvp_btw_p1c_monicapa_03-03-24-1242-46-883"><br>                                                <li class="li">True, if physical sensor.</li><br><br>                                                <li class="li">False, if virtual sensor.</li><br><br>                                            </ul> |
    | 22 | `SNS_STD_SENSOR_ATTRID_PHYSICAL_SENSOR_TESTS` | No | Integer | List of supported physical sensor tests using enum<br>                                                values in `<br>                                                  sns_physical_sensor_test_type`. |
    | 23 | `SNS_STD_SENSOR_ATTRID_SELECTED_RESOLUTION` | No | Float | Measurement resolution for each dynamic range<br>                                                value. |
    | 24 | `SNS_STD_SENSOR_ATTRID_SELECTED_RANGE` | No | Float[2] | Dynamic range options supported by the sensor. For<br>                                                the default option, see the requirement<br>                                                specification. |
    | 25 | `SNS_STD_SENSOR_ATTRID_ADDITIONAL_LOW_LATENCY_RATES` | No | Float | List of additional sample rates for low-latency<br>                                                operation, in Hz. These sample rates are for<br>                                                dedicated low-latency clients, extending the list of<br>                                                rates published in the<br>                                                  `SNS_STD_SENSOR_ATTRID_RATES`<br>                                                attribute.<br><br><br>                                            <br>Use of these higher data rates may impact system<br>                                                performance and must only be used by the dedicated<br>                                                internal clients. |
    | 26 | `SNS_STD_SENSOR_ATTRID_PASSIVE_REQUEST` | No | Boolean | True if the sensor supports passive requests, false<br>                                                otherwise. If a sensor does not support passive<br>                                                requests, then all requests must be treated as<br>                                                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<br>                                            level operating system (HLOS) specification for the<br>                                            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,<br>                                                  `sns_tech` in<br>                                                  `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 Callflow and usage of QSH client APIs with QSH

Source: [https://docs.qualcomm.com/doc/80-70014-7/topic/samples.html](https://docs.qualcomm.com/doc/80-70014-7/topic/samples.html)

A sample application named `SessionClient` is provided as reference to
            demonstrate the QSH Client API usage. This sample application is built by default and
            located in `/usr/bin` folder on the device. For complete sample code, see
                `<workspace>/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.

Figure : Callflow to stream a given sensor
                
            <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by Microsoft Visio, SVG Export callflow-to-stream-a-given-sensor.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.01042in" height="5.33333in" viewbox="0 0 360.75 384" xml:space="preserve" color-interpolation-filters="sRGB" class="st15"><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-2 .st1 { fill: #f7f8fa; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.75 }
.svg-2 .st2 { fill: #f7f8fa; stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-2 .st3 { fill: #000000; font-family: Arial; font-size: 1.00001em }
.svg-2 .st4 { stroke: #000000; stroke-dasharray: 7, 5; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-2 .st5 { marker-end: url("#mrkr5-20"); stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-2 .st6 { fill: #000000; fill-opacity: 1; stroke: #000000; stroke-opacity: 1; stroke-width: 0.28409090909091 }
.svg-2 .st7 { fill: #ffffff; stroke: none; stroke-linecap: butt; stroke-width: 7.2 }
.svg-2 .st8 { fill: #000000; font-family: Arial; font-size: 0.833336em }
.svg-2 .st9 { marker-start: url("#mrkr5-28"); stroke: #000000; stroke-dasharray: 7, 5; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-2 .st10 { fill: none; stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-2 .st11 { marker-end: url("#mrkr5-20"); stroke: #000000; stroke-linecap: butt; stroke-width: 1 }
.svg-2 .st12 { fill: none; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.75 }
.svg-2 .st13 { fill: #000000; font-family: Arial; font-size: 0.666664em }
.svg-2 .st14 { fill: #ffffff; stroke: none; stroke-linecap: butt }
.svg-2 .st15 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<defs id="Markers">	<g id="lend5">		<path d="M 2 1 L 0 0 L 1.98117 -0.993387 C 1.67173 -0.364515 1.67301 0.372641 1.98465 1.00043 " style="stroke:none"></path>	</g>	<marker id="mrkr5-20" class="st6" v:arrowtype="5" v:arrowsize="2" v:setback="6.16" refx="-6.16" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend5" transform="scale(-3.52,-3.52) "></use>	</marker>	<marker id="mrkr5-28" class="st6" v:arrowtype="5" v:arrowsize="2" v:setback="5.8" refx="5.8" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend5" transform="scale(3.52) "></use>	</marker></defs><g v:mid="0" v:index="1" v:groupcontext="foregroundPage">	<title>Page-1</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="19" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<g id="shape1007-1" v:mid="1007" v:groupcontext="shape" transform="translate(18.375,-18.375)">		<title></title>		<rect x="0" y="36.75" width="324" height="347.25" class="st1"></rect>	</g>	<g id="shape2-3" v:mid="2" v:groupcontext="shape" transform="translate(73.625,-334.625)">		<title></title>		<desc>Application</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="42.75" cy="370.5" width="85.5" height="27"></v:textrect>		<rect x="0" y="357" width="85.5" height="27" class="st2"></rect>		<text x="13.4" y="374.1" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Application</text>		</g>	<g id="shape4-6" v:mid="4" v:groupcontext="shape" transform="translate(203,-334.625)">		<title></title>		<desc>libSensingHubSession</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="66.375" cy="370.5" width="132.75" height="27"></v:textrect>		<rect x="0" y="357" width="132.75" height="27" class="st2"></rect>		<text x="6.34" y="374.1" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>libSensingHubSession</text>		</g>	<g id="shape5-9" v:mid="5" v:groupcontext="shape" transform="translate(499.25,49.375) rotate(90)">		<title></title>		<path d="M0 384 L287 384" class="st4"></path>	</g>	<g id="shape6-12" v:mid="6" v:groupcontext="shape" transform="translate(653.375,49.375) rotate(90)">		<title></title>		<path d="M0 384 L305.85 384" class="st4"></path>	</g>	<g id="shape7-15" v:mid="7" v:groupcontext="shape" transform="translate(115.25,-316.625)">		<title></title>		<desc>getSession</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="384" width="154.13" height="0"></v:textrect>		<path d="M0 384 L147.96 384" class="st5"></path>		<rect v:rectcontext="textBkgnd" x="52.3235" y="378" width="49.4783" height="12.0001" class="st7"></rect>		<text x="52.32" y="387" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>getSession</text>		</g>	<g id="shape8-23" v:mid="8" v:groupcontext="shape" transform="translate(115.25,-298.625)">		<title></title>		<desc>ISession*</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="384" width="154.13" height="0"></v:textrect>		<path d="M5.8 384 L6.16 384 L154.12 384" class="st9"></path>		<rect v:rectcontext="textBkgnd" x="55.9391" y="378" width="42.2468" height="12.0001" class="st7"></rect>		<text x="55.94" y="387" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>ISession*</text>		</g>	<g id="shape11-31" v:mid="11" v:groupcontext="shape" transform="translate(24.125,-229.875)">		<title></title>		<rect x="0" y="330" width="310.5" height="54" class="st10"></rect>	</g>	<g id="shape12-33" v:mid="12" v:groupcontext="shape" transform="translate(115.25,-261.375)">		<title></title>		<desc>get SUID using ISession*</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="384" width="154.13" height="0"></v:textrect>		<path d="M0 384 L147.96 384" class="st5"></path>		<rect v:rectcontext="textBkgnd" x="20.9215" y="378" width="112.282" height="12.0001" class="st7"></rect>		<text x="20.92" y="387" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>get SUID using ISession*</text>		</g>	<g id="shape13-40" v:mid="13" v:groupcontext="shape" transform="translate(115.25,-243.375)">		<title></title>		<desc>SUID</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="384" width="154.13" height="0"></v:textrect>		<path d="M5.8 384 L6.16 384 L154.12 384" class="st9"></path>		<rect v:rectcontext="textBkgnd" x="65.1168" y="378" width="23.8917" height="12.0001" class="st7"></rect>		<text x="65.12" y="387" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>SUID</text>		</g>	<g id="shape14-47" v:mid="14" v:groupcontext="shape" transform="translate(115.25,-196.125)">		<title></title>		<desc>get Attributes using ISession*</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="384" width="154.13" height="0"></v:textrect>		<path d="M0 384 L147.96 384" class="st5"></path>		<rect v:rectcontext="textBkgnd" x="11.7466" y="378" width="130.632" height="12.0001" class="st7"></rect>		<text x="11.75" y="387" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>get Attributes using ISession*</text>		</g>	<g id="shape15-54" v:mid="15" v:groupcontext="shape" transform="translate(115.25,-180.375)">		<title></title>		<desc>Attributes</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="384" width="154.13" height="0"></v:textrect>		<path d="M5.8 384 L6.16 384 L154.12 384" class="st9"></path>		<rect v:rectcontext="textBkgnd" x="55.9416" y="378" width="42.2419" height="12.0001" class="st7"></rect>		<text x="55.94" y="387" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Attributes</text>		</g>	<g id="shape17-61" v:mid="17" v:groupcontext="shape" transform="translate(115.25,-112.875)">		<title></title>		<desc>sensorEvents</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="384" width="154.13" height="0"></v:textrect>		<path d="M5.8 384 L6.16 384 L154.12 384" class="st9"></path>		<rect v:rectcontext="textBkgnd" x="46.7691" y="378" width="60.5869" height="12.0001" class="st7"></rect>		<text x="46.77" y="387" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>sensorEvents</text>		</g>	<g id="shape20-68" v:mid="20" v:groupcontext="shape" transform="translate(115.25,-83.625)">		<title></title>		<v:userdefs>			<v:ud v:nameu="TextPos" v:val="VT0(2):26"></v:ud>			<v:ud v:nameu="Scale" v:val="VT0(1):26"></v:ud>			<v:ud v:nameu="AntiScale" v:val="VT0(1):26"></v:ud>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>			<v:ud v:nameu="msvDisableCustomConnectionPoints" v:prompt="" v:val="VT0(1):5"></v:ud>		</v:userdefs>		<path d="M0 384 L31.95 384 A6.75 6.75 0 0 1 38.7 390.75 L38.7 390.75 A6.75 6.75 0 0 1 31.95 397.5 L6.16 397.5" class="st11"></path>	</g>	<g id="shape21-73" v:mid="21" v:groupcontext="shape" transform="translate(72.375,-24)">		<title></title>		<desc>Application</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="42.75" cy="370.5" width="85.5" height="27"></v:textrect>		<rect x="0" y="357" width="85.5" height="27" class="st2"></rect>		<text x="13.4" y="374.1" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Application</text>		</g>	<g id="shape22-76" v:mid="22" v:groupcontext="shape" transform="translate(203.217,-24)">		<title></title>		<desc>libSensingHubSession</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="66.375" cy="370.5" width="132.75" height="27"></v:textrect>		<rect x="0" y="357" width="132.75" height="27" class="st2"></rect>		<text x="6.34" y="374.1" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>libSensingHubSession</text>		</g>	<g id="shape23-79" v:mid="23" v:groupcontext="shape" transform="translate(29.75,-78)">		<title></title>		<desc>delete ISession*</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="41.625" cy="378.937" width="83.25" height="10.125"></v:textrect>		<rect x="0" y="373.875" width="83.25" height="10.125" class="st12"></rect>		<text x="5.49" y="381.94" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>delete ISession*</text>		</g>	<g id="shape26-82" v:mid="26" v:groupcontext="shape" transform="translate(24.125,484.125) scale(1,-1)">		<title></title>		<desc>opt</desc>		<v:userdefs>			<v:ud v:nameu="CTypeTopLeftSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CTypeTopRightSnip" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CTypeBotLeftSnip" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CTypeBotRightSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockHoriz" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockVert" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockDiag" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="TopLeftOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.15):1"></v:ud>			<v:ud v:nameu="BotLeftOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="BotRightOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="visVersion" v:prompt="" v:val="VT0(15):26"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.08203125):1"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="12.375" cy="378.094" width="24.75" height="11.8125"></v:textrect>		<path d="M0 384 L24.75 384 L24.75 378.09 L18.84 372.19 L0 372.19 L0 384 Z" class="st2"></path>		<text x="6.81" y="-375.69" transform="scale(1,-1)" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>opt</text>		</g>	<g id="shape28-85" v:mid="28" v:groupcontext="shape" transform="translate(48.75,-272.062)">		<title></title>		<desc>[refer QSH Interface]</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="41.625" cy="378.937" width="83.25" height="10.125"></v:textrect>		<rect x="0" y="373.875" width="83.25" height="10.125" class="st12"></rect>		<text x="4.72" y="381.34" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>[refer QSH Interface]</text>		</g>	<g id="shape1000-88" v:mid="1000" v:groupcontext="shape" transform="translate(25.125,-166.875)">		<title></title>		<rect x="0" y="330" width="310.5" height="54" class="st10"></rect>	</g>	<g id="shape1001-90" v:mid="1001" v:groupcontext="shape" transform="translate(25.125,547.125) scale(1,-1)">		<title></title>		<desc>opt</desc>		<v:userdefs>			<v:ud v:nameu="CTypeTopLeftSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CTypeTopRightSnip" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CTypeBotLeftSnip" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CTypeBotRightSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockHoriz" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockVert" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockDiag" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="TopLeftOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.15):1"></v:ud>			<v:ud v:nameu="BotLeftOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="BotRightOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="visVersion" v:prompt="" v:val="VT0(15):26"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.08203125):1"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="12.375" cy="378.094" width="24.75" height="11.8125"></v:textrect>		<path d="M0 384 L24.75 384 L24.75 378.09 L18.84 372.19 L0 372.19 L0 384 Z" class="st2"></path>		<text x="6.81" y="-375.69" transform="scale(1,-1)" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>opt</text>		</g>	<g id="shape1002-93" v:mid="1002" v:groupcontext="shape" transform="translate(49.75,-209.062)">		<title></title>		<desc>[refer QSH Interface]</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="41.625" cy="378.937" width="83.25" height="10.125"></v:textrect>		<rect x="0" y="373.875" width="83.25" height="10.125" class="st12"></rect>		<text x="4.72" y="381.34" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>[refer QSH Interface]</text>		</g>	<g id="shape1003-96" v:mid="1003" v:groupcontext="shape" transform="translate(25.125,-99.375)">		<title></title>		<rect x="0" y="330" width="310.5" height="54" class="st10"></rect>	</g>	<g id="shape1004-98" v:mid="1004" v:groupcontext="shape" transform="translate(25.125,614.625) scale(1,-1)">		<title></title>		<desc>opt</desc>		<v:userdefs>			<v:ud v:nameu="CTypeTopLeftSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CTypeTopRightSnip" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CTypeBotLeftSnip" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CTypeBotRightSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockHoriz" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockVert" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockDiag" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="TopLeftOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.15):1"></v:ud>			<v:ud v:nameu="BotLeftOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="BotRightOffset" v:prompt="" v:val="VT0(0):1"></v:ud>			<v:ud v:nameu="visVersion" v:prompt="" v:val="VT0(15):26"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.08203125):1"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="12.375" cy="378.094" width="24.75" height="11.8125"></v:textrect>		<path d="M0 384 L24.75 384 L24.75 378.09 L18.84 372.19 L0 372.19 L0 384 Z" class="st2"></path>		<text x="6.81" y="-375.69" transform="scale(1,-1)" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>opt</text>		</g>	<g id="shape1005-101" v:mid="1005" v:groupcontext="shape" transform="translate(49.75,-141.563)">		<title></title>		<desc>[refer QSH Interface]</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="41.625" cy="378.937" width="83.25" height="10.125"></v:textrect>		<rect x="0" y="373.875" width="83.25" height="10.125" class="st12"></rect>		<text x="4.72" y="381.34" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>[refer QSH Interface]</text>		</g>	<g id="shape1006-104" v:mid="1006" v:groupcontext="shape" transform="translate(115.25,-128.625)">		<title></title>		<desc>Start Streaming using SUID</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="77.0625" cy="384" width="154.13" height="0"></v:textrect>		<path d="M0 384 L147.96 384" class="st5"></path>		<rect v:rectcontext="textBkgnd" x="15.6484" y="378" width="122.829" height="12.0001" class="st14"></rect>		<text x="15.65" y="387" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Start Streaming using SUID</text>		</g></g>
</svg>

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 a new interface for SUID by calling
                                    `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 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<mutex> 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 a new 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<mutex> 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 a new 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<mutex> 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 accelerometer sensor with 10 Hz sample rate and 2 second batch period for 10
            seconds, 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

## QSH sample algorithm and integration with QSH

Source: [https://docs.qualcomm.com/doc/80-70014-7/topic/samples.html](https://docs.qualcomm.com/doc/80-70014-7/topic/samples.html)

This information is currently available for users who have full access to the proprietary
            software shipped with Qualcomm Linux. For more information, see *Samples* in [Qualcomm Linux Sensors Guide - Addendum](https://docs.qualcomm.com/bundle/resource/topics/80-70014-7A/overview.html).
            
Note: [Qualcomm Linux
                    Sensors Guide - Addendum](https://docs.qualcomm.com/bundle/resource/topics/80-70014-7A/overview.html) is accessible only
                to the Authorized users.

Last Published: Jul 12, 2024

[Previous Topic
Software](https://docs.qualcomm.com/bundle/publicresource/80-70014-7/topics/software.md) [Next Topic
Tools](https://docs.qualcomm.com/bundle/publicresource/80-70014-7/topics/test_tools.md)