<?xml version="1.0"?>
<?xml-stylesheet href="docbook.xsl" type="text/xsl" ?>
<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="book_rxt_v12_v5b">
  <info>
    <title>WebRTC Specification</title>
    <titleabbrev>WebRTC</titleabbrev>
    <releaseinfo>25.12</releaseinfo>
    <author>
      <orgname>ONVIF™</orgname>
      <uri>www.onvif.org</uri>
    </author>
    <pubdate>December, 2025</pubdate>
    <mediaobject>
      <imageobject>
        <imagedata fileref="media/logo.png" contentwidth="60mm"/>
      </imageobject>
    </mediaobject>
    <copyright>
      <year>2008-2025</year>
      <holder>ONVIF™ All rights reserved.</holder>
    </copyright>
    <legalnotice>
      <para>Recipients of this document may copy, distribute, publish, or display this document so
        long as this copyright notice, license and disclaimer are retained with all copies of the
        document. No license is granted to modify this document.</para>
      <para>THIS DOCUMENT IS PROVIDED "AS IS," AND THE CORPORATION AND ITS MEMBERS AND THEIR
        AFFILIATES, MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
        LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
        NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THIS DOCUMENT ARE SUITABLE FOR ANY PURPOSE;
        OR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS,
        TRADEMARKS OR OTHER RIGHTS.</para>
      <para>IN NO EVENT WILL THE CORPORATION OR ITS MEMBERS OR THEIR AFFILIATES BE LIABLE FOR ANY
        DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR
        RELATING TO ANY USE OR DISTRIBUTION OF THIS DOCUMENT, WHETHER OR NOT (1) THE CORPORATION,
        MEMBERS OR THEIR AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR (2)
        SUCH DAMAGES WERE REASONABLY FORESEEABLE, AND ARISING OUT OF OR RELATING TO ANY USE OR
        DISTRIBUTION OF THIS DOCUMENT. THE FOREGOING DISCLAIMER AND LIMITATION ON LIABILITY DO NOT
        APPLY TO, INVALIDATE, OR LIMIT REPRESENTATIONS AND WARRANTIES MADE BY THE MEMBERS AND THEIR
        RESPECTIVE AFFILIATES TO THE CORPORATION AND OTHER MEMBERS IN CERTAIN WRITTEN POLICIES OF
        THE CORPORATION.</para>
    </legalnotice>
    <revhistory>
      <revision>
        <revnumber>24.06</revnumber>
        <date>Jun 2024</date>
        <author>
          <personname>Fredrik Svensson, Jonas Cremon, Karin Hedlund, Hans Busch</personname>
        </author>
        <revremark>First release.</revremark>
      </revision>
      <revision>
        <revnumber>24.12</revnumber>
        <date>Dec 2024</date>
        <author>
          <personname>Jean-Francois Levesque, Jose Melancon</personname>
        </author>
        <revremark>Add requirements for device supporting ICE candidates. Add RTCP &amp; I-Frame request requirements</revremark>
      </revision>
      <revision>
      <revnumber>25.06</revnumber>
        <date>June, 2025</date>
        <author>
          <personname>Tomasz Zajac</personname>
        </author>
        <revremark>Added data channels.</revremark>
      </revision>
      <revision>
        <revnumber>25.12</revnumber>
        <date>Dec, 2025</date>
        <author>
          <personname>Henrik Hein</personname>
        </author>
        <revremark>Added extend method and capabilities.</revremark>
      </revision>
    </revhistory>
  </info>
  <chapter xml:id="chapter_txt_v12_v5b">
    <title>Scope </title>
    <para>This document defines how WebRTC and related protocols are to be used for ONVIF clients
      and devices to establish a peer-to-peer connection between a client and a device using a
      signaling server.</para>
    <para>The client communication with its signaling server is provided as an example, both those
      components belong to the Client and their interaction may be vendor dependent. </para>
    <para>Sending PTZ and other commands via WebRTC datachannels is outside of the scope of this
      version of the specification.</para>
  </chapter>
  <chapter xml:id="chapter_uxt_v12_v5b">
    <title>Normative references</title>
    <para>IETF RFC 4585 - Extended RTP Profile for Real-Time Transport Control Protocol (RTCP)-Based Feedback</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://datatracker.ietf.org/doc/html/rfc4585"/>&gt;</para>
    <para>IETF RFC 5104 - Codec Control Messages in the RTP Audio-Visual Profile with Feedback (AVPF) Profile</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://datatracker.ietf.org/doc/html/rfc5104"/>&gt;</para>
    <para>IETF RFC 6544 - TCP Candidates with Interactive Connectivity Establishment (ICE)</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://tools.ietf.org/html/rfc6544"/>&gt;</para>
    <para>IETF RFC 6455 - The WebSocket Protocol</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://tools.ietf.org/html/rfc6455"/>&gt;</para>
    <para>IETF RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://tools.ietf.org/html/rfc6750"/>&gt;</para>
    <para>IETF RFC 8825 - Overview: Real-Time Protocols for Browser-Based Applications</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
        xlink:href="https://tools.ietf.org/html/rfc8825"/>&gt;</para>
    <para>IETF RFC 8829 - JavaScript Session Establishment Protocol (JSEP)</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
        xlink:href="https://tools.ietf.org/html/rfc8829"/>&gt;</para>
    <para>IETF RFC 8834 - Media Transport and Use of RTP in WebRTC</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://tools.ietf.org/html/rfc8834"/>&gt;</para>
    <para>IETF RFC 8838 - Trickle ICE: Incremental Provisioning of Candidates for the
      Interactive Connectivity Establishment (ICE) Protocol</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://tools.ietf.org/html/rfc8838"/>&gt;</para>
    <para>IETF RFC 8445 - Interactive Connectivity Establishment (ICE)</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
        xlink:href="https://tools.ietf.org/html/rfc8445"/>&gt;</para>
    <para>JSON-RPC 2.0</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://www.jsonrpc.org/specification"/>&gt;</para>
    <para>W3C WebRTC Specification: Real-Time Communication in Browsers</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://www.w3.org/TR/webrtc/"/>&gt;</para>
  </chapter>
  <chapter xml:id="chapter_vxt_v12_v5b">
    <title>Terms and Definitions</title>
    <section xml:id="section_wxt_v12_v5b">
      <title>Definitions</title>
      <informaltable>
        <tgroup cols="2">
          <colspec colname="c1" colwidth="1*"/>
          <colspec colname="c2" colwidth="2.45*"/>
          <tbody valign="top">
            <row>
              <entry align="left">
                <para>
                  <emphasis role="bold">Signaling Server</emphasis>
                </para>
              </entry>
              <entry align="left">
                <para>A server that manages the WebRTC connections between clients and
                  devices.</para>
              </entry>
            </row>
            <row>
              <entry align="left">
                <para>
                  <emphasis role="bold">Session ID</emphasis>
                </para>
              </entry>
              <entry align="left">
                <para>Identifier for a connection between peers.</para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>
    <section xml:id="section_xxt_v12_v5b">
      <title>Abbreviations</title>
      <informaltable>
        <tgroup cols="2">
          <colspec colname="c1" colwidth="24*"/>
          <colspec colname="c2" colwidth="76*"/>
          <tbody valign="top">
            <row>
              <entry valign="middle">
                <para>ICE</para>
              </entry>
              <entry valign="middle">
                <para>Interactive Connectivity Establishment</para>
              </entry>
            </row>
            <row>
              <entry valign="middle">
                <para>NAT</para>
              </entry>
              <entry valign="middle">
                <para>Network Address Translation</para>
              </entry>
            </row>
            <row>
              <entry valign="middle">
                <para>SDP</para>
              </entry>
              <entry valign="middle">
                <para>Session Description Protocol</para>
              </entry>
            </row>
            <row>
              <entry valign="middle">
                <para>STUN</para>
              </entry>
              <entry valign="middle">
                <para>Session Traversal Utilities for NAT</para>
              </entry>
            </row>
            <row>
              <entry valign="middle">
                <para>TURN</para>
              </entry>
              <entry valign="middle">
                <para>Traversal Using Relays around NAT</para>
              </entry>
            </row>
            <row>
              <entry valign="middle">
                <para>WebRTC</para>
              </entry>
              <entry valign="middle">
                <para>Web Real-Time Communication</para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>
  </chapter>
  <chapter xml:id="chapter_yxt_v12_v5b">
    <title>Overview</title>
    <para>The WebRTC standard includes APIs for communicating with an ICE Agent, but the signaling
      component is not part of it. Signaling is needed in order for two peers to share how they
      should connect.</para>
    <para>Signaling can be implemented in many different ways, and the WebRTC standard doesn't
      recommend any specific solution.</para>
    <para>This specification contains documentation and examples of the signaling protocol used in
      ONVIF to set up a WebRTC peer-to-peer connection. The setup involves three participants:
        <emphasis role="italic">client</emphasis>, <emphasis role="italic">device</emphasis> and
        <emphasis role="italic">signaling server</emphasis>.</para>
    <figure xml:id="_Ref493258796">
      <title>Client, device, signaling server</title>
      <mediaobject>
        <imageobject>
          <imagedata fileref="media/WebRTC/client_device_server_triangle.svg"
            contentwidth="120mm"/>
        </imageobject>
      </mediaobject>
    </figure>
    <para>In <xref linkend="_Ref493258796"/><itemizedlist>
        <listitem>
          <para>The <emphasis role="italic">client</emphasis> represents a user who initiates
            the WebRTC session.</para>
        </listitem>
        <listitem>
          <para>The <emphasis role="italic">device</emphasis> is the resource delivering the media,
            for example a camera.</para>
        </listitem>
        <listitem>
          <para>The <emphasis role="italic">signaling server</emphasis> is the mediator that both
              <emphasis role="italic">client</emphasis> and <emphasis role="italic"
              >device</emphasis> connect to in order to establish a peer-to-peer connection between
            them.</para>
        </listitem>
      </itemizedlist></para>
    <para>The <emphasis>Signaling Protocol</emphasis> described in this specification details the
      data exchange between client and device via the signaling server.</para>
    <para>Once a peer-to-peer connection has been established, how WebRTC is used is described in the
      WebRTC usage chapter.</para>
  </chapter>
  <chapter xml:id="chapter_zxt_v12_v5b">
    <title>Signaling Protocol</title>
    <para>The <emphasis role="italic">Signaling Protocol</emphasis> defines the messages between a
      <emphasis role="italic">client</emphasis> and a <emphasis role="italic">device</emphasis>
      with the intention of establishing a WebRTC peer-to-peer connection between the
      client and a device. The messages are always sent via the <emphasis>signaling
        server</emphasis>, called <emphasis>server</emphasis> from now on. Once a peer-to-peer
      connection has been established the connection with the server can be dropped without
      affecting the peer-to-peer connection.</para>
    <para>A WebRTC signaling server may enforce expiration on active sessions by using the ExpiryTime property of the connect command. In such scenarios, the client shall maintain the connection with the signaling <emphasis>server</emphasis> and send extend command periodically before the session expires.</para>
    <figure xml:id="_Ref493258797">
      <title>Signaling flow sequence diagram</title>
      <mediaobject>
        <imageobject>
          <imagedata fileref="media/WebRTC/webrtc_signaling_flow.svg" contentwidth="160mm"/>
        </imageobject>
      </mediaobject>
    </figure>
    <para><xref linkend="_Ref493258797"/> shows an overview of the messages being sent between client, signaling server and device.</para>
    <section>
      <title>WebSocket Connection Management</title>
      <para>Both a client and a device need to connect to the server by setting up a WebSocket
        connection according to RFC 6455. The WebSocket sub protocol shall be set to
        'webrtc.onvif.org'.</para>
      <para>A device shall connect to a signaling server as soon as the configuration contains a valid URI. </para>
      <para>In case a connection is dropped the device shall reconnect automatically. Each client
        should use an individual ascending interval strategy to avoid that all clients reconnect at
        the same time.</para>
      <para>A client as well as a device shall provide their access token using the Authorization header
        or via query parameter on the WebSocket URI as defined by RFC 6750 Section 2.3.</para>
      <para>Once the WebSocket is open, both device and client shall immediately send a register command
        as specified in section <xref linkend="section_register"/> when they receive the HTTP 101 switching
        protocol.</para>
    </section>
    <section xml:id="section_ayt_v12_v5b">
      <title>Communication Protocol</title>
      <para>The communication protocols shall use JSON-RPC version 2 over a WebSocket connection .
        Parameters shall be passed through an Object by-name as defined in JSON-RPC section 4.2. <xref linkend="_Ref_parameter_encoding"/> provides the encodings to
        be used.</para>
      <para>
        <table xml:id="_Ref_parameter_encoding" frame="all">
          <title>Parameter encoding</title>
          <tgroup cols="2">
            <colspec colname="c1" colnum="1" colwidth="1*"/>
            <colspec colname="c2" colnum="2" colwidth="2.36*"/>
            <thead>
              <row>
                <entry>
                  <para>Type</para>
                </entry>
                <entry>
                  <para>Encoding</para>
                </entry>
              </row>
            </thead>
            <tbody>
              <row>
                <entry>
                  <para>SDP</para>
                </entry>
                <entry>
                  <para>SDP according to RFC 8866 with \r\n escaping</para>
                </entry>
              </row>
              <row>
                <entry>
                  <para>IceCandidate</para>
                </entry>
                <entry>
                  <para>JSON encoding according to W3C WebRTC RTCIceCandidateInit</para>
                </entry>
              </row>
              <row>
                <entry>
                  <para>RTCIceServer</para>
                </entry>
                <entry>
                  <para>Connection parameters for a STUN or TURN server as defined by W3C
                    WebRTC</para>
                </entry>
              </row>
              <row>
                <entry>
                  <para>DataChannelSubprotocol</para>
                </entry>
                <entry>
                  <para>Data channel subprotocol identifier</para>
                </entry>
              </row>
            </tbody>
          </tgroup>
        </table>
      </para>
      <section xml:id="section_capabilities">
        <title>Session Capabilities</title>
        <para>When calling connect command, an optional parameter called capabilities may be returned. The capabilities parameter will inform the client of the functionality available in the session. <xref linkend="_Ref_session_capabilities"/> list the possible capabilities</para>
        <table xml:id="_Ref_session_capabilities" frame="all">
          <title>Capabilities</title>
          <tgroup cols="2">
            <colspec colname="c1" colnum="1" colwidth="2.0*"/>
            <colspec colname="c2" colnum="2" colwidth="8.0*"/>
            <thead>
              <row>
                <entry><para>Capability</para></entry>
                <entry><para>Functionality</para></entry>
              </row>
            </thead>
            <tbody>
              <row>
                <entry><para>subProtocols</para></entry>
                <entry><para>SubProtocols are supported, read section <xref linkend="section_data_channels"/>. As

                    Sub-protocols are added before capabilities, some implementations may support this

                    without it being part of the capabilities. Support of these capabilities can be seen within the invite

                    command received.</para></entry>
              </row>
              <row>
                <entry><para>extend</para></entry>
                <entry><para>The Connect command will return an expiry time parameter. It is possible to call the extend command
                    before the expiry time ends to extend the session. </para></entry>
              </row>
            </tbody>
          </tgroup>
        </table>
      </section>
      <section xml:id="section_register">
        <title>register</title>
        <para> A signaling server shall expect this command to be sent once before any other command
          is sent over the WebSocket connection. The signaling server shall verify the validity of
          the access token either provided by the http connect request or as request parameter.
          Token details are outside of the scope of this specification.</para>
        <section xml:id="section_register_client">
          <title>register - Client to Signaling Server</title>
          <para>When the client sends the <literal>register</literal> command to the signaling server</para>
          <variablelist role="op">
            <varlistentry>
              <term>request</term>
              <listitem>
                <para role="param">authorization optional [string]</para>
                <para role="text">Access token that authorizes the device or client.</para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>response</term>
              <listitem>
                <para role="param">id [string]</para>
                <para role="text">The ID assigned by the signaling server to the endpoint. </para>
              </listitem>
            </varlistentry>
            <varlistentry>
                <term>faults</term>
                <listitem>
                  <para role="param">401 Authorization failed</para>
                  <para role="text">The access token cannot be verified or has expired.</para>
                </listitem>
              </varlistentry>
          </variablelist>
        </section>
        <section xml:id="section_register_device">
          <title>register - Device to Signaling Server</title>
          <para>When the device sends the <literal>register</literal> command to the signaling server</para>
          <variablelist role="op">
            <varlistentry>
              <term>request</term>
              <listitem>
                <para role="param">authorization optional [string]</para>
                <para role="text">Access token that authorizes the device or client.</para>
                <para role="param">name optional [string]</para>
                <para role="text">The human readable name of the device or client.</para>
                <para role="param">capabilities optional [string[]]</para>
                <para role="text">Capabilities of the device. This should only be used by the device and
                    the possible values can be found in the section <xref linkend="section_capabilities"
                    />.</para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>response</term>
              <listitem>
                <para role="param">id [string]</para>
                <para role="text">The ID assigned by the signaling server to the endpoint. </para>
              </listitem>
            </varlistentry>
            <varlistentry>
                <term>faults</term>
                <listitem>
                  <para role="param">401 Authorization failed</para>
                  <para role="text">The access token cannot be verified or has expired.</para>
                </listitem>
              </varlistentry>
          </variablelist>
        </section>
      </section>
      <section xml:id="section_unregister">
        <title>unregister</title>
	<para> A client or device may send this to a signaling server before closing the WebSocket
	  connection, indicating that the closing of the WebSocket is intentional and that it no
	  longer wants to be registered. The main use case is to support a device or client that
	  isn't always connected to the network.</para>
        <variablelist role="op">
        <varlistentry>
          <term>request</term>
          <listitem>
            <para role="text">&lt;none&gt;</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>response</term>
          <listitem>
            <para role="text">&lt;none&gt;</para>
          </listitem>
        </varlistentry>
        <varlistentry>
            <term>faults</term>
            <listitem>
              <para role="param">404 Not Found</para>
              <para role="text">Not registered.</para>
            </listitem>
          </varlistentry>
      </variablelist>
      </section>
    <section xml:id="section_init">
      <title>connect</title>
      <para>An ONVIF compliant signaling server and device shall support this command to establish a
        streaming session between two peers. </para>
      <section xml:id="section_connect_client">
        <title>connect - Client to Signaling Server</title>
        <para>When the client sends the <literal>connect</literal> command to the signaling server</para>
        <variablelist role="op">
          <varlistentry>
            <term>request</term>
            <listitem>
              <para role="param">peer [string]</para>
              <para role="text">The ID of the peer the client wants to connect to. This ID is defined outside of this specification and must be negotiated out-of-band.</para>
              <para role="param">authorization [string]</para>
              <para role="text">Access token of the client to be authorized by the signaling server.</para>
              <para role="param">profile optional [string]</para>
              <para role="text">Token of the media streaming profile to use.</para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term>response</term>
            <listitem>
              <para role="param">session [string]</para>
              <para role="text">The ID assigned by the signaling server to the session.</para>
              <para role="param">iceServers optional unbounded [RTCIceServer]</para>
              <para role="text">List of STUN and TURN servers provided by the signaling server to be used for this session.</para>
              <para role="param">expiryTimeSeconds optional [integer]</para>
              <para role="text">The time represented in seconds before the session ends.</para>
              <para role="param">capabilities optional [string[]]</para>
              <para role="text">A list of capabilities supported for a session.</para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term>faults</term>
            <listitem>
              <para role="param">401 Authorization failed</para>
              <para role="text">The access token cannot be verified or has expired.</para>
              <para role="param">403 Forbidden</para>
              <para role="text">The client is not authorized to connect to the provided peer.</para>
              <para role="param">480 Temporary unavailable.</para>
              <para role="text">The target device is currently unavailable.</para>
            </listitem>
          </varlistentry>
        </variablelist>
      </section>
      <section xml:id="section_connect_device">
        <title>connect - Signaling Server to Device</title>
        <para>When the signaling server forwards the <literal>connect</literal> command to the device</para>
        <variablelist role="op">
          <varlistentry>
            <term>request</term>
            <listitem>
              <para role="param">session [string]</para>
              <para role="text">The ID assigned by the signaling server to the session.</para>
              <para role="param">profile optional [string]</para>
              <para role="text">Token of the media streaming profile to use.</para>
              <para role="param">iceServers optional unbounded [RTCIceServer]</para>
              <para role="text">List of STUN and TURN servers provided by the signaling server to be used for this session.</para>
              <para role="param">expiryTimeSeconds optional [integer]</para>
              <para role="text">The time represented in seconds before the session ends.</para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term>response</term>
            <listitem>
              <para role="param">capabilities optional [string[]]</para>
              <para role="text">A list of capabilities supported for a session.
                This list shall be the same as the list provided with the <literal>register</literal> command.</para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term>faults</term>
            <listitem>
              <para role="param">480 Temporary unavailable.</para>
              <para role="text">The target device is currently unavailable.</para>
            </listitem>
          </varlistentry>
        </variablelist>
        <para>An ONVIF compliant signaling server shall provide the session ID and a list of STUN and TURN servers in
          both request and response such that both device and client can use them.
          A compliant client and device shall support password based authentication of TURN server.
          The urls parameter of the iceServers shall always be encoded as array of strings. The
          optional shortcut defined by W3C WebRTC specification of passing a single string shall not
          be used. </para>
        <para>An ONVIF compliant device shall issue an invite method immediately after responding to
          this method.</para>
      </section>
    </section>
    <section xml:id="section_invite">
      <title>invite</title>
      <para>An ONVIF compliant signaling server shall support this command to establish a streaming
        session between two peers. It shall forward this command to the client and correspondingly
        route the response back to the device.</para>
      <para>The dynamics and the format of the SDP records shall be according to RFC 8829 section 5.2 and 5.3.</para>
      <para>Note that since supporting trickle is mandatory the SDP offer / answer shall include the SDP attribute "ice-options:trickle".</para>
      <para>Usage of WebRTC data channels is specified in section <xref linkend="section_data_channels"/>.</para>
      <para>'subprotocols' list included in Invite response from the device may vary depending on
          the Profile configuration identified via profile token sent in <xref
            linkend="section_connect_device"/> request.</para>
      <variablelist role="op">
        <varlistentry>
          <term>request</term>
          <listitem>
            <para role="param">session [string]</para>
            <para role="text">The ID assigned by the signaling server to the session. </para>
            <para role="param">offer [SDP]</para>
            <para role="text">The SDP offer provided by the device. </para>
            <para role="param">subprotocols optional unbounded [DataChannelSubprotocol]</para>
            <para role="text">List of data channel subprotocols to be allowed</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>response</term>
          <listitem>
            <para role="param">answer [SDP]</para>
            <para role="text">The SDP answer provided by the client. </para>
            <para role="param">subprotocols optional unbounded [DataChannelSubprotocol]</para>
            <para role="text">List of data channel subprotocols to be allowed</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>faults</term>
          <listitem>
            <para role="param">400 Bad Request</para>
            <para role="text">Invalid session ID or SDP payload.</para>
            <para role="param">408 Request Timeout</para>
            <para role="text">The peer did not react.</para>
            <para role="param">410 Gone</para>
            <para role="text">The peer is no more available.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section>
    <section xml:id="section_trickle">
      <title>trickle</title>
      <para>An ONVIF compliant signaling server, device and client shall support this command to
        signal new ICE candidates for the trickleICE procedure as defined in RFC 8838.</para>
      <para>A signaling server shall relay this command unaltered to the peer.</para>
      <variablelist role="op">
        <varlistentry>
          <term>request</term>
          <listitem>
            <para role="param">session [string]</para>
            <para role="text">The ID assigned by the signaling server to the session. </para>
            <para role="param">candidate [IceCandidate]</para>
            <para role="text">The ICE Candidate SDP update for the peer. </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>response</term>
          <listitem>
            <para role="text">&lt;none&gt;</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>faults</term>
          <listitem>
            <para role="text">&lt;none&gt;</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>Both client and device produce ICE candidates and send them to each other, via the
          server. Once all ICE candidates have been sent by a peer, it shall send a last trickle
          notification with an empty ICE candidate content to indicate that all candidates have
          been sent according to RFC 8838.</para>
      <para><emphasis role="bold">NOTE</emphasis>: Note that ICE candidates can arrive <emphasis
        role="bold">before</emphasis> the SDP offer and the implementing client needs to handle
        this.</para>
      <para>If everything works as it should, a peer-to-peer WebRTC session can be set up between
        client and device. After the session has been established the client can terminate the
        WebSocket session to the signaling server and the peer-to-peer connection will not be
        affected. The only reason to keep the connection to the server is if the client needs to extend the session.</para>
    </section>
    <section xml:id="section_extend">
      <title>extend</title>
      <para>This command updates a session if more time is required. If an expiryTime is given
          during the connect command response, the session will timeout. It is possible to request
          an extension by just sending a new authorization token to the signaling server.</para>
      <section xml:id="section_extend_client">
        <title>extend - Client to Signaling Server</title>
        <para>When the client sends the <literal>extend</literal> command to the signaling server</para>
        <variablelist role="op">
          <varlistentry>
            <term>request</term>
            <listitem>
              <para role="param">session [string]</para>
              <para role="text">The ID assigned by the signaling server to the session.</para>
              <para role="param">authorization optional [string]</para>
              <para role="text">Access token that authorizes the client.</para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term>response</term>
            <listitem>
              <para role="param">expiryTimeSeconds [integer]</para>
              <para role="text">The time represented in seconds until the session expires.</para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term>faults</term>
            <listitem>
              <para role="param">401 Authorization failed</para>
              <para role="text">The authorization token cannot be verified. The authorization token may not include the required claims, or has expired.</para>
              <para role="param">403 Forbidden</para>
              <para role="text">The client is not authorized to connect to the provided peer.</para>
            </listitem>
          </varlistentry>
        </variablelist>
      </section>
      <section xml:id="section_extend_device">
        <title>extend - Device to Signaling Server</title>
        <para>When the device sends the <literal>extend</literal> command to the signaling server</para>
        <variablelist role="op">
          <varlistentry>
            <term>request</term>
            <listitem>
              <para role="param">session [string]</para>
              <para role="text">The ID assigned by the signaling server to the session.</para>
              <para role="param">expiryTimeSeconds optional [integer]</para>
              <para role="text">The new expiry time requested by the signaling server represented in seconds.</para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term>response</term>
            <listitem>
              <para role="param">expiryTimeSeconds [integer]</para>
              <para role="text">The time represented in seconds until the session expires.</para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term>faults</term>
            <listitem>
              <para role="param">401 Authorization failed</para>
              <para role="text">The authorization token cannot be verified. The authorization token may not include the required claims, or has expired.</para>
              <para role="param">403 Forbidden</para>
              <para role="text">The client is not authorized to connect to the provided peer.</para>
            </listitem>
          </varlistentry>
        </variablelist>
      </section>
    </section>  
    <section xml:id="section_error_notification">
      <title>error</title>
      <para>An ONVIF compliant signaling server, device and client shall support sending or receiving notifications signaling that an error has occurred.</para>
			<para>This message is a "Response" or "Notification" message as defined by JSON-RPC and shall contain "Error object" as defined by JSON-RPC. If the error is not connected to a request, but sent as a notification, the id shall be omittedt.</para>
      <variablelist role="op">
        <varlistentry>
          <term>request</term>
          <listitem>
            <para role="param">code [int]</para>
            <para role="text">A number that indicates the error type that occurred.</para>
            <para role="param">message [string]</para>
            <para role="text">A string providing a short description of the error. The message should be limited to a concise single sentence.</para>
            <para role="param">session [string]</para>
            <para role="text">The ID assigned by the signaling server to the session. </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>response</term>
          <listitem>
            <para role="text">&lt;none&gt;</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>faults</term>
          <listitem>
            <para role="text">&lt;none&gt;</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para><xref linkend="_Ref_possible_error_codes"/> defines possible error codes:</para>
      <table xml:id="_Ref_possible_error_codes">
        <title>WebRTC signaling errors</title>
        <tgroup cols="3">
          <colspec colname="c1" colwidth="49*" />
          <colspec colname="c2" colwidth="13*" />
          <colspec colname="c3" colwidth="37*" />
          <thead>
            <row>
              <entry>
                <para>Signaling Error</para>
              </entry>
              <entry>
                <para>Error Code</para>
              </entry>
              <entry>
                <para>Reason</para>
              </entry>
            </row>
          </thead>
          <tbody valign="top">
            <row>
              <entry>
                <para>Insufficient resources</para>
              </entry>
              <entry>
                <para>1001</para>
              </entry>
              <entry>
                <para>The peer does not have sufficient resources.</para>
              </entry>
            </row>
            <row>
              <entry>
                <para>Peer disconnected</para>
              </entry>
              <entry>
                <para>1002</para>
              </entry>
              <entry>
                <para>A peer in the session has closed its websocket connection with the Signaling Server.</para>
              </entry>
            </row>
            <row>
              <entry>
                <para>Malformed candidate</para>
              </entry>
              <entry>
                <para>1003</para>
              </entry>
              <entry>
                <para>The trickle ICE candidate received is malformed.</para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </table>
      <para>Note that the message layout slightly deviates from the JSON RPC 2.0 specification.</para>
    </section>
    <section>
      <title>Example Flow (informative)</title>
      <para>The following example shows the flow using JSON-RPC 2.0. Note that for improved
          readability the mandatory JSON version string is not shown.</para>
      <programlisting><![CDATA[
Client -> Server: { "method": "register", "params": {"authorization": "access token"}, "id":1}
Server -> Client: { "result": { "id": "client-a1" }, "id": 1}
Device -> Server: { "method": "register", "params": {"authorization": "access token"}, "id":1}
Server -> Device: { "result": { "id": "device-b1" }, "id": 1}

Client -> Server: { "method": "connect",
                "params": {"authorization": "access token", "peer": "device-b1"}, "id":2}
Server -> Device: { "method": "connect",
                "params": {"session": "s1", "iceServers": [{"urls": ["stun:1.2.3.4"]}],
                "id":2}
Device -> Server: { "result": {}, "id": 2}
Server -> Client: { "result": {"session": "s1",
                "iceServers": [{"urls": ["stun:1.2.3.4"]}]}, "id": 2}

Device -> Server: { "method": "invite", "params": {"session": "s1", "offer": "SDP...",
                "subprotocols": ["proto1"]}, "id":3}
Server -> Client: { "method": "invite", "params": {"session": "s1", "offer": "SDP...",
                "subprotocols": ["proto1"]}, "id":3}
Client -> Server: { "result": {"answer": "SDP...", "subprotocols": ["proto1"]}, "id": 3}
Server -> Device: { "result": {"answer": "SDP...", "subprotocols": ["proto1"]}, "id": 3}

Device -> Server: { "method": "trickle", "params": {"session": "s1", "candidate": {...}}}
Server -> Client: { "method": "trickle", "params": {"session": "s1", "candidate": {...}}}

Client -> Server: { "method": "trickle", "params": {"session": "s1", "candidate": {...}}}
Server -> Device: { "method": "trickle", "params": {"session": "s1", "candidate": {...}}}

Client -> Server: { "method": "trickle", "params": {"session": "s1", "candidate": {...}}}
Server -> Device: { "method": "trickle", "params": {"session": "s1", "candidate": {...}}}
...
Client -> Server: { "method": "extend", "params": {"session": "s1", "authorization": "...",
                "id": 4}
Server -> Client: { "error": {"code": -32601, "message": "Method not found"}, "id": "4"}
...
Device -> Server: { "error": {"code": 1001, "message": "Insufficient resources"}}
Server -> Client: { "error": {"code": 1001, "message": "Insufficient resources"}}

]]></programlisting>
    </section>
    </section>
  </chapter>
  <chapter xml:id="chapter_uyt_v12_v5b">
    <title>WebRTC Usage</title>
    <para>This chapter describes ONVIF specific usage of WebRTC regarding how to send data between
      the client and device on the peer-to-peer connection.</para>
    <para>If not otherwise stated in this specification, an ONVIF compliant implementation shall
      be done in accordance with the WebRTC Non-Browser requirements in RFC 8825.</para>
    <section xml:id="section_uyt_v12_v5b">
      <title>Bandwidth management</title>
      <para>Devices may define profiles for different streaming scenarios that can be chosen by the
      client based on the available bandwidth or other limiting factors. For example, a specific
      profile for mobile clients, another one for high quality streaming, etc.</para>
      <para>Devices should estimate available uplink bandwidth and reduce stream
        bitrate as needed to avoid packet loss. It may be achieved by selecting video stream
        from another profile with the same video source and the same video codec.
        Once there is enough available bandwidth, devices should aim to switch back to the desired
        configuration.</para>
    </section>
    <section xml:id="section_xyt_v12_v5b">
      <title>Feedback mechanisms</title>
      <para>Devices shall be able to exchange RTCP feedback with their peer as defined in RFC 8834.
        In particular, devices shall handle FIR messages, as defined in RFC 5104, and PLI messages,
        as defined in RFC 4585, and attempt to provide a synchronization point according to the
        semantics of these requests.</para>
    </section>
    <section>
      <title>Congestion control</title>
      <para>ONVIF recommends to always use congestion control to ensure that WebRTC cannot be used
        to flood the network. For additional information, IETF recommends to use mechanism specified
        in RFC8836 while many actual implementations refer to [RTP Extension for congestion control]
        and its out of the scope for this specification to mandate specific congestion control
        mechanism.</para>
    </section>
    <section>
      <title>ICE candidates</title>
        <para>A device shall support generating and receiving host, server reflexive and relay ICE candidates as defined in RFC 8445.</para>
        <para>A device shall handle passive ICE TCP candidates as defined in RFC 6544. On reception, it shall generate an active ICE TCP candidate to match and establish a TCP connection to the endpoint announced by the candidate. A device is not required to listen on a TCP endpoint and generate a passive ICE TCP candidate.</para>
    </section>
    <section xml:id="section_vyt_v12_v5b">
      <title>Video</title>
      <para>RFC 7742, required by RFC 8825, defines "WebRTC Video Processing and Codec Requirements". This
        specification removes the requirements in sections 5 "Mandatory-to-Implement Video Codec".
      <para>When using WebRTC with a web browser only certain codecs will work. Because of this
        ONVIF recommends to use the h.264 codec.</para>
    </section>
    <section xml:id="section_wyt_v12_v5b">
      <title>Audio</title>
      <para>RFC 7874, required by RFC 8825, defines "WebRTC Audio Codec and Processing Requirements". This
        specification removes the requirements in sections 3 "Codec requirements".
      <para>When using WebRTC with a web browser only certain codecs will work. Because of this
        ONVIF recommends to use the Opus or PCMU codec.</para>
      <para>If the selected media profile contains an AudioDecoder, the device shall include an
        audio track with <literal>a=recvonly</literal> in its SDP offer. If the selected media profile contains
        an AudioEncoder, the device shall include an audio track with <literal>a=sendonly in its SDP offer</literal>.
        If the profile contains both AudioEncoder and AudioDecoder, the device shall include an audio
        track with <literal>a=sendrecv</literal> in its SDP offer. For two-way audio it is  recommended to use echo 
        cancellation to avoid feedback loops.</para>
    </section>
    <section xml:id="section_data_channels">
      <title>Data channels</title>
        <section xml:id="section_data_channels_enable">
          <title>Enabling data channels</title>
            <para>If the device supports WebRTC data channels, it shall signal this in the SDP offer
              of the invite method. If the client supports data channels and intends to use them during
              the WebRTC session, it shall signal this in the SDP answer.</para>
            <para>ONVIF-defined data channel subprotocol names shall have “vnd.onvif” prefix.
              Usage of this prefix is restricted to ONVIF-defined subprotocols only.</para>
            <para>Before creating and using any data channel subprotocol, the device and client shall
              exchange a list of allowed data channel subprotocols in the invite method. Only
              subprotocols provided by both the device and client during the invite method shall be
              allowed to be enabled during the WebRTC session.</para>
            <para>At any time after obtaining a WebRTC connection, a client may request enabling a
              pre-negotiated data channel subprotocol by creating a new data channel with the specified
              subprotocol identifier. Device shall enable the requested data channel subprotocol only
              after ensuring it was negotiated during the SDP exchange; otherwise, it shall close the
              data channel.
            </para>
        </section>
        <section xml:id="section_data_channels_metadata">
          <title>Metadata over data channels</title>
          <para><emphasis role="bold">Subprotocol identifier</emphasis>: vnd.onvif.metadata+gzip</para>
            <para>The Metadata data channel subprotocol enables streaming XML Metadata over WebRTC data
              channels. An ONVIF compliant device supporting streaming of metadata shall support gzip
              compressed metadata as signaled via the subprotocol vnd.onvif.metadata+gzip.
            </para>
            <para>A device shall use the MetadataConfiguration from the media streaming profile selected
              for the WebRTC session and ignore the CompressionType setting.</para>
            <para>The data channel Metadata payload is a binary data channel message starting with a GZIP
              header according to RFC 1952, followed by the compressed data. Messages may be fragmented as
              needed, and the client shall determine the beginning of a new GZIP payload based on the
              existence of the GZIP header.</para>
        </section>
    </section>
  </chapter>
  <appendix>
    <title>Bibliography</title>
    <para>[RFC7742] WebRTC Video Processing and Codec Requirements</para>
    <para role="reference">[<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://datatracker.ietf.org/doc/html/rfc7742"/></para>
    <para>[RFC7874] WebRTC Audio Codec and Processing Requirements</para>
    <para role="reference">[<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://datatracker.ietf.org/doc/html/rfc7474"/></para>
    <para>[RFC8836] Congestion Control Requirements for Interactive Real-Time Media</para>
    <para role="reference">[<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://datatracker.ietf.org/doc/html/rfc8836"/></para>
    <para>[RTP Extension for congestion control] RTP Extensions for Transport-wide Congestion Control</para>
    <para role="reference">[<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://datatracker.ietf.org/doc/html/draft-holmer-rmcat-transport-wide-cc-extensions-01"/></para>
  </appendix>
  <appendix role="revhistory">
    <title>Revision History</title>
    <para/>
  </appendix>
</book>
