<?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>24.12</releaseinfo>
    <author>
      <orgname>ONVIF™</orgname>
      <uri>www.onvif.org</uri>
    </author>
    <pubdate>December 2024</pubdate>
    <mediaobject>
      <imageobject>
        <imagedata fileref="media/logo.png" contentwidth="60mm"/>
      </imageobject>
    </mediaobject>
    <copyright>
      <year>2008-2024</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>
    </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>Sending PTZ and other commands via WebRTC datachannels is outside of the scope of this 
      version of the specifcation.</para>
  </chapter>
  <chapter xml:id="chapter_uxt_v12_v5b">
    <title>Normative references</title>
    <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>
    <para>IETF RFC 6455 - The WebSocket Protocol</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="http://tools.ietf.org/html/rfc6455"/>&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="http://tools.ietf.org/html/rfc6544"/>&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="http://tools.ietf.org/html/rfc8829"/>&gt;</para>
    <para>IETF RFC 5245 - Interactive Connectivity Establishment (ICE)</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
        xlink:href="http://tools.ietf.org/html/rfc5245"/>&gt;</para>
    <para>IETF RFC 8866 - SDP: Session Description Protocol</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
        xlink:href="http://tools.ietf.org/html/rfc8866"/>&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="http://tools.ietf.org/html/rfc8834"/>&gt;</para>
    <para>IETF RFC 8839 - Session Description Protocol (SDP) Offer/Answer Procedures for
      Interactive Connectivity Establishment (ICE)</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="http://tools.ietf.org/html/rfc8839"/>&gt;</para>
    <para>IETF RFC 8840 - A Session Initiation Protocol (SIP) Usage for Incremental Provisioning
      of Candidates for the Interactive Connectivity Establishment (Trickle ICE)</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="http://tools.ietf.org/html/rfc8840"/>&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="http://tools.ietf.org/html/rfc8445"/>&gt;</para>
    <para>IETF RFC 8489 - Session Traversal Utilities for NAT (STUN)</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
        xlink:href="http://tools.ietf.org/html/rfc8489"/>&gt;</para>
    <para>IETF RFC 8656 - Traversal Using Relays around NAT (TURN)</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
        xlink:href="http://tools.ietf.org/html/rfc8856"/>&gt;</para>
    <para>IETF RFC 7519 - JSON Web Token (JWT)</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="http://tools.ietf.org/html/rfc7519"/>&gt;</para>
    <para>IETF RFC 6749 - The OAuth 2.0 Authorization Framework</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="http://tools.ietf.org/html/rfc6749"/>&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="http://tools.ietf.org/html/rfc6750"/>&gt;</para>
    <para>IETF RFC 7064 - URI Scheme for the Session Traversal Utilities for NAT (STUN) Protocol</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://datatracker.ietf.org/doc/html/rfc7064"/>&gt;</para>
    <para>IETF RFC 7065 - Traversal Using Relays around NAT (TURN) Uniform Resource Identifiers</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://datatracker.ietf.org/doc/html/rfc7065"/>&gt;</para>
    <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>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>OpenID Connect Core</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://openid.net/specs/openid-connect-core-1_0.html"/>&gt;</para>
    <para>ONVIF Security Service Specification</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink"
      xlink:href="https://www.onvif.org/specs/srv/security/ONVIF-Security-Service-Spec.pdf"/>&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">Peer ID</emphasis>
                </para>
              </entry>
              <entry>
                <para>A peer's assigned ID provided by the signaling server.</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 this figure,<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>
    <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>
    <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>Both a client and a device shall provide their JWT access token using the Authorization header
        or via query parameter on the WebSocket URI as defined by [RFC6750] 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 [JSON-RPC section 4.2]. The table below provides the encodings to
        be used.</para>
      <para>
        <table frame="all">
          <title>Parameter encoding</title>
          <tgroup cols="2">
            <colspec colname="c1" colnum="1" colwidth="2.0*"/>
            <colspec colname="c2" colnum="2" colwidth="8.0*"/>
            <thead>
              <row>
                <entry><para>Type</para></entry>
                <entry><para>Encoding</para></entry>
              </row>
            </thead>
            <tbody>
              <row>
                <entry><para>JWT</para></entry>
                <entry><para>Encoded according to RFC 7519</para></entry>
              </row>
              <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>
      <para>The following sections specify the parameters of the individual commands.</para>
      <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. Token details are outside of the scope of this specification.</para>
        <variablelist role="op">
        <varlistentry>
          <term>request</term>
          <listitem>
            <para role="param">authorization [JWT]</para>
            <para role="text">Access token that authorizes the device or client.</para>
            <para role="param">id optional [string]</para>
            <para role="text">The unique ID of 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>
          </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 JWT token cannot be verified, does not include the required claims or has expired.</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>
      <variablelist role="op">
        <varlistentry>
          <term>request</term>
          <listitem>
              <para role="param">peer optional [string]</para>
            <para role="text">The ID of the peer to connect to.</para>
            <para role="param">authorization [JWT]</para>
            <para role="text">Access token that authorizes the device or client.</para>
            <para role="param">session optional [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">Optional 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 to be used. </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>response</term>
          <listitem>
            <para role="param">session optional [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 to be used. </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>faults</term>
          <listitem>
            <para role="param">401 Authorization failed</para>
            <para role="text">The JWT token cannot be verified, does 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>
            <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 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 are defined in RFC 8829.</para>
      <para>Usage of WebRTC data channels is specified in section <xref linkend="section_data_channels"/>.</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 8840.</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.</para>
    </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 [JSON-RPC] "Request notification" and shall include [JSON-RPC] "Error object" in its <literal>params</literal> field.</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>The following table defines possible error codes:</para>
      <table>
        <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>
    </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": "JWT..."}, "id":1}
Server -> Client: { "result": { "id": "client-a1" }, "id": 1}
Device -> Server: { "method": "register", "params": {"authorization": "JWT..."}, "id":1}
Server -> Device: { "result": { "id": "device-b1" }, "id": 1}

Client -> Server: { "method": "connect", 
                "params": {"authorization": "JWT...", "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": {...}}}
...
]]></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>
    <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 switching the currently
       streamed profile into a profile with a lower bitrate encoding. Devices are allowed to
       switch only between profiles with the same video source and same video codec. Once there
       is enough available bandwidth, devices should aim to switch back to the initially selected
       profile.</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>
      <para></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>When using WebRTC with a web browser only certain codecs will work. Because of this
        ONVIF recommends to use the h.264 codec.</para>
      <para>In line with WebRTC standard, ONVIF also recommends to always use congestion control to
        ensure that WebRTC cannot be used to flood the network.</para>
    </section>
    <section xml:id="section_wyt_v12_v5b">
      <title>Audio</title>
      <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>For two-way audio it's 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 role="revhistory">
    <title>Revision History</title>
    <para/>
  </appendix>
</book>
