<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.30 (Ruby 4.0.5) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

]>


<rfc ipr="trust200902" docName="draft-ietf-asdf-nipc-21" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="NIPC">An Application Layer Interface for Non-Internet-connected Physical Components (NIPC)</title>

    <author initials="B." surname="Brinckman" fullname="Bart Brinckman">
      <organization>Cisco Systems</organization>
      <address>
        <postal>
          <city>Brussels</city>
          <country>Belgium</country>
        </postal>
        <email>bbrinckm@cisco.com</email>
      </address>
    </author>
    <author initials="R." surname="Mohan" fullname="Rohit Mohan">
      <organization>Cisco Systems</organization>
      <address>
        <postal>
          <street>170 West Tasman Drive</street>
          <city>San Jose</city>
          <code>95134</code>
          <country>USA</country>
        </postal>
        <email>rohitmo@cisco.com</email>
      </address>
    </author>
    <author initials="B." surname="Sanford" fullname="Braeden Sanford">
      <organization>Philips</organization>
      <address>
        <postal>
          <city>Cambridge</city>
          <country>USA</country>
        </postal>
        <email>braeden.sanford@philips.com</email>
      </address>
    </author>

    <date year="2026" month="August" day="11"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 70?>

<t>This document describes an API that allows applications to perform operations against a gateway serving one or more devices described by an SDF model. The API consists of a RESTful application layer interface that performs operations on those devices, as well as a CBOR-based publish-subscribe interface for streaming data.</t>



    </abstract>

    <note title="About This Document" removeInRFC="true">
      <t>
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        A Semantic Definition Format for Data and Interactions of Things Working Group mailing list (<eref target="mailto:asdf@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/asdf/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/asdf/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/ietf-wg-asdf/asdf-nipc"/>.</t>
    </note>


  </front>

  <middle>


<?line 74?>

<section anchor="introduction"><name>Introduction</name>

<section anchor="motivation"><name>Motivation</name>

<t>Low‑power sensors, actuators, and other connected devices deployed for building management, healthcare, workplace, manufacturing, logistics, and hospitality use cases are often resource and battery constrained. Many lack native IP connectivity and instead attach via heterogeneous non‑IP operational networks. Common non‑IP protocols include BLE <xref target="BLE53"/> and Zigbee <xref target="Zigbee22"/>. When IP is available, constrained application protocols such as CoAP <xref target="RFC7252"/> may be used. These devices still need to exchange data with IP‑based applications. Accordingly, applications on the IP network obtain telemetry from and issue operations to such devices through an application‑layer gateway. This gateway bridges the application network and one or more separate operational networks where devices are connected, allowing applications on the IP network to perform operations on devices connected to these other operational networks.</t>

<figure title="Gateway for non-Internet-Connected Devices" anchor="gw"><artset><artwork  type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="128" width="520" viewBox="0 0 520 128" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
<path d="M 8,32 L 8,80" fill="none" stroke="black"/>
<path d="M 120,32 L 120,80" fill="none" stroke="black"/>
<path d="M 240,32 L 240,80" fill="none" stroke="black"/>
<path d="M 320,32 L 320,80" fill="none" stroke="black"/>
<path d="M 440,32 L 440,80" fill="none" stroke="black"/>
<path d="M 512,32 L 512,80" fill="none" stroke="black"/>
<path d="M 8,32 L 120,32" fill="none" stroke="black"/>
<path d="M 240,32 L 320,32" fill="none" stroke="black"/>
<path d="M 440,32 L 512,32" fill="none" stroke="black"/>
<path d="M 128,48 L 232,48" fill="none" stroke="black"/>
<path d="M 328,48 L 432,48" fill="none" stroke="black"/>
<path d="M 8,80 L 120,80" fill="none" stroke="black"/>
<path d="M 240,80 L 320,80" fill="none" stroke="black"/>
<path d="M 440,80 L 512,80" fill="none" stroke="black"/>
<polygon class="arrowhead" points="440,48 428,42.4 428,53.6" fill="black" transform="rotate(0,432,48)"/>
<polygon class="arrowhead" points="336,48 324,42.4 324,53.6" fill="black" transform="rotate(180,328,48)"/>
<polygon class="arrowhead" points="240,48 228,42.4 228,53.6" fill="black" transform="rotate(0,232,48)"/>
<polygon class="arrowhead" points="136,48 124,42.4 124,53.6" fill="black" transform="rotate(180,128,48)"/>
<g class="text">
<text x="64" y="52">Application</text>
<text x="280" y="52">Gateway</text>
<text x="476" y="52">Device</text>
<text x="176" y="68">Application</text>
<text x="380" y="68">Device</text>
<text x="176" y="84">network</text>
<text x="384" y="84">network</text>
</g>
</svg>
</artwork><artwork  type="ascii-art"><![CDATA[
    +-------------+              +---------+              +--------+
    | Application |<------------>| Gateway |<------------>| Device |
    |             | Application  |         |    Device    |        |
    +-------------+   network    +---------+    network   +--------+

]]></artwork></artset></figure>

<t>There have been efforts to define Gateway functions for devices that support
a particular protocol, such as a BLE GATT REST API for BLE Gateways
(<xref target="Gatt-REST-API"/>), however they have been limited to a single protocol or
a particular use case. In absence of an open standard describing how
applications on an IP network communicate with devices on other operational networks, bespoke and
vendor-specific implementations have proliferated.
Each deployment then requires: (1) defining or adapting yet another API, and (2) deploying additional gateway functions, increasing operational and integration cost.
This specification defines a single, extensible application layer interface for cross-network and cross-protocol device interaction through a network gateway. The intent is to support multiple network and network protocols (and versions) concurrently, allow incremental addition of new protocols via mapping, and reduce redundant infrastructure by enabling multiple applications to share one standardized gateway function. Furthermore, by leveraging interaction models, the application and gateway are able to maintain a protocol-neutral interface, while the gateway handles the protocol-specific interactions with devices.</t>

<t>A standardized Application Layer Gateway interface has the following benefits:</t>

<t><list style="numbers" type="1">
  <t>Eliminates repeated bespoke integration effort across deployments.</t>
  <t>Avoids deploying multiple overlapping gateway functions for different networks, protocols or use cases.</t>
  <t>Reduces time and operational cost to integrate new networks and devices.</t>
  <t>Allows applications to interact with devices in a protocol-neutral way, leveraging interaction models.</t>
</list></t>

</section>
<section anchor="nipc-gateway"><name>NIPC Gateway</name>

<t>A Non-Internet-connected Physical Components (NIPC) gateway is an application layer gateway (ALG) that implements APIs for applications to communicate with devices on different networks connected to the Gateway. These devices may leverage different protocols, IP based or non-IP based. Even when the device network uses IP, the ALG may still need to act as an intermediary, since the device network may not be directly reachable from the application network, may use a different overlay protocol than the one expected by applications, or may be subject to a different authorization model. NIPC APIs allow reading or writing properties of devices, invoking actions on devices, as well as enabling or disabling events on devices, by means of a supporting gateway, in a protocol-neutral way.</t>

<t>In order to perform NIPC operations on a device, 2 prerequisites must be fulfilled:</t>

<t><list style="symbols">
  <t>The gateway has access to a device object, that contains its identity, in the form of a unique UUID and any credentials &amp; trust material required to communicate with the device. Provisioning this device object is out of scope of this document. It may be performed via SCIM <xref target="RFC7644"/> with <xref target="RFC9944"/>.</t>
  <t>An interaction model for the class of devices must be available to the gateway. This allows the gateway to understand how to interact with the device in a protocol-neutral way. The interaction model is provided to the gateway by means of an SDF model, as described in <xref target="RFC9880"/>.</t>
</list></t>

<t>Once these prerequisites are met, the gateway can resolve an SDF affordance referenced in the SDF model into the protocol-specific operations required for that device.</t>

<t>A NIPC gateway provides the following functions:</t>

<t><list style="symbols">
  <t>Authentication and authorization of application clients that will leverage the NIPC APIs.</t>
  <t>Maintain or have access to a repository of device objects, including device identity and trust material.</t>
  <t>Accept and validate SDF interaction model registrations.</t>
  <t>Expose APIs for property, action, and event operations.</t>
  <t>Perform implicit connection management to devices where required; optionally support explicit connection management.</t>
  <t>Stream events (publish/subscribe) to authorized data applications.</t>
  <t>Proxy payloads between networks without interpreting or modifying application data.</t>
  <t>Operate one or more channels to supported wired or wireless networks.</t>
  <t>Optionally provide a bridge between devices on one or more device networks connected to the NIPC-Gateway. This may include translating between different protocols, if multiple protocols are supported on the device network(s).</t>
</list></t>

<t>The gateway’s role is to provide gateway functions between application and device networks; it is not intended to be middleware that inspects, decodes, or transforms device payloads.</t>

<figure title="Basic Architecture" anchor="arch"><artset><artwork  type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="288" width="560" viewBox="0 0 560 288" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
<path d="M 8,64 L 8,112" fill="none" stroke="black"/>
<path d="M 8,144 L 8,224" fill="none" stroke="black"/>
<path d="M 104,64 L 104,112" fill="none" stroke="black"/>
<path d="M 104,144 L 104,224" fill="none" stroke="black"/>
<path d="M 208,32 L 208,72" fill="none" stroke="black"/>
<path d="M 208,104 L 208,152" fill="none" stroke="black"/>
<path d="M 208,200 L 208,256" fill="none" stroke="black"/>
<path d="M 232,64 L 232,112" fill="none" stroke="black"/>
<path d="M 232,144 L 232,208" fill="none" stroke="black"/>
<path d="M 312,64 L 312,112" fill="none" stroke="black"/>
<path d="M 336,144 L 336,208" fill="none" stroke="black"/>
<path d="M 368,144 L 368,176" fill="none" stroke="black"/>
<path d="M 432,144 L 432,176" fill="none" stroke="black"/>
<path d="M 464,144 L 464,176" fill="none" stroke="black"/>
<path d="M 536,144 L 536,176" fill="none" stroke="black"/>
<path d="M 552,32 L 552,256" fill="none" stroke="black"/>
<path d="M 208,32 L 552,32" fill="none" stroke="black"/>
<path d="M 8,64 L 104,64" fill="none" stroke="black"/>
<path d="M 232,64 L 312,64" fill="none" stroke="black"/>
<path d="M 104,80 L 224,80" fill="none" stroke="black"/>
<path d="M 112,96 L 232,96" fill="none" stroke="black"/>
<path d="M 8,112 L 104,112" fill="none" stroke="black"/>
<path d="M 232,112 L 312,112" fill="none" stroke="black"/>
<path d="M 8,144 L 104,144" fill="none" stroke="black"/>
<path d="M 232,144 L 336,144" fill="none" stroke="black"/>
<path d="M 368,144 L 432,144" fill="none" stroke="black"/>
<path d="M 464,144 L 536,144" fill="none" stroke="black"/>
<path d="M 104,160 L 136,160" fill="none" stroke="black"/>
<path d="M 176,160 L 224,160" fill="none" stroke="black"/>
<path d="M 336,160 L 360,160" fill="none" stroke="black"/>
<path d="M 432,160 L 456,160" fill="none" stroke="black"/>
<path d="M 368,176 L 432,176" fill="none" stroke="black"/>
<path d="M 464,176 L 536,176" fill="none" stroke="black"/>
<path d="M 112,192 L 128,192" fill="none" stroke="black"/>
<path d="M 192,192 L 232,192" fill="none" stroke="black"/>
<path d="M 232,208 L 336,208" fill="none" stroke="black"/>
<path d="M 8,224 L 104,224" fill="none" stroke="black"/>
<path d="M 208,256 L 552,256" fill="none" stroke="black"/>
<polygon class="arrowhead" points="464,160 452,154.4 452,165.6" fill="black" transform="rotate(0,456,160)"/>
<polygon class="arrowhead" points="368,160 356,154.4 356,165.6" fill="black" transform="rotate(0,360,160)"/>
<polygon class="arrowhead" points="232,160 220,154.4 220,165.6" fill="black" transform="rotate(0,224,160)"/>
<polygon class="arrowhead" points="232,80 220,74.4 220,85.6" fill="black" transform="rotate(0,224,80)"/>
<polygon class="arrowhead" points="120,192 108,186.4 108,197.6" fill="black" transform="rotate(180,112,192)"/>
<polygon class="arrowhead" points="120,96 108,90.4 108,101.6" fill="black" transform="rotate(180,112,96)"/>
<g class="text">
<text x="160" y="68">Request</text>
<text x="60" y="84">onboarding</text>
<text x="268" y="84">SCIM</text>
<text x="56" y="100">app</text>
<text x="268" y="100">Server</text>
<text x="140" y="116">Ctrl</text>
<text x="184" y="116">Endpt</text>
<text x="56" y="164">Control</text>
<text x="156" y="164">REST</text>
<text x="284" y="164">NIPC</text>
<text x="396" y="164">AP</text>
<text x="500" y="164">Device</text>
<text x="56" y="180">&amp;</text>
<text x="208" y="180">|</text>
<text x="288" y="180">Gateway</text>
<text x="56" y="196">Telemetry</text>
<text x="160" y="196">pub/sub</text>
<text x="60" y="212">Apps</text>
<text x="336" y="244">Network</text>
<text x="412" y="244">Deployment</text>
</g>
</svg>
</artwork><artwork  type="ascii-art"><![CDATA[
                         +------------------------------------------+
                         |                                          |
+-----------+   Request  |  +---------+                             |
| onboarding+-------------->|  SCIM   |                             |
|    app    |<--------------+ Server  |                             |
+-----------+  Ctrl Endpt|  +---------+                             |
                         |                                          |
+-----------+            |  +------------+   +-------+   +--------+ |
|  Control  +----REST------>|    NIPC    +-->|  AP   +-->| Device | |
|     &     |            |  |   Gateway  |   +-------+   +--------+ |
| Telemetry |<--pub/sub-----+            |                          |
|    Apps   |            |  +------------+                          |
+-----------+            |                                          |
                         |            Network Deployment            |
                         +------------------------------------------+

]]></artwork></artset></figure>

<t><xref target="arch"/> illustrates the basic components: applications, the NIPC application‑layer gateway (ALG), an access point (AP), and a device (D). The applications, ALG, and AP reside on an IP network; the AP provides a wireless or wired interface to the device. Applications often operate in a different administrative domain than the ALG and AP, so the ALG will have to support authorization. The ALG bridges the IP application domain and the device network, be it an IP-based or non-IP device network. This enables applications to perform operations on devices attached to those device networks. Applications use a JSON-based <xref target="RFC8259"/> RESTful NIPC APIs for property, action, and event operations, and a CBOR‑based <xref target="RFC8949"/> publish/subscribe interface for event streaming.</t>

</section>
<section anchor="terminology"><name>Terminology</name>

<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in BCP
14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they appear in all
capitals, as shown here.</t>

</section>
<section anchor="glossary"><name>Glossary</name>

<t><list style="symbols">
  <t>NIPC: Non-Internet-connected Physical Components, the application layer interface defined in this
document.</t>
  <t>NIPC Gateway: An application layer gateway that implements the NIPC
interface.</t>
  <t>SDF: Semantic Device Format, a standardized format to describe devices
and their interaction models, as defined in <xref target="RFC9880"/>.</t>
  <t>SDF Affordance: An interaction point on a device as defined in an SDF
model. Examples of affordances are properties, actions, and events.</t>
  <t>SDF Global Name: Absolute URI (with fragment) identifying an SDF affordance.</t>
  <t>SCIM: System for Cross-domain Identity Management, a standardized
protocol to manage identity information, as defined in <xref target="RFC7644"/>.</t>
  <t>ALG: Application Layer Gateway.</t>
  <t>IoT: Internet of Things.</t>
  <t>Protocol Mapping / sdfProtocolMap: Mapping from protocol-neutral SDF affordances to protocol-specific operations.</t>
  <t>BLE: Bluetooth Low Energy protocol.</t>
  <t>Zigbee: Low-power mesh networking protocol.</t>
  <t>GATT: Generic Attribute Profile used in BLE for services/characteristics/descriptors.</t>
  <t>Service (BLE): Top-level GATT grouping of characteristics.</t>
  <t>Characteristic (BLE): GATT data element supporting read/write/notify.</t>
  <t>Descriptor (BLE): Metadata element attached to a characteristic.</t>
  <t>Bonding (BLE): Procedure to establish trusted, reusable security keys.</t>
  <t>Service Discovery (BLE): Procedure to enumerate GATT services/characteristics/descriptors.</t>
  <t>Endpoint (Zigbee): Addressable application entity on a Zigbee device, grouping clusters.</t>
  <t>Cluster (Zigbee): Group of related attributes and commands defined by the Zigbee Cluster Library.</t>
  <t>Attribute (Zigbee): Zigbee Cluster Library data element, supporting read/write/report access.</t>
  <t>Device ID / Group ID: UUID identifying a device or a group of devices.</t>
  <t>UUID: Universally unique identifier (128-bit).</t>
  <t>Data Application / Data App: Registered application receiving streamed event data.</t>
  <t>MQTT: Publish/subscribe messaging protocol used for streaming.</t>
  <t>Webhook: HTTP callback endpoint for push delivery.</t>
  <t>Websocket: Bidirectional TCP-based message channel over HTTP.</t>
  <t>Publish/Subscribe Interface: Streaming channel for events (CBOR-encoded payloads).</t>
  <t>CBOR: Concise Binary Object Representation; compact binary data format.</t>
  <t>CDDL: Concise Data Definition Language; schema language for CBOR data.</t>
  <t>JSON: JavaScript Object Notation; text encoding used for API payloads.</t>
  <t>Access Point (AP): Network element with a radio interface communicating with devices.</t>
</list></t>

</section>
</section>
<section anchor="architecture"><name>Architecture</name>

<section anchor="overview"><name>Overview</name>

<t>A Non‑Internet‑Connected Physical Components (NIPC) gateway is an application‑layer gateway (ALG) that exposes APIs enabling applications to perform operations on devices attached to networks connected to the gateway. NIPC defines two API categories:</t>

<t><list style="symbols">
  <t>Registrations: register SDF models for classes of devices and register data applications that receive streaming event data.</t>
  <t>Operations: perform protocol‑neutral device interactions (read/write properties, invoke actions, enable/disable events) across heterogeneous networks and protocols.</t>
</list></t>

<t>To execute NIPC operations on a device, both prerequisites MUST be met:</t>

<t><list style="numbers" type="1">
  <t>The NIPC gateway has access to device instance information: The device object contains its identity, in the form of a unique UUID and any credentials/trust material required to communicate with the device (e.g., via SCIM <xref target="RFC7644"/> with <xref target="RFC9944"/>). This device object is identified by the device ID referenced in NIPC API paths.</t>
  <t>The NIPC gateway has access to an interaction model (device class information): An SDF model <xref target="RFC9880"/> is registered, providing protocol‑neutral affordances and mappings to protocol‑specific operations.</t>
</list></t>

<figure title="NIPC prerequisites" anchor="prereq"><artset><artwork  type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="240" width="352" viewBox="0 0 352 240" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
<path d="M 8,32 L 8,96" fill="none" stroke="black"/>
<path d="M 8,144 L 8,192" fill="none" stroke="black"/>
<path d="M 112,32 L 112,96" fill="none" stroke="black"/>
<path d="M 112,144 L 112,192" fill="none" stroke="black"/>
<path d="M 208,64 L 208,176" fill="none" stroke="black"/>
<path d="M 344,64 L 344,176" fill="none" stroke="black"/>
<path d="M 8,32 L 112,32" fill="none" stroke="black"/>
<path d="M 208,64 L 344,64" fill="none" stroke="black"/>
<path d="M 112,80 L 200,80" fill="none" stroke="black"/>
<path d="M 8,96 L 112,96" fill="none" stroke="black"/>
<path d="M 8,144 L 112,144" fill="none" stroke="black"/>
<path d="M 112,160 L 200,160" fill="none" stroke="black"/>
<path d="M 208,176 L 344,176" fill="none" stroke="black"/>
<path d="M 8,192 L 112,192" fill="none" stroke="black"/>
<polygon class="arrowhead" points="208,160 196,154.4 196,165.6" fill="black" transform="rotate(0,200,160)"/>
<polygon class="arrowhead" points="208,80 196,74.4 196,85.6" fill="black" transform="rotate(0,200,80)"/>
<g class="text">
<text x="60" y="52">SCIM</text>
<text x="60" y="68">object</text>
<text x="60" y="84">{ID}</text>
<text x="236" y="100">NIPC</text>
<text x="296" y="100">Operation</text>
<text x="248" y="116">-</text>
<text x="292" y="116">Property</text>
<text x="248" y="132">-</text>
<text x="284" y="132">Action</text>
<text x="248" y="148">-</text>
<text x="280" y="148">Event</text>
<text x="64" y="164">SDF</text>
<text x="64" y="180">model</text>
</g>
</svg>
</artwork><artwork  type="ascii-art"><![CDATA[
    +------------+
    |    SCIM    |
    |   object   |           +----------------+
    |    {ID}    +---------->|                |
    +------------+           | NIPC Operation |
                             |    - Property  |
                             |    - Action    |
    +------------+           |    - Event     |
    |     SDF    +---------->|                |
    |    model   |           +----------------+
    +------------+

]]></artwork></artset></figure>

<t>Once both prerequisites are met, authorized applications can perform NIPC operations on devices identified by their IDs. See <xref target="security-considerations"/> for authorization details. NIPC operations act on SDF affordances—properties, actions, and events defined in the registered SDF model. Certain NIPC operations may also be performed on groups of devices identified by a group ID.</t>

<section anchor="device-instance-information"><name>Device instance information</name>

<t>In order for the NIPC gateway to perform operations on a device, it must have access to the device's instance information. This includes the device’s identity and any credentials or trust material required to communicate with the device. The device object MUST include a unique identity (UUID) and sufficient information to bootstrap trust and establish connectivity, as NIPC operations assume connectivity can be established without separate API calls. While provisioning devices instance information can be performed in various ways, it is RECOMMENDED to use SCIM <xref target="RFC7644"/> with the device schema <xref target="RFC9944"/>, which defines the necessary attributes and extensions to support NIPC. As per <xref section="4.2" sectionFormat="of" target="RFC7643"/>, group objects may also be declared, and leveraged in NIPC operations.</t>

</section>
<section anchor="device-class-information"><name>Device class information</name>

<t>Device class information is declared through SDF models, as defined in <xref target="RFC9880"/>. These SDF models define the protocol-neutral affordances of a class of devices, as well as protocol mappings <xref target="I-D.ietf-asdf-sdf-protocol-mapping"/> that relate these affordances to protocol-specific operations. The SDF model for a class of devices can be registered through NIPC registration APIs, as described in <xref target="nipc-registrations"/>.</t>

<t>The SDF model reference and/or data‑app registration MAY also be included in a device's SCIM object. See <xref target="RFC9944"/> and <xref target="I-D.ietf-asdf-sdf-protocol-mapping"/> for details.</t>

</section>
</section>
<section anchor="nipc-registrations"><name>NIPC Registrations</name>

<t>NIPC registration APIs allow applications to register objects that are not tied to specific device instances.</t>

<t>NIPC supports two registration types:</t>

<t><list style="numbers" type="1">
  <t>SDF model registration: Registers an SDF interaction model for a class of devices.</t>
  <t>Data application authorization: Authorizes an application to receive streaming event data.</t>
</list></t>

<section anchor="sdf-model-registrations"><name>SDF model registrations</name>

<t>The SDF model for a class of devices determines how a gateway can interact with
these devices in a protocol-neutral way. To enable this, the SDF model
must contain protocol mappings, mapping protocol-neutral SDF affordances
to protocol-specific operations as defined in <xref target="I-D.ietf-asdf-sdf-protocol-mapping"/>.
The SDF affordances supported by the device, as well as its protocol-mappings,
are provided to the gateway by means of an SDF model.
SDF models are described in <xref target="RFC9880"/>.</t>

</section>
<section anchor="data-application-registrations"><name>Data application registrations</name>

<t>NIPC operations can enable or disable event reporting on a device. Events are reported through a publish-subscribe interface.
Applications that are authorized to perform NIPC operations on devices can define which applications are permitted to receive streaming event data for that device. The data-app registrations API maps an event to an application that is authorized to receive that data. The registration also defines what protocol will be used to deliver the data (e.g., MQTT, webhook, websocket). This registration basically allows applications to instruct the gateway to direct event data-streams to specific data-applications.</t>

</section>
</section>
<section anchor="nipc-ops"><name>NIPC Operations</name>

<section anchor="nipc-ops-overview"><name>Overview</name>

<t>NIPC APIs are exposed over HTTP <xref target="RFC9110"/>. Requests and responses use JSON <xref target="RFC8259"/> unless another media type is negotiated via Content-Type and Accept. A media type for an SDF affordance can also be stipulated in the SDF ContentFormat data quality, as described in <xref section="4.7" sectionFormat="of" target="RFC9880"/>. The default media type is “application/nipc+json” (see <xref target="iana-media-types"/>). SDF model registrations use “application/sdf+json”. Property APIs MAY use other media types appropriate to the property payload.</t>

<t>Failures use Problem Details <xref target="RFC9457"/> with media type application/problem+json.</t>

<t>NIPC operations are protocol-neutral operations on SDF affordances, more specifically properties, actions &amp; events. NIPC operations can happen against
affordances registered in an SDF model. Operations reference affordances by their SDF global name. If the underlying protocol requires a connection, the gateway establishes and tears down the connection implicitly unless an explicit connection is already in place.</t>

<t>NIPC exposes four operation groups:</t>

<t><list style="symbols">
  <t>Properties APIs: These APIs allow applications to perform operations on properties, such as to read or write values to them.</t>
  <t>Actions APIs: These APIs perform actions on devices, such as enabling or disabling a feature on a device.</t>
  <t>Events APIs: These APIs allow apps to enable or disable event reporting on devices. Events are reported over the events publish/subscribe interface.</t>
  <t>Trigger APIs: These APIs allow an event on one device or group to trigger an action on another device or group. Trigger APIs are not a fundamental operation, but rather tie 2 fundamental operations together; an event triggers an action.</t>
</list></t>

</section>
<section anchor="properties"><name>Properties</name>

<t>Property operations allow clients to read and write values for SDF properties.</t>

<t>An example of using a property API is reading the property temperature from a temperature sensor.</t>

<t>Requests and responses use application/nipc+json unless another media type is negotiated via Content‑Type and Accept.
When using JSON, binary property values are base64‑encoded with padding per <xref section="4" sectionFormat="of" target="RFC4648"/>. Regardless of media type, the byte order of any multi-byte values within a binary payload is not specified by NIPC and is determined by the underlying protocol.
Multiple properties MAY be read or written in a single request. When a single property is addressed via a query parameter, non‑JSON media types MAY be used for the payload.
On success, the response returns either 200 with per‑property status (JSON) or 204 No Content for single, non‑JSON writes.</t>

</section>
<section anchor="actions"><name>Actions</name>

<t>Action operations invoke SDF actions on devices.</t>

<t>An example of using an action API is to turn on a lightbulb.</t>

<t>A successful action request returns 202 Accepted with a Location header referencing the action instance.
Clients poll the instance URI to obtain status (e.g., IN_PROGRESS, COMPLETED).
Request bodies are optional and MAY carry action input in a media type appropriate to the underlying protocol (e.g., octet‑stream).</t>

</section>
<section anchor="events"><name>Events</name>

<t>Event operations enable and disable device event reporting.</t>

<t>An example of using an event API receiving an event that a button has been pressed.</t>

<t>Enabling an event returns 201 Created with a Location header referencing the event instance.
Disabling an event uses the instance identifier and returns 204 No Content on success (for a single device) or 200 Success with a per‑device status list (for a group).
Event payloads are delivered via the publish/subscribe interface encoded in CBOR <xref target="RFC8949"/>.</t>

</section>
<section anchor="triggers"><name>Triggers</name>

<t>Triggers allow an event on one device or group to trigger an action on another device or group. Triggers are not protocol-specific. As an example, an event on a BLE device can trigger an action on a Zigbee device.</t>

<t>An example of a Trigger is when a button is pressed (event), a lightbulb should turn on (action). Multiple buttons (group) can also turn on a lightbulb (device). A single button (device) could also turn on multiple lights (group).</t>

<t>Creating a trigger returns 201 Created with a Location header referencing the trigger instance.
Deleting a trigger uses the instance identifier and returns 204 No Content on success (for a single device) or 200 Success with a per‑device trigger list (for a group).</t>

</section>
<section anchor="groups"><name>Groups</name>

<t>Where supported by the underlying protocol, operations MAY target a group of devices identified by a group ID. Responses for group operations return per‑device results; failures for individual devices are reported using Problem Details entries within the array.</t>

</section>
<section anchor="connection-management-for-nipc-operations"><name>Connection management for NIPC Operations</name>

<t>For protocols that require connection setup, the gateway performs implicit connection management during an operation (establish on demand; tear down on completion). Gateways MAY support explicit connection management; when an explicit connection is active, operations reuse it and do not tear it down. Explicit connection management is described in <xref target="nipc-connection-management-apis"/>.</t>

</section>
<section anchor="extensions"><name>Extensions</name>

<t>NIPC supports API extensions for compound or specialized operations. Extensions can execute a set of NIPC operations in a single request or provide more efficient mechanisms for specific use cases (e.g., a bulk operation).</t>

<t>Extensions MUST use the “/extensions” path element. To ensure interoperability, extensions MUST be registered with IANA as defined in <xref target="iana-api-ext"/>.</t>

</section>
</section>
<section anchor="events-publish-subscribe-interface"><name>Events publish subscribe interface</name>

<t>Events are delivered via a publish/subscribe interface. NIPC events are encoded in CBOR (<xref target="RFC8949"/>) and can be transported over MQTT, Webhook or Websocket.</t>

<t>CBOR is used for the publish/subscribe interface as Non-IP payloads are typically binary. CBOR encodes binary payloads efficiently, and is more compact than JSON, therefore reducing the amount of data that needs to be transmitted to the application.</t>

<t>Event types include:</t>

<t><list style="symbols">
  <t>Streaming data from devices: Streaming data is activated/deactivated with the NIPC events API</t>
  <t>Broadcasts from devices (e.g., advertisements in BLE)</t>
  <t>Connection events: Devices connecting &amp; disconnecting</t>
</list></t>

</section>
<section anchor="paths"><name>Paths</name>

<section anchor="paths-general"><name>General</name>

<t>The NIPC HTTP protocol is described in terms of a path relative to a Base URI.
The Base URI MUST NOT contain a query string, as clients MAY append additional
path information and query parameters as part of forming the request.  The base
URI is a URL that most often consists of the "https" protocol scheme, a domain
name, and an initial path <xref target="RFC3986"/>.  That initial path for NIPC is
recommended to be /nipc.
For example:</t>

<figure><artwork><![CDATA[
  "https://example.com/nipc/"
]]></artwork></figure>

<t>Additionally a version number may be added, for example:</t>

<figure><artwork><![CDATA[
  "https://example.com/nipc/v1/"
]]></artwork></figure>

<t>After the base or version number, the path must contain a collection identifier.
The collection identifier can be one of the following:</t>

<t><list style="symbols">
  <t>/registrations: for NIPC registration APIs</t>
  <t>/devices: for NIPC operations on devices</t>
  <t>/groups: for NIPC operations on groups of devices</t>
  <t>/extensions: for NIPC extension APIs</t>
</list></t>

<t>The well-known URI <spanx style="verb">/.well-known/nipc</spanx> defined in <xref target="iana-well-known"/> can
be used to discover the base path of the NIPC APIs and the supported versions
and extensions. The response to a GET request on this URI MUST be a JSON
document that contains the base path, and optionally the supported versions and
extension APIs. The paths MUST be a URI template as defined in <xref target="RFC6570"/>.
The following is an example of a template defining the NIPC base path as well
as supported extensions on a server.</t>

<figure title="Example response for /.well-known/nipc" anchor="ex-wellknown"><sourcecode type="json" markers="true"><![CDATA[
{
  "base_path": "/nipc",
  "versions": [
    "/v1"
  ],
  "extensions": [
    "/extensions/{id}/bulk",
    "/extensions/{id}/properties/blob",
    "/extensions/{id}/properties/file",
    "/extensions/{id}/properties/read/conditional",
    "/extensions/{id}/events/conditional"
  ]
}
]]></sourcecode></figure>

<t>A formal CBOR definition of the well-known response is as follows:</t>

<figure><sourcecode type="cddl" markers="true" name="nipc_well_known.cddl"><![CDATA[
NipcWellKnown = {
  base_path: text,
  ? versions: [* uri / text],
  ? extensions: [* uri / text]
}
]]></sourcecode></figure>

</section>
<section anchor="nipc-registrations-paths"><name>NIPC Registrations</name>

<t>Registrations leverage the base path + /registrations. NIPC supports SDF model
registrations and data-app registrations.</t>

<t>paths:</t>

<t><list style="symbols">
  <t>/registrations/models</t>
  <t>/registrations/data-apps</t>
</list></t>

</section>
<section anchor="nipc-operations"><name>NIPC Operations</name>

<t>Every NIPC Operations API pertains to either a device or group of devices, identified by
an ID, hence the ID must be reflected as the first parameter in the path.
For example:</t>

<figure><artwork><![CDATA[
  "https://example.com/nipc/v1/{id}"
]]></artwork></figure>

<t>The second parameter in the path refers to the NIPC operation that the API will
perform on the device. This can be:</t>

<t><list style="symbols">
  <t>properties</t>
  <t>events</t>
  <t>actions</t>
  <t>triggers</t>
  <t>extensions</t>
</list></t>

<t>These are described in <xref target="nipc-ops"/>.</t>

</section>
</section>
<section anchor="schema"><name>Schema</name>

<t>The NIPC schema leans heavily on the SDF schema, as defined in
<xref target="RFC9880"/>. NIPC operations map directly to SDF affordances.</t>

<section anchor="sdf-model-registrations-1"><name>SDF model registrations</name>

<t>To execute NIPC operations, an SDF interaction model for the device class MUST be registered. The model MUST include protocol mappings that relate protocol‑neutral SDF affordances to protocol‑specific operations.</t>

<t>Registration is performed via POST /registrations/models with the SDF model in the request body. A registered model can be retrieved via GET /registrations/models using the model identifier (sdfName).</t>

</section>
<section anchor="nipc-operations-1"><name>NIPC Operations</name>

<t>NIPC operations require two parameters:</t>

<t><list style="numbers" type="1">
  <t>Device ID: the UUID identifying the target device (or group).</t>
  <t>sdfName: the SDF global name (absolute URI with fragment) of the affordance (property, action, or event) on which the operation acts.</t>
</list></t>

<section anchor="device-id"><name>Device ID</name>

<t>All NIPC operations are executed against a device or a group of devices.
Devices or groups of devices are identified by a unique UUID, adhering to <xref target="RFC9562"/>.</t>

<texttable title="Definition of a device or group of devices" anchor="devicedef">
      <ttcol align='left'>Attribute</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c>id</c>
      <c>uuid</c>
      <c>1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30</c>
</texttable>

<t>ID is a UUID assigned to uniquely identify a device to the NIPC Gateway (e.g., by a SCIM server) and the application calling the APIs. The NIPC Gateway must have access to a device object identified by this device ID and the application must store this UUID in order to use it to identify the device on which it wants to perform NIPC operations.</t>

</section>
<section anchor="sdf-name"><name>SDF Name</name>

<t>Operations act on SDF affordances and reference them by SDF global name—an absolute URI with fragment that includes the namespace. The affordance referenced MAY be a property, action, or event; the reference is carried as a string.</t>

<t>For example:</t>

<texttable title="Example SDF names for NIPC operations" anchor="nipcopsdef">
      <ttcol align='left'>NIPC Operation</ttcol>
      <ttcol align='left'>Example SDF Name used in the API</ttcol>
      <c>Property</c>
      <c>https://example.com/heartrate#/<br />sdfObject/thermostat/sdfProperty/temperature</c>
      <c>Event</c>
      <c>https://example.com/heartrate#<br />/sdfObject/healthsensor/sdfEvent/fallDetected</c>
      <c>Action</c>
      <c>https://example.com/heartrate#/<br />sdfObject/thermostat/sdfAction/resetThermostat</c>
</texttable>

</section>
</section>
<section anchor="parameters"><name>Parameters</name>

<t>To minimize deployment risk arising from inconsistent URI path normalization and handling of percent‑encoded reserved characters in path elements (notably “/” encoded as “%2F”) across common HTTP servers and intermediaries (e.g., Jetty, Tomcat, Apache httpd, NGINX), NIPC uses query parameters (except the primary {id} path segment) rather than additional path segments for values that can legitimately contain reserved characters (such as SDF global names). Although <xref target="RFC3986"/> and <xref target="RFC9110"/> require that reserved characters not be normalized or decoded in ways that alter semantics, misinterpretation of these rules has led to security vulnerabilities (path confusion, cache poisoning, authorization bypass) and to conservative default configurations that reject encoded slashes. In proxy deployments, relaxing these defaults often triggers security review friction. Representing such values in the query component avoids reliance on tolerant path normalization behavior, reduces ambiguity for intermediaries, and aligns with prevailing “safe” operational profiles; a malformed or unsupported parameter can be rejected with a 4xx status without exposing downstream services to traversal or normalization discrepancies.</t>

</section>
<section anchor="responses"><name>Responses</name>

<t>A NIPC Gateway must respond to a NIPC operation request synchronously, and provide the result of the completed operation in the HTTP response.</t>

<t>Exceptions to this are the following:</t>

<t><list style="numbers" type="1">
  <t>Extensions: Extension APIs (see <xref target="apiextensions"/>) execute compound operations and thus require the gateway to execute multiple
NIPC operations. On acceptance, the gateway returns 202 Accepted. Clients poll the extension URI (GET) for execution status. If a callback URI was supplied in the request, the gateway MAY send the final result upon completion.</t>
  <t>Actions: Action requests return 202 Accepted with a Location header pointing to the action instance used for status tracking, and a Retry-After header indicating the number of seconds the client should wait before polling for status.</t>
</list></t>

<t>A failure response must contain an HTTP status code of 4xx or 5xx, and use <xref target="RFC9457"/> Problem Details with <spanx style="verb">application/problem+json</spanx> media type.</t>

<t>All NIPC failure responses must include the following attributes:</t>

<t><list style="symbols">
  <t>type: a URI identifying the error (see <xref target="errorhandling"/>)</t>
  <t>status: the 4xx or 5xx HTTP status code</t>
  <t>title: a brief, human‑readable summary</t>
  <t>detail: a human‑readable explanation specific to this occurrence
Additional attributes MAY be included as permitted by <xref target="RFC9457"/>.</t>
</list></t>

<figure><sourcecode type="cddl" markers="true" name="failure_response.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

FailureResponse = {
  type: FailureTypeURI,
  status: uint,
  title: text,
  detail: text
}

; Enumerated problem type URIs registered for NIPC
FailureTypeURI = (
  "https://www.iana.org/assignments/nipc-problem-types#invalid-id" /
  "https://www.iana.org/assignments/nipc-problem-types#invalid-sdf-\
                                                               url" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-\
                                            operation-not-executed" /
  "https://www.iana.org/assignments/nipc-problem-types#sdf-model-\
                                                already-registered" /
  "https://www.iana.org/assignments/nipc-problem-types#sdf-model-in-\
                                                               use" /
  "https://www.iana.org/assignments/nipc-problem-types#unsupported-\
                                                        uri-scheme" /
  "https://www.iana.org/assignments/nipc-problem-types#property-not-\
                                                          readable" /
  "https://www.iana.org/assignments/nipc-problem-types#property-read\
                                                           -failed" /
  "https://www.iana.org/assignments/nipc-problem-types#property-not-\
                                                          writable" /
  "https://www.iana.org/assignments/nipc-problem-types#property-\
                                                      write-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#event-already\
                                                          -enabled" /
  "https://www.iana.org/assignments/nipc-problem-types#event-not-\
                                                           enabled" /
  "https://www.iana.org/assignments/nipc-problem-types#event-not-\
                                                        registered" /
  "https://www.iana.org/assignments/nipc-problem-types#trigger-\
                                                   already-enabled" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                             ble-already-connected" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                                 ble-no-connection" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                            ble-connection-timeout" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                                ble-bonding-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                             ble-connection-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                      ble-service-discovery-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                             ble-invalid-service-or-characteristic" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                         zigbee-connection-timeout" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                zigbee-invalid-endpoint-or-cluster" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-\
                                             transmit-invalid-data" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-\
                                                 firmware-rollback" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-\
                                            firmware-update-failed" /
  "about:blank"
)
]]></sourcecode></figure>

<t>Example of a failure response:</t>

<figure title="Example failure response" anchor="failure"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

{
  "type": "https://www.iana.org/assignments/nipc-problem-types#\
                                                         invalid-id",
  "status": 400,
  "title": "Invalid Device ID",
  "detail": "Device ID 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30 does \
                                        not exist or is not a device"
}
]]></sourcecode></figure>

</section>
</section>
</section>
<section anchor="nipc-registration-apis"><name>NIPC Registration APIs</name>

<section anchor="sdf-model-registrations-apis"><name>SDF model registrations APIs</name>

<t>SDF model registration APIs allow applications to register an SDF model for a class of devices.
These APIs use the <spanx style="verb">application/sdf+json</spanx> media type, as described in <xref section="7.1" sectionFormat="of" target="RFC9880"/>.</t>

<section anchor="register-an-sdf-model"><name>Register an SDF model</name>

<t>Method: <spanx style="verb">POST /registrations/models</spanx></t>

<t>Description: Registers one or more SDF models for a class of devices. If the SDF model is already registered, the gateway will return an error with the <spanx style="verb">sdf-model-already-registered</spanx> problem type.</t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>The SDF document in JSON format containing one or more sdfThings or sdfObjects, similar to the example in <xref target="thermometer-sdf"/>.</t>
  <t>The SDF document MUST contain protocol mappings, as described in <xref target="I-D.ietf-asdf-sdf-protocol-mapping"/>.</t>
</list></t>

<t>Response:</t>

<t>A list containing objects where each object has an "sdfName" which is the global name of the top-level sdfThing or sdfObject in the SDF model. The response uses the <spanx style="verb">201 Created</spanx> status code.</t>

<figure><sourcecode type="cddl" markers="true" name="sdf_reference.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

SdfGlobalName = text    ; absolute URI with fragment referencing an \
                                                sdfThing or sdfObject

SdfReference = {
  sdfName: SdfGlobalName
}

SdfReferenceArray = [* SdfReference]
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example of a response to an SDF model registration" anchor="exregresp"><sourcecode type="json" markers="true"><![CDATA[
[
 {
  "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
 }
]
]]></sourcecode></figure>

</section>
<section anchor="get-all-sdf-models"><name>Get all SDF models</name>

<t>Method: <spanx style="verb">GET /registrations/models</spanx></t>

<t>Description: Gets all SDF models registered with the gateway.</t>

<t>Response:</t>

<t>A list containing objects where each object has an "sdfName" which is the global name of the top-level sdfThing or sdfObject in the SDF model.</t>

<figure><sourcecode type="cddl" markers="true" name="sdf_reference.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

SdfGlobalName = text    ; absolute URI with fragment referencing an \
                                                sdfThing or sdfObject

SdfReference = {
  sdfName: SdfGlobalName
}

SdfReferenceArray = [* SdfReference]
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example of a response to get all SDF models" anchor="exgetallresp"><sourcecode type="json" markers="true"><![CDATA[
[
 {
  "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
 },
 {
  "sdfName": "https://example.com/thermometer#/sdfObject/thermometer"
 }
]
]]></sourcecode></figure>

</section>
<section anchor="get-an-sdf-model"><name>Get an SDF model</name>

<t>Method: <spanx style="verb">GET /registrations/models{?sdfName}</spanx></t>

<t>Description: Gets an SDF model registered with the gateway.</t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>sdfName: the name of the top-level sdfThing or sdfObject in the SDF model.</t>
</list></t>

<t>Response:</t>

<t><list style="symbols">
  <t>The SDF model is returned in JSON format, similar to the example in <xref target="thermometer-sdf"/>.</t>
</list></t>

</section>
<section anchor="delete-an-sdf-model"><name>Delete an SDF model</name>

<t>Method: <spanx style="verb">DELETE /registrations/models{?sdfName}</spanx></t>

<t>Description: Deletes an SDF model registered with the gateway.</t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>sdfName: the name of the top-level sdfThing or sdfObject in the SDF model.</t>
</list></t>

<t>Response:</t>

<t><list style="symbols">
  <t>An object with an "sdfName" which is the global name of the top-level sdfThing or sdfObject in the SDF model</t>
</list></t>

<figure><sourcecode type="cddl" markers="true" name="sdf_reference.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

SdfGlobalName = text    ; absolute URI with fragment referencing an \
                                                sdfThing or sdfObject

SdfReference = {
  sdfName: SdfGlobalName
}

SdfReferenceArray = [* SdfReference]
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example of a response to an SDF model registration" anchor="exregdelresp"><sourcecode type="json" markers="true"><![CDATA[
{
  "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
}
]]></sourcecode></figure>

</section>
<section anchor="update-an-sdf-model"><name>Update an SDF model</name>

<t>Method: <spanx style="verb">PUT /registrations/models{?sdfName}</spanx></t>

<t>Description: Updates an SDF model registered with the gateway.</t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>sdfName: the name of the top-level sdfThing or sdfObject in the SDF model.</t>
</list></t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>An SDF model in JSON format, similar to the example in <xref target="thermometer-sdf"/>.</t>
</list></t>

<t>Response:</t>

<t><list style="symbols">
  <t>An object with an "sdfName" which is the global name of the top-level sdfThing or sdfObject in the SDF model</t>
</list></t>

<figure><sourcecode type="cddl" markers="true" name="sdf_reference.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

SdfGlobalName = text    ; absolute URI with fragment referencing an \
                                                sdfThing or sdfObject

SdfReference = {
  sdfName: SdfGlobalName
}

SdfReferenceArray = [* SdfReference]
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example of a response to an SDF model registration" anchor="exregupresp"><sourcecode type="json" markers="true"><![CDATA[
{
  "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
}
]]></sourcecode></figure>

</section>
</section>
<section anchor="data-application-registrations-apis"><name>Data application registrations APIs</name>

<t>Data-app registration APIs allow applications to register a data application that will receive streaming data from the gateway. These APIs operate on a data app ID. This ID corresponds to the endpoint app ID of the telemetry endpoint app that is registered with the SCIM server as an authorized endpoint that can receive data for a device. The endpoint app is defined in <xref section="6" sectionFormat="of" target="RFC9944"/>.</t>

<t>Apart from the endpoint app ID, the API also configures the protocol the data-app supports. These should be one of the following:</t>

<t><list style="symbols">
  <t>mqttClient: The data-app is an MQTT client, which means that the NIPC gateway must act as an MQTT broker.</t>
  <t>mqttBroker: The data-app is an MQTT broker, which means that the NIPC gateway must act as an MQTT client. The MQTT broker configuration data, such as the URI, credentials and MQTT topic must also be provided in the registration API.</t>
  <t>webhook: The data-app supports a webhook the gateway can publish to. The registration API has to include the webhook URI &amp; credentials.</t>
  <t>websocket: The data-app supports a websocket interface. The registration API has to include the websocket URI &amp; credentials.</t>
</list></t>

<section anchor="register-data-app"><name>Register a data application</name>

<t>Method: <spanx style="verb">POST /registrations/data-apps{?dataAppId}</spanx></t>

<t>Description: Registers a data application with the gateway.</t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>dataAppId: the ID of the data application</t>
</list></t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>events: a list of events that the data application is authorized for.</t>
  <t>mqttClient: a boolean that denotes that the data application is an MQTT client.</t>
  <t>mqttBroker: The data app is an MQTT broker. This object contains the MQTT broker information:
  <list style="symbols">
      <t>URI: the URI of the MQTT broker.</t>
      <t>username: the username to authenticate with the MQTT broker.</t>
      <t>password: the password to authenticate with the MQTT broker.</t>
      <t>brokerCACert: the base64-encoded CA certificate of the MQTT broker (optional).</t>
      <t>customTopic: By default, the topic will be composed of <spanx style="verb">data-app/&lt;dataAppId&gt;/&lt;namespace&gt;/&lt;json_pointer_to_sdf_event&gt;</spanx>, as described in <xref target="nipc-event-apis"/>. In this attribute, a custom topic can be configured (optional).</t>
    </list></t>
  <t>webhook: The data app supports a webhook. This object contains a webhook URL along with any credentials that are required to authenticate the webhook.
  <list style="symbols">
      <t>URI: the webhook URI. The URI MUST include the scheme used by the webhook server (e.g., "https://"). It is up to the implementation to support different schemes. If a scheme is not supported, the NIPC gateway MUST return an error response with type "https://www.iana.org/assignments/nipc-problem-types#unsupported-uri-scheme".</t>
      <t>headers: An object that contains the headers to be sent with the webhook request. The headers can contain any authentication information required by the webhook server. Each header is represented as a key-value pair in the object.</t>
      <t>serverCACert: the CA certificate of the webhook server, encoded as per <xref target="RFC7468"/> and newlines encoded as '\n' (optional)</t>
    </list></t>
  <t>websocket: The data app supports a websocket. This object contains a websocket URL along with any credentials that are required to authenticate the websocket.
The websocket URL is the endpoint where the streaming data will be sent.
  <list style="symbols">
      <t>URI: the websocket URI. The URI MUST include the scheme used by the websocket server (e.g., "wss://"). It is up to the implementation to support different schemes. If a scheme is not supported, the NIPC gateway MUST return an error response with type "https://www.iana.org/assignments/nipc-problem-types#unsupported-uri-scheme".</t>
      <t>headers: An object that contains the headers to be sent with the websocket request. The headers can contain any authentication information required by the websocket server. Each header is represented as a key-value pair in the object.</t>
      <t>serverCACert: the CA certificate of the websocket server, encoded as per <xref target="RFC7468"/> and newlines encoded as '\n' (optional)</t>
    </list></t>
</list></t>

<figure><sourcecode type="cddl" markers="true" name="data_app.cddl"><![CDATA[
DataApp = {
  events: [* EventRef],
  ( DataAppMqttClient //
    DataAppMqttBroker //
    DataAppWebhook //
    DataAppWebsocket )
}

EventRef = {
  event: text    ; SDF global name (absolute URI with fragment)
}

DataAppMqttClient = {
  mqttClient: bool
}

DataAppMqttBroker = {
  mqttBroker: {
    URI: text,
    username: text,
    password: text,
    ? brokerCACert: text,   ; PEM-encoded CA certificate
    ? customTopic: text     ; optional custom MQTT topic
  }
}

DataAppWebhook = {
  webhook: {
    URI: text,
    ? headers: { * text => text },  ; key/value headers
    ? serverCACert: text
  }
}

DataAppWebsocket = {
  websocket: {
    URI: text,
    ? headers: { * text => text },  ; key/value headers
    ? serverCACert: text
  }
}
]]></sourcecode></figure>

<t>Example of a request body:</t>

<figure title="Example with mqttClient" anchor="exregmqttclientrsp"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

{
  "events": [
    {
      "event": "https://example.com/heartrate#/sdfObject/\
                                  healthsensor/sdfEvent/fallDetected"
    }
  ],
  "mqttClient": true
}
]]></sourcecode></figure>

<t>Example of a request body for a data application that is an MQTT broker:</t>

<figure title="Example with mqttBroker" anchor="exregmqttbrokerrsp"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

{
  "events": [
    {
      "event": "https://example.com/heartrate#/sdfObject/\
                                  healthsensor/sdfEvent/fallDetected"
    }
  ],
  "mqttBroker": {
    "URI": "mqtt.example.com:1883",
    "username": "user",
    "password": "password",
    "customTopic": "custom/topic"
  }
}
]]></sourcecode></figure>

<t>Response:</t>

<t><list style="symbols">
  <t>If successful, the response will be identical to the request body.</t>
</list></t>

</section>
<section anchor="update-a-data-application"><name>Update a data application</name>

<t>Method: <spanx style="verb">PUT /registrations/data-apps{?dataAppId}</spanx></t>

<t>Description: Updates a data application registration.</t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>dataAppId: the ID of the data application</t>
</list></t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>The request body is identical to the request body for the register data application API <xref target="register-data-app"/>.</t>
</list></t>

<t>Response:</t>

<t><list style="symbols">
  <t>If successful, the response will be identical to the request body.</t>
</list></t>

</section>
<section anchor="get-a-data-application"><name>Get a data application</name>

<t>Method: <spanx style="verb">GET /registrations/data-apps{?dataAppId}</spanx></t>

<t>Description: Gets a data application object registered with the gateway.</t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>dataAppId: the ID of the data application</t>
</list></t>

<t>Response:</t>

<t>The response will be identical to the request body for the register data application API <xref target="register-data-app"/>.</t>

</section>
<section anchor="delete-a-data-application"><name>Delete a data application</name>

<t>Method: <spanx style="verb">DELETE /registrations/data-apps{?dataAppId}</spanx></t>

<t>Description: Deletes a data application registered with the gateway.</t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>dataAppId: the ID of the data application</t>
</list></t>

<t>Response:</t>

<t><list style="symbols">
  <t>If successful, the response will be <spanx style="verb">204 No Content</spanx>.</t>
</list></t>

</section>
</section>
</section>
<section anchor="nipc-operation-apis"><name>NIPC Operation APIs</name>

<t>The NIPC operation APIs perform protocol‑neutral interactions on SDF affordances, properties, events, and actions. This allows applications to read and update device properties, invoke actions, and consume events.</t>

<t>NIPC defines three API collections aligned with the SDF Affordances defined in <xref section="1.2" sectionFormat="of" target="RFC9880"/>:</t>

<t><list style="symbols">
  <t>Properties: read and write device properties.</t>
  <t>Events: enable and disable device event reporting.</t>
  <t>Actions: invoke device actions.</t>
</list></t>

<t>Additionally, NIPC defines one more API collection that allows applications to install triggers on events. Triggers will trigger an action if the event is executed. Trigger collection:</t>

<t><list style="symbols">
  <t>Triggers: Install a trigger on an event (invokes an action)</t>
</list></t>

<t>To invoke NIPC operations APIs on a device, one or more SDF models MUST be registered for that device. The SDF model MAY have a top‑level sdfThing (with multiple sdfObjects) or a top‑level sdfObject. Operations depend on affordances (sdfProperty, sdfEvent, sdfAction) defined in the registered SDF model and on a device ID (see <xref target="RFC9944"/>). Affordances are referenced by their SDF global name (absolute URI with fragment) as described in <xref section="4" sectionFormat="of" target="RFC9880"/>.</t>

<t>The NIPC Gateway must match the SDF global name against the registered SDF model to resolve the protocol mapping (protocolmap) the gateway will execute. When carried in a URI, the SDF global name MUST be percent‑encoded per <xref section="2.1" sectionFormat="of" target="RFC3986"/>.</t>

<section anchor="nipc-property-apis"><name>NIPC Property APIs</name>

<t>These APIs allow applications to read and update device properties. If the underlying protocol requires a connection, the gateway establishes it implicitly for the operation; when an explicit connection is already active, operations reuse it without modification.</t>

<t>Requests and responses support content negotiation via Content-Type and Accept.
When using "application/nipc+json", payloads must follow the examples above. Binary property values must be base64‑encoded with padding per <xref section="4" sectionFormat="of" target="RFC4648"/> in the "value" field. For other media types, payload semantics must follow the selected media type.</t>

<section anchor="update-one-or-multiple-values"><name>Update one or multiple values</name>

<t>Method: <spanx style="verb">PUT /devices/{id}/properties{?propertyName}</spanx></t>

<t>Description: Write values to one or more properties on a device</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>propertyName: Identifies a single property to update. If present, the request body MAY use any media type appropriate to the property payload.</t>
</list></t>

<t>-or-</t>

<t><list style="symbols">
  <t>If absent, the request body MUST be application/nipc+json and contain an array of update items, each with a property and a value.</t>
</list></t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>If the query parameter propertyName is provided, the request body MAY use any media type appropriate to the property payload. The value is encoded as per the content type of the payload.</t>
</list></t>

<t>-or-</t>

<t><list style="symbols">
  <t>If the query parameter propertyName is NOT provided, the request body must be an array of properties to update, each containing a property and a value. The value attribute contains the raw binary data, which must be encoded in base64 with padding as per <xref section="4" sectionFormat="of" target="RFC4648"/>.</t>
</list></t>

<figure><sourcecode type="cddl" markers="true" name="property_value_array.cddl"><![CDATA[
PropertyValueArray = [* PropertyValue]

; Minimal PropertyValue shape (matches allOf of Property + Value)
PropertyValue = {
  property: text,        ; SDF global name of the property
  value: b64text         ; base64-encoded bytes (RFC 4648 Section 4)
}

; Helper type for base64-with-padding encoded text
b64text = text
]]></sourcecode></figure>

<t>Example body for updating multiple properties:</t>

<figure title="Example updating multiple properties" anchor="exupmprop"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

[
  {
    "property": "https://example.com/heartrate#/sdfObject/thermostat\
                                           /sdfProperty/temperature",
    "value": "dGVzdA=="
  },
  {
    "property": "https://example.com/heartrate#/sdfObject/thermostat\
                                              /sdfProperty/humidity",
    "value": "eGVzdB=="
  }
]
]]></sourcecode></figure>

<t>Response:</t>

<t><list style="symbols">
  <t>If the Accept header is set to <spanx style="verb">application/nipc+json</spanx>, the response must be an array with a status field set to 200 for each property that was updated, or a problem type object for each property that failed to update. The "properties" array must be an array of properties that were updated, each containing a property and a value.</t>
</list></t>

<t>-or-</t>

<t><list style="symbols">
  <t>If the Accept header is set to any other media type and the propertyName query parameter is provided, the response must be 204 No Content with no body.</t>
</list></t>

<figure><sourcecode type="cddl" markers="true" name="property_value_response_array.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

PropertyValueResponseArray = [* PropertyValueResponseArrayItem]

PropertyValueResponseArrayItem = ( SuccessResponse // \
                                                    FailureResponse )

; Minimal success shape (may be extended)
SuccessResponse = {
  status: uint
}
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example update multiple properties response" anchor="exupmresp"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

[
  {
    "status": 200
  },
  {
    "type": "https://www.iana.org/assignments/nipc-problem-types#\
                                              property-not-writable",
    "status": 400,
    "title": "Property Not Writable",
    "detail": "Property https://example.com/heartrate#/sdfObject/\
thermostat/sdfProperty/temperature does not exist or is not writable"
  }
]
]]></sourcecode></figure>

</section>
<section anchor="read-one-or-multiple-values"><name>Read one or multiple values</name>

<t>Method: <spanx style="verb">GET /devices/{id}/properties{?propertyName*}</spanx></t>

<t>Description: Read values from one or more properties on a device</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>propertyName: The property to read. This can be a single property or multiple properties. If multiple properties are provided, the request body MUST contain an application/nipc+json payload with an array of properties to read.</t>
</list></t>

<t>Response:</t>

<t><list style="symbols">
  <t>If the Accept header is set to <spanx style="verb">application/nipc+json</spanx>, the response must be an array of properties, each containing a property and a value. The value must be the raw binary data read from the property, encoded in base64 with padding as per <xref section="4" sectionFormat="of" target="RFC4648"/>. The array must contain objects with 2 attributes:
    - property: The property that was read.
    - value: The bytes that were read in base64 encoding</t>
</list></t>

<t>-or-</t>

<t><list style="symbols">
  <t>If the Accept header is set to any other media type and a single propertyName query parameter is provided, the request body MAY use any media type appropriate to the property payload. The value is encoded as per the content type of the payload.</t>
</list></t>

<figure><sourcecode type="cddl" markers="true" name="property_value_read_response_array.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

PropertyValueReadResponseArray = [* \
                                  PropertyValueReadResponseArrayItem]

PropertyValueReadResponseArrayItem = ( PropertyValue // \
                                                    FailureResponse )
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example read multiple properties response" anchor="exreadmresp"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

[
  {
    "property": "https://example.com/heartrate#/sdfObject/thermostat\
                                           /sdfProperty/temperature",
    "value": "dGVzdA=="
  },
  {
    "property": "https://example.com/heartrate#/sdfObject/thermostat\
                                              /sdfProperty/humidity",
    "value": "eGVzdB=="
  }
]
]]></sourcecode></figure>

</section>
</section>
<section anchor="nipc-event-apis"><name>NIPC Event APIs</name>

<t>Event APIs enable or disable reporting of device events. For certain protocols, a connection may be required. If the underlying protocol requires a connection, the gateway establishes it implicitly for the operation. If an explicitly created connection is already active, it is reused without modification.</t>

<t>Events are referenced by the SDF global name of an sdfEvent. The {id} path segment identifies a device or a group of devices. A group event MAY be enabled only if the underlying protocol supports group activation (e.g., BLE advertisement or connection status events).</t>

<t>Events are delivered to registered data-apps over a publish/subscribe interface, as defined in <xref target="pubsub"/>.
If the data application registered for this event is an MQTT broker or client, the event SDF global name may be used to construct the MQTT topic for the event. The topic is constructed using the data application ID, the default namespace for the event, and the event itself.
For example, if the data application ID is "0927ce7c-b258-4bfa-a345-bcc9f74385b4"
and the event is "https://example.com/thermometer#/sdfThing/thermometer/sdfEvent/isPresent", the topic will be:</t>

<figure><artwork><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

data-app/<dataAppId>/<namespace>/<json_pointer_to_sdf_event>

data-app/0927ce7c-b258-4bfa-a345-bcc9f74385b4/thermometer/sdfThing/\
                                       thermometer/sdfEvent/isPresent
]]></artwork></figure>

<t>A data application may subscribe to this topic using the topic or it may use MQTT wildcards to subscribe to <spanx style="verb">data-app/+/temperature/#</spanx> to receive all events for the <spanx style="verb">temperature</spanx> namespace.</t>

<t>If a customTopic was supplied in the data‑app registration (mqttBroker case), that topic MUST be used instead of the constructed default.</t>

<section anchor="enable-event-reporting"><name>Enable event reporting</name>

<t>Method: <spanx style="verb">POST /devices/{id}/events{?eventName}</spanx></t>

<t>Description: Enables an event on a device</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>eventName: the event to enable. The eventName must be a URL encoded string that is the absolute URI that is the global name of an <spanx style="verb">sdfEvent</spanx>.</t>
</list></t>

<t>Response:</t>

<t><list style="symbols">
  <t>Returns HTTP status code 201 Created with a Location header pointing to the created event instance.</t>
</list></t>

<t>Example of a successful response:</t>

<figure><artwork><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

HTTP/1.1 201 Created
Location: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/events?\
                      instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
]]></artwork></figure>

<t>The Location header must contain the URI for the created event instance, which may be used to check status or disable the event.</t>

</section>
<section anchor="disable-event-reporting"><name>Disable event reporting</name>

<t>Method: <spanx style="verb">DELETE /devices/{id}/events{?instanceId}</spanx></t>

<t>Description: Disables an event on a device</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device or group of devices</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>instanceId: the instance ID of the event to disable (obtained from the Location header when the event was enabled)</t>
</list></t>

<t>Response:</t>

<t><list style="symbols">
  <t>Returns HTTP status code 204 No Content on successful disable.</t>
</list></t>

<figure><artwork><![CDATA[
HTTP/1.1 204 No Content
]]></artwork></figure>

</section>
<section anchor="get-status-of-one-or-more-events"><name>Get status of one or more events</name>

<t>Method: <spanx style="verb">GET /devices/{id}/events{?instanceId*}</spanx></t>

<t>Description: Get the status of one or more events on a specific device</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device or group of devices</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>instanceId: a comma separated list of event instance IDs to filter by (optional)</t>
</list></t>

<t>Response:
The response must be an array of events, each containing an instanceID and an event.
 - instanceId: must be the unique instance ID for each enabled event.
 - event: must be the event URI for each enabled event.</t>

<figure><sourcecode type="cddl" markers="true" name="event_status_array.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

EventStatusResponseArray = [* EventStatusResponseArrayItem]

EventStatusResponseArrayItem = ( EventInstanceSuccess // \
                                                    FailureResponse )

; Success item = { event, instanceId }
EventInstanceSuccess = {
  event: text,        ; SDF global name of the event (absolute URI \
                                                       with fragment)
  instanceId: text    ; UUID (as text)
}
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example get multiple events status response" anchor="exgetmresp"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

[
  {
    "instanceId": "02ee282c-8915-4b2e-bbd2-88966773134a",
    "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
                                               sdfEvent/fallDetected"
  }
]
]]></sourcecode></figure>

</section>
<section anchor="enable-event-reporting-on-a-group-of-devices"><name>Enable event reporting on a group of devices</name>

<t>Method: <spanx style="verb">POST /groups/{id}/events</spanx></t>

<t>Description: Enables an event on a group of devices</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the group of devices</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>eventName: the event to enable. The eventName is a URL encoded string that is the absolute URI that is the global
name of an <spanx style="verb">sdfEvent</spanx>.</t>
</list></t>

<t>Response:</t>

<t><list style="symbols">
  <t>The response must return HTTP status code 201 Created with a Location header pointing to the created event instance. The Location header must contain the URI for the created event instance, which can be used to check status or disable the event.</t>
</list></t>

<t>Example of a successful response:</t>

<figure><artwork><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

HTTP/1.1 201 Created
Location: /groups/0dc729d7-f6c3-491d-9b9d-e7176d2be243/events?\
                      instanceId=f1b9f26b-21ce-4deb-9d57-289ba7e17cce
]]></artwork></figure>

</section>
<section anchor="disable-event-reporting-on-a-group-of-devices"><name>Disable event reporting on a group of devices</name>

<t>Method: <spanx style="verb">DELETE /groups/{id}/events{?instanceId}</spanx></t>

<t>Description: Disables an event on a group of devices</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the group of devices</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>instanceId: the instance ID of the event to disable (obtained from the Location header when the event was enabled)</t>
</list></t>

<t>Response:</t>

<t>MUST return 200 OK with an array of per‑device event status entries. For each device where the event was successfully disabled, the entry MUST include deviceId and event (SDF global name). For each device where disabling failed, the entry MUST be a Problem Details error object for that device.</t>

<figure><sourcecode type="cddl" markers="true" name="group_event_status_response_array.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

GroupEventStatusResponseArray = [* GroupEventStatusResponse]

GroupEventSuccessResponse = { event: text, deviceId: text }

; Each item is either an event+deviceId success or a \
                                                 GroupFailureResponse
GroupEventStatusResponse = (GroupEventSuccessResponse // \
                                                GroupFailureResponse)

GroupFailureResponse = {
  FailureResponse,
  ? deviceId: text
}
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure><sourcecode type="json"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

[
  {
    "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
                                              sdfEvent/fallDetected",
    "deviceId": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
  },
  {
    "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
                                              sdfEvent/fallDetected",
    "deviceId": "d62c7fb2-a216-4811-a388-053b17fdbedc"
  },
  {
    "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
                                              sdfEvent/fallDetected",
    "deviceId": "01b52a23-b98c-454c-ba9e-086a43bdfd79"
  },
  {
    "type": "https://www.iana.org/assignments/nipc-problem-types#\
                                                  event-not-enabled",
    "status": 400,
    "title": "Event Not Enabled",
    "deviceId": "9171ec16-e3c1-4ccf-ad23-b92a1a3f069d",
    "detail": "Failed to disable the event for device 9171ec16-e3c1-\
                                              4ccf-ad23-b92a1a3f069d"
  }
]
]]></sourcecode></figure>

</section>
<section anchor="get-event-status-on-a-group-of-devices"><name>Get event status on a group of devices</name>

<t>Method: <spanx style="verb">GET /groups/{id}/events{?instanceId}</spanx></t>

<t>Description: Get the status of one or more events for a group of devices</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the group of devices</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>instanceId: the instance ID of the event (obtained from the Location header when the event was enabled).</t>
</list></t>

<t>Response:</t>

<t>MUST return 200 OK with an array of per‑device event status entries. For each device where the event was successfully enabled, the entry MUST include deviceId and event (SDF global name). For each device where enabling failed, the entry MUST be a Problem Details error object for that device.</t>

<figure><sourcecode type="cddl" markers="true" name="group_event_status_response_array.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

GroupEventStatusResponseArray = [* GroupEventStatusResponse]

GroupEventSuccessResponse = { event: text, deviceId: text }

; Each item is either an event+deviceId success or a \
                                                 GroupFailureResponse
GroupEventStatusResponse = (GroupEventSuccessResponse // \
                                                GroupFailureResponse)

GroupFailureResponse = {
  FailureResponse,
  ? deviceId: text
}
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example get multiple group events status response" anchor="exgetmgevntsresp"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

[
  {
    "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
                                              sdfEvent/fallDetected",
    "deviceId": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
  },
  {
    "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
                                              sdfEvent/fallDetected",
    "deviceId": "d62c7fb2-a216-4811-a388-053b17fdbedc"
  },
  {
    "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
                                              sdfEvent/fallDetected",
    "deviceId": "01b52a23-b98c-454c-ba9e-086a43bdfd79"
  },
  {
    "type": "https://www.iana.org/assignments/nipc-problem-types#\
                                                  event-not-enabled",
    "status": 400,
    "title": "Event Not Enabled",
    "deviceId": "9171ec16-e3c1-4ccf-ad23-b92a1a3f069d",
    "detail": "Failed to enable the event for device 9171ec16-e3c1-\
                                              4ccf-ad23-b92a1a3f069d"
  }
]
]]></sourcecode></figure>

</section>
</section>
<section anchor="nipc-action-apis"><name>NIPC Action APIs</name>

<t>NIPC Action APIs invoke device actions. If the underlying protocol requires a connection, the gateway establishes it implicitly for the operation. If an explicitly established connection is already active, the operation MUST reuse it without modification.</t>

<section anchor="perform-an-action"><name>Perform an action</name>

<t>Method: <spanx style="verb">POST /devices/{id}/actions{?actionName}</spanx></t>

<t>Description: Perform an action on a specific device</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>actionName: the action to perform</t>
</list></t>

<t>Request Body:</t>

<t>The request body is optional and may contain a value. The media type of the value can be defined by the underlying protocol, for example it could be octet-stream for binary data.</t>

<t>Response:</t>

<t>Actions are performed asynchronously. A successful request returns HTTP status code 202 Accepted with a Location header pointing to the action instance for status checking, and a Retry-After header indicating the number of seconds the client should wait before polling. The Location header contains the URI for the action instance, which can be used to check the action status.</t>

<t>Example of a successful response:</t>

<figure><artwork><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

HTTP/1.1 202 Accepted
Location: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/actions?\
                      instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
Retry-After: 5
]]></artwork></figure>

</section>
<section anchor="check-action-status"><name>Check action status</name>

<t>Method: <spanx style="verb">GET /devices/{id}/actions{?instanceId}</spanx></t>

<t>Description: Check the status of an action on a specific device</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>instanceId: the instance ID of the action (obtained from the Location header)</t>
</list></t>

<t>Response:
MUST return 200 OK with an action status, which may be "IN_PROGRESS" or "COMPLETED".</t>

<figure><sourcecode type="cddl" markers="true" name="action_response.cddl"><![CDATA[
ActionResponse = {
  status: ActionStatus
}

ActionStatus = "IN_PROGRESS" / "COMPLETED"
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example action status response" anchor="exactionstatusresp"><sourcecode type="json" markers="true"><![CDATA[
{
  "status": "COMPLETED"
}
]]></sourcecode></figure>

</section>
<section anchor="perform-an-action-on-a-group-of-devices"><name>Perform an action on a group of devices</name>

<t>Method: <spanx style="verb">POST /groups/{id}/actions{?actionName}</spanx></t>

<t>Description: Perform an action on a group of devices</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the group</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>actionName: the action to perform</t>
</list></t>

<t>Request Body:</t>

<t>The request body is optional and may contain a value. The media type of the value can be defined by the underlying protocol, for example it could be octet-stream for binary data.</t>

<t>Response:</t>

<t>Actions are performed asynchronously. A successful request returns HTTP status code 202 Accepted with a Location header pointing to the action instance for status checking, and a Retry-After header indicating the number of seconds the client should wait before polling.</t>

<t>Example of a successful response:</t>

<figure><artwork><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

HTTP/1.1 202 Accepted
Location: /groups/0dc729d7-f6c3-491d-9b9d-e7176d2be243/actions?\
                      instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
Retry-After: 5
]]></artwork></figure>

</section>
<section anchor="check-group-action-status"><name>Check group action status</name>

<t>Method: <spanx style="verb">GET /groups/{id}/actions{?instanceId}</spanx></t>

<t>Description: Check the status of an action on a group of devices. Returns a per-device status array.</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the group</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>instanceId: the instance ID of the action (obtained from the Location header)</t>
</list></t>

<t>Response:</t>

<t>MUST return 200 OK with an array of per-device action statuses. Each entry contains the action status and a deviceId. Entries for failed devices contain a problem detail with the deviceId.</t>

<figure><sourcecode type="cddl" markers="true" name="group_action_status_response_array.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

; Group Action status response array and item shape

GroupActionStatusResponseArray = [* GroupActionStatusResponse]

GroupActionStatusResponse = (GroupActionSuccessResponse // \
                                          GroupActionFailureResponse)

GroupActionSuccessResponse = {
  status: ActionStatus,
  deviceId: text     ; UUID (as text)
}

ActionStatus = "IN_PROGRESS" / "COMPLETED"

GroupActionFailureResponse = {
  FailureResponse,
  ? deviceId: text
}
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example group action status response" anchor="exgroupactionstatusresp"><sourcecode type="json" markers="true"><![CDATA[[
  {
    "status": "COMPLETED",
    "deviceId": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
  },
  {
    "status": "IN_PROGRESS",
    "deviceId": "d62c7fb2-a216-4811-a388-053b17fdbedc"
  }
]
]]></sourcecode></figure>

</section>
</section>
<section anchor="nipc-trigger-apis"><name>NIPC Trigger APIs</name>

<t>Triggers APIs do not actually execute an operation on a device or group of devices, but install a trigger that registers an operation. When triggered the registered operation gets executed.</t>

<t>Triggers can be installed for devices or groups of devices, represented by their id as a path parameter.</t>

<t>The trigger must always be triggered by an event. the global name of the event must be passed as a path parameter.</t>

<t>The triggered operation must always be an action. Since an action can be executed against both a device and a group, the trigger API also supports actions on both devices and groups of devices. The action is defined by its full NIPC URI to be executed, for example:</t>

<figure><artwork><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

/devices/3171ec43-42a5-4415-ab4b-afd0dfbe9615/actions?actionName=\
       https://example.com/AlarmSystem#/sdfObject/bell/sdfAction/ring
]]></artwork></figure>

<t>If a NIPC Gateway supports multiple protocols, then a trigger can be defined on a devices that supports one protocol and triggers an action on a device that supports a different protocol. As an example, an event on a BLE device can trigger an action on a Zigbee device.</t>

<section anchor="create-a-trigger-on-a-device"><name>Create a trigger on a device</name>

<t>Method: <spanx style="verb">POST /devices/{id}/triggers{?eventName}</spanx></t>

<t>Description: Creates a trigger on an affordance of a device. A trigger will trigger an action on another device or a group of devices. If a trigger for the same <spanx style="verb">eventName</spanx> is already enabled on the device, the gateway MUST return an error with the <spanx style="verb">trigger-already-enabled</spanx> problem type.</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>eventName: the eventName of the event that is associated with the trigger. This must be a URL encoded string that is the absolute URI that is the global name of an <spanx style="verb">sdfEvent</spanx>.</t>
</list></t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>The request body must be of type 'application/nipc+json', and contain an action object. The action object contains a NIPC URI to be executed, including the device or group id and actionname percent-encoded query parameter.</t>
</list></t>

<figure><sourcecode type="cddl" markers="true" name="action.cddl"><![CDATA[
Action = {
  action: text  ; NIPC action operation to execute
}
]]></sourcecode></figure>

<t>Example body for trigger creation:</t>

<figure title="Example trigger creation" anchor="excreatetrigger"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

{
  "action": "/devices/3171ec43-42a5-4415-ab4b-afd0dfbe9615/actions?\
actionName=https%3A%2F%2Fexample.com%2FAlarmSystem%23%2FsdfObject%\
                                           2Fbell%2FsdfAction%2Fring"
}
]]></sourcecode></figure>

<t>Response:</t>

<t><list style="symbols">
  <t>Returns HTTP status code 201 Created with a Location header pointing to the created trigger instance.</t>
</list></t>

<t>Example of a successful response:</t>

<figure><artwork><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

HTTP/1.1 201 Created
Location: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/triggers?\
                      instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
]]></artwork></figure>

<t>The Location header must contain the URI for the created trigger instance, which may be used to check status or disable the trigger.</t>

</section>
<section anchor="delete-a-trigger-on-a-device"><name>Delete a trigger on a device</name>

<t>Method: <spanx style="verb">DELETE /devices/{id}/triggers{?instanceId}</spanx></t>

<t>Description: Deletes an installed trigger</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>instanceId: the instance ID of the trigger to disable (obtained from the Location header when the trigger was installed)</t>
</list></t>

<t>Response:</t>

<t><list style="symbols">
  <t>Returns HTTP status code 204 No Content on successful delete.</t>
</list></t>

<figure><artwork><![CDATA[
HTTP/1.1 204 No Content
]]></artwork></figure>

</section>
<section anchor="get-installed-triggers-for-a-device"><name>Get installed triggers for a device</name>

<t>Method: <spanx style="verb">GET /devices/{id}/triggers{?instanceId}</spanx></t>

<t>Description: Get the installed triggers for a devices, or a specific trigger when specifying an instanceId.</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>instanceId: an InstanceID, or comma separated list of event instance IDs to filter by (optional)</t>
  <t>If no query parameter is supplied, then all triggers for the device must be retrieved</t>
</list></t>

<t>Response:</t>

<t>The response must be an array of triggers, each containing an instanceId, the sdfName of an event and an action.</t>

<t><list style="symbols">
  <t>instanceId: must be the instance ID for each installed trigger, as returned by the NIPC GW when the trigger was created.</t>
  <t>eventName: must be the sdfName of the event that is associated with the trigger.</t>
  <t>action: must be the NIPC URI of the action to be executed when the trigger is activated.</t>
</list></t>

<figure><sourcecode type="cddl" markers="true" name="trigger_status_array.cddl"><![CDATA[
; Trigger status response array and item shape

TriggerStatusResponseArray = [* TriggerResponse]

TriggerResponse = {
  eventName: text,      ; SDF event name
  action: text,      ; NIPC action operation to execute
  instanceId: text     ; UUID (as text)
}
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example get multiple triggers response" anchor="exgetmtriggers"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

[
  {
    "instanceId": "02ee282c-8915-4b2e-bbd2-88966773134a",
    "eventName": "https://example.com/heartrate#/sdfObject/\
                                 healthsensor/sdfEvent/fallDetected",
    "action": "/devices/3171ec43-42a5-4415-ab4b-afd0dfbe9615/actions\
?actionName=https%3A%2F%2Fexample.com%2FAlarmSystem%23%2FsdfObject%\
                                           2Fbell%2FsdfAction%2Fring"
  }
]
]]></sourcecode></figure>

</section>
<section anchor="create-a-trigger-on-a-group-of-devices"><name>Create a trigger on a group of devices</name>

<t>Method: <spanx style="verb">POST /groups/{id}/triggers{?eventName}</spanx></t>

<t>Description: Creates a trigger on an affordance of a group of devices. A trigger will trigger an action on another device or a group of devices. If a trigger for the same <spanx style="verb">eventName</spanx> is already enabled on the group, the gateway MUST return an error with the <spanx style="verb">trigger-already-enabled</spanx> problem type.</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the group of devices</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>eventName: the eventName of the affordance that is associated with the trigger. This must be an event. The eventName must be a URL encoded string that is the absolute URI that is the global name of an <spanx style="verb">sdfEvent</spanx>.</t>
</list></t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>The request body must be of type 'application/nipc+json', and contain an action object. The action object contains a NIPC URI to be executed, including the device or group id and actionname percent-encoded query parameter.</t>
</list></t>

<figure><sourcecode type="cddl" markers="true" name="action.cddl"><![CDATA[
Action = {
  action: text  ; NIPC action operation to execute
}
]]></sourcecode></figure>

<t>Example body for trigger creation:</t>

<figure title="Example trigger creation" anchor="excreategrouptrigger"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

{
  "action": "/groups/3171ec43-42a5-4415-ab4b-afd0dfbe9615/actions?\
actionName=https%3A%2F%2Fexample.com%2FAlarmSystem%23%2FsdfObject%\
                                           2Fbell%2FsdfAction%2Fring"
}
]]></sourcecode></figure>

<t>Response:</t>

<t><list style="symbols">
  <t>Returns HTTP status code 201 Created with a Location header pointing to the created trigger instance.</t>
</list></t>

<t>Example of a successful response:</t>

<figure><artwork><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

HTTP/1.1 201 Created
Location: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/triggers?\
                      instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
]]></artwork></figure>

<t>The Location header must contain the URI for the created trigger instance, which may be used to check status or disable the trigger.</t>

</section>
<section anchor="delete-a-trigger-on-a-group-of-devices"><name>Delete a trigger on a group of devices</name>

<t>Method: <spanx style="verb">DELETE /groups/{id}/triggers{?instanceId}</spanx></t>

<t>Description: Deletes an installed trigger</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the group of devices</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>instanceId: the instance ID of the trigger to disable (obtained from the Location header when the trigger was installed)</t>
</list></t>

<t>Response:</t>

<t><list style="symbols">
  <t>Returns HTTP status code 204 No Content on successful delete.</t>
</list></t>

<figure><artwork><![CDATA[
HTTP/1.1 204 No Content
]]></artwork></figure>

</section>
<section anchor="get-installed-triggers-for-a-group-of-devices"><name>Get installed triggers for a group of devices</name>

<t>Method: <spanx style="verb">GET /groups/{id}/triggers{?instanceId}</spanx></t>

<t>Description: Get the installed triggers for a group of devices, or a specific trigger when specifying an instanceId.</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the group of devices</t>
</list></t>

<t>Query Parameters:</t>

<t><list style="symbols">
  <t>instanceId: an InstanceID, or comma separated list of event instance IDs to filter by (optional)</t>
  <t>If no query parameter is supplied, then all triggers for the group of devices must be retrieved</t>
</list></t>

<t>Response:</t>

<t>The response must be an array of triggers, each containing an instanceId, the sdfName of an affordance and an action.
 - deviceId: must be the device ID for each installed trigger.
 - eventName: must be the sdfName of the affordance (event or action) that is associated with the trigger.
 - action: must be the NIPC URI of the action to be executed when the trigger is activated.</t>

<figure><sourcecode type="cddl" markers="true" name="group_trigger_status_array.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

; Group Trigger status response array and item shape

GroupTriggerStatusResponseArray = [* GroupTriggerResponse]

GroupTriggerResponse = (GroupTriggerSuccessResponse // \
                                         GroupTriggerFailureResponse)

GroupTriggerSuccessResponse = {
  eventName: text,      ; SDF event name
  action: text,      ; NIPC action operation to execute
  deviceId: text     ; UUID (as text)
}

GroupTriggerFailureResponse = {
  FailureResponse,
  ? deviceId: text
}
]]></sourcecode></figure>

<t>Example of a response:</t>

<figure title="Example get multiple group triggers response" anchor="exgetmgrouptriggers"><sourcecode type="json" markers="true"><![CDATA[=============== NOTE: '\' line wrapping per RFC 8792 ================

[
  {
    "deviceId": "02ee282c-8915-4b2e-bbd2-88966773134a",
    "eventName": "https://example.com/heartrate#/sdfObject/\
                                         healthsensor/sdfEvent/rate",
    "action": "/devices/3171ec43-42a5-4415-ab4b-afd0dfbe9615/actions\
?actionName=https%3A%2F%2Fexample.com%2FAlarmSystem%23%2FsdfObject%\
                                           2Fbell%2FsdfAction%2Fring"
  }
]
]]></sourcecode></figure>

</section>
</section>
<section anchor="nipc-connection-management-apis"><name>NIPC explicit connection management APIs</name>

<t>Some protocols do not require explicit connection setup; for those protocols, the APIs in this section do not apply. For protocols that do require a connection (e.g., BLE), an NIPC gateway performs implicit connection management for individual operations (establish on demand; release on completion), so clients ordinarily need not manage connections. Clients MAY choose to explicitly establish and retain a connection to perform a sequence of operations that depends on intermediate results. This section specifies APIs for explicit connection lifecycle control. Examples use BLE.</t>

<section anchor="protocol-information-obj"><name>Protocol Information Object</name>
<t>The protocol information object is used to define protocol specific parameters for connections. The protocol information object is protocol specific and defined in the protocol extensions. An example of where a protocol info object would be used is to return protocol specific connection parameters when making connections, for example a BLE service map. An example of a BLE protocol information object is shown below.</t>

<t>This specification defines both the BLE and the Zigbee protocol information objects for connections and broadcast messages.</t>

<figure><sourcecode type="cddl" markers="true" name="protocolinfo.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

; Top-level wrappers
protocol-info-service-map = (
  ? protocolInformation: ble-service-map / zigbee-service-map
)

protocol-info-broadcast = (
  ? protocolInformation: ble-broadcast / zigbee-broadcast
)

; BLE protocol information
ble-service-map = {
  ble: {
    ? services: [* ble-service],
    ? cached: bool,
    ? cacheExpiryDuration: int,
    ? autoUpdate: bool,
    ? bonding: bonding-type,
  }
}

bonding-type = "default" / "none" / "justworks" / "passkey" / "oob"

ble-service = {
  serviceID: uuid,
  ? characteristics: [* ble-characteristic],
}

ble-characteristic = {
  characteristicID: uuid,
  ? flags: [* ble-flag],
  ? descriptors: [* ble-descriptor],
}

ble-flag = "read" / "write" / "notify" / "indicate" / "write-no-\
                                                            response"

ble-descriptor = {
  descriptorID: uuid,
}

ble-broadcast = {
  ble: {
    ? connectable: bool,
  },
}

; Zigbee protocol information
zigbee-service-map = {
  zigbee: {
    ? endpoints: [* zigbee-endpoint],
  },
}

zigbee-endpoint = {
  endpointID: uint,
  ? clusters: [* zigbee-cluster],
}

zigbee-cluster = {
  clusterID: uint,
  ? attributes: [* zigbee-attribute],
}

zigbee-attribute = {
  attributeID: uint,
  attributeType: uint,
  ? flags: [* zigbee-flag],
}

zigbee-flag = "read" / "write" / "report"

zigbee-broadcast = {
  zigbee: {
  },
}

; Basic types
uuid = tstr .regexp "(?i)^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-\
                                                 f]{4}-[0-9a-f]{12}$"
]]></sourcecode></figure>

</section>
<section anchor="connect-to-a-device"><name>Connect to a device</name>

<t>Method: <spanx style="verb">POST /devices/{id}/connections</spanx></t>

<t>Description: Connect to a device</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>Connection retry parameters</t>
  <t>A protocol info object representing the BLE service map to be discovered. In the case of BLE, if no protocol info object is included, service discovery is performed to discover all supported properties when connecting to a device. Optionally, service discovery may be limited to properties defined in the "ble" protocol extension. The services to be discovered can be added in an array. Property discovery can be buffered across connections, so the API also supports caching parameters.</t>
</list></t>

<figure><sourcecode type="cddl" markers="true" name="connection.cddl"><![CDATA[
ConnectionRequest = {
  ? retries: uint,
  ? protocol-info-service-map
}

ConnectionResponse = {
  id: text,  ; Device ID
  ? protocol-info-service-map
}
]]></sourcecode></figure>

<t>Example body of a connection without specific discovery of properties:</t>

<figure title="Example connection" anchor="exconn"><sourcecode type="json" markers="true"><![CDATA[{
  "retries": 3
}
]]></sourcecode></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"retries" defines the number of retries in case the operation does not
succeed</t>
</list></t>

<t>In case the application would like to discover specific properties of a device, an additional protocol information object can be provided that defines what properties should be discovered.</t>

<t>Example body of a BLE connection with specific discovery of properties:</t>

<figure title="Example connection with explicit discovery of connections" anchor="exconnprp"><sourcecode type="json" markers="true"><![CDATA[{
  "retries": 3,
  "protocolInformation": {
    "ble": {
      "services": [
        {
          "serviceID": "00001809-0000-1000-8000-00805f9b34fb"
        }
      ],
      "cached": false,
      "cacheExpiryDuration": 3600,
      "autoUpdate": true,
      "bonding": "default"
    }
  }
}
]]></sourcecode></figure>

<t>where in the BLE protocol object:</t>

<t><list style="symbols">
  <t>"services" is an array of services defined by their serviceIDs.</t>
  <t>"cached" refers to whether the services need to be discovered for this connection.
If cached is true, the services will be discovered for this connection only if it is not present in the cache.
If cached is false, the services will be discovered for this connection.
The services will be cached once it is discovered.</t>
  <t>"cacheExpiryDuration" defines how long (in seconds) the cache should be maintained
before purging.</t>
  <t>some devices support notifications on changes in services,
"autoUpdate" allows the network to update services based on
notification (on by default)</t>
  <t>"bonding" allows you to override the bonding method configured in the device object. Possible values are default, none, justworks, passkey, oob. Default behavior is to use the bonding method defined in the device object.</t>
</list></t>

<t>Response:</t>

<t>Success responses includes an optional protocol information object with an array of discovered properties, as defined in the BLE protocol info object in section <xref target="protocol-information-obj"/>.
This is an array of supported services, which in turn contains an array of characteristics, which in turn contains an array of descriptors, as shown in <xref target="BLEservices"/>.</t>

<figure title="BLE Services" anchor="BLEservices"><artwork><![CDATA[
    services
     - serviceID
        |
        |> characteristics
            - characteristicID
            - flags
               |
               |> Descriptors
                   - descriptorID
]]></artwork></figure>

<t>Example of a response:</t>

<figure title="Example connection response" anchor="exconnresp"><sourcecode type="json" markers="true"><![CDATA[
{
  "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
  "protocolInformation": {
    "ble": {
      "services": [
        {
          "serviceID": "00001809-0000-1000-8000-00805f9b34fb",
          "characteristics": [
            {
              "characteristicID":
                  "00002a1c-0000-1000-8000-00805f9b34fb",
              "flags": [
                "read",
                "write"
              ],
              "descriptors": [
                {
                  "descriptorID":
                      "00002902-0000-1000-8000-00805f9b34fb"
                }
              ]
            }
          ]
        }
      ]
    }
  }
}
]]></sourcecode></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id" is the ID of the device</t>
  <t>"protocolInformation" contains an Array of BLE services as shown in
   <xref target="BLEservices"/></t>
</list></t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="update-a-connection"><name>Update a connection</name>

<t>Method: <spanx style="verb">PUT /devices/{id}/connections</spanx></t>

<t>Description: Update a connection, for BLE this will update the cached ServiceMap for a device. Full service discovery will be performed, unless specific services are described in the API body.</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>A protocol information object. In the case of BLE, if no protocol information is included, service discovery is performed to discover all supported properties when connecting to a device. Optionally, service discovery may be limited to properties defined in the "ble" protocol extension. The services to be discovered can be added in an array. Property discovery can be buffered across connections, so the API also supports caching parameters.</t>
</list></t>

<t>Example body of an update connection:</t>

<figure title="Example service discovery response" anchor="exupconn"><sourcecode type="json" markers="true"><![CDATA[
{
  "protocolInformation": {
    "ble": {
      "services": [
        {
          "serviceID": "00001809-0000-1000-8000-00805f9b34fb"
        }
      ],
      "cached": false,
      "cacheExpiryDuration": 3600,
      "autoUpdate": true
    }
  }
}
]]></sourcecode></figure>

<t>where in the BLE protocol object:</t>

<t><list style="symbols">
  <t>"services" is an array of services defined by their serviceIDs</t>
  <t>"cached" refers to whether the services need to be cached for
subsequent connects, in order not to perform service discovery on
each request</t>
  <t>"cacheExpiryDuration" defines how long the cache should be maintained
before purging</t>
  <t>some devices support notifications on changes in services,
"autoUpdate" allows the network to update services based on
notification (on by default)</t>
</list></t>

<t>Response:</t>

<t>Success responses include a protocol information object with an array of
discovered properties, as defined in the specific protocol.
For example, for BLE, this is an array of supported services, which in turn
contains an array of characteristics, which in turn contains an array of
descriptors, as shown in <xref target="BLEservices"/>.</t>

<t>Example of a response:</t>

<figure title="Example connection response" anchor="exupconnresp"><sourcecode type="json" markers="true"><![CDATA[
{
  "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
  "protocolInformation": {
    "ble": {
      "services": [
        {
          "serviceID": "00001809-0000-1000-8000-00805f9b34fb",
          "characteristics": [
            {
              "characteristicID":
                "00002a1c-0000-1000-8000-00805f9b34fb",
              "flags": [
                "read",
                "write"
              ],
              "descriptors": [
                {
                  "descriptorID":
                    "00002902-0000-1000-8000-00805f9b34fb"
                }
              ]
            }
          ]
        }
      ]
    }
  }
}
]]></sourcecode></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id" is the ID of the device</t>
  <t>"protocolInformation" contains an Array of BLE services as shown in
   <xref target="BLEservices"/> and described in <xref target="protocol-information-obj"/>.</t>
</list></t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="disconnect-from-a-device"><name>Disconnect from a device</name>

<t>Method: <spanx style="verb">DELETE /devices/{id}/connections</spanx></t>

<t>Description: Disconnect from a device</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Response:</t>

<t>Returns HTTP status code 204 No Content on successful disconnect.</t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="get-connection-status"><name>Get connection status</name>

<t>Method: <spanx style="verb">GET /devices/{id}/connections</spanx></t>

<t>Description: Get connection status for a device. Success when device(s)
is/are connected, includes service map for the device if available.
Failure when a device is not connected.</t>

<t>Parameters:</t>

<t><list style="symbols">
  <t>id: the ID of the device</t>
</list></t>

<t>Response:</t>

<t>Example of a response:</t>

<figure title="Example connection status response" anchor="exconnstatresp"><sourcecode type="json" markers="true"><![CDATA[
{
  "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
  "protocolInformation": {
    "ble": {
      "services": [
        {
          "serviceID": "00001809-0000-1000-8000-00805f9b34fb",
          "characteristics": [
            {
              "characteristicID":
                "00002a1c-0000-1000-8000-00805f9b34fb",
              "flags": [
                "read",
                "write"
              ],
              "descriptors": [
                {
                  "descriptorID":
                    "00002902-0000-1000-8000-00805f9b34fb"
                }
              ]
            }
          ]
        }
      ]
    }
  }
}
]]></sourcecode></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id" is the ID of the device</t>
  <t>"protocolInformation" contains an Array of BLE services as shown in <xref target="BLEservices"/></t>
</list></t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
</section>
</section>
<section anchor="nipc-extensibility"><name>NIPC Extensibility</name>

<t>NIPC is designed to be extensible in two complementary ways:</t>

<t><list style="symbols">
  <t>Protocol mappings: NIPC relies on SDF protocol mappings to relate protocol‑neutral affordances to protocol‑specific operations. Adding a new mapping enables support for additional device protocols (or versions) without the need to change the NIPC API itself. This allows deployments to evolve as device ecosystems change, while preserving application portability and gateway interoperability. Protocol mapping is an extension to SDF and described in <xref target="I-D.ietf-asdf-sdf-protocol-mapping"/>.</t>
  <t>API extensions: Extensions compose multiple NIPC operations into a single request or introduce specialized flows optimized for common scenarios (e.g., bulk property updates, conditional reads, firmware operations). Extensions MUST use the “/extensions” path element and SHOULD focus on efficiency, latency reduction, and operational simplicity (fewer round trips, reduced state management). To ensure interoperability and consistent security review, extensions MUST be registered with IANA as defined in <xref target="iana-api-ext"/>.</t>
</list></t>

<section anchor="protocol-mappings"><name>Protocol mappings</name>

<t>NIPC relies on SDF protocol mappings <xref target="I-D.ietf-asdf-sdf-protocol-mapping"/> to relate protocol‑neutral affordances to protocol‑specific operations. In <xref target="I-D.ietf-asdf-sdf-protocol-mapping"/> BLE and Zigbee are used as examples, however the mapping mechanism is extensible; so support for additional protocols (or versions) can be added without changing the NIPC schema or API.</t>

</section>
<section anchor="apiextensions"><name>API extensions</name>

<t>The extension APIs allow for extensibility of the APIs.
Extension APIs may leverage the basic NIPC defined APIs and combine them in compound statements in order to streamline application operation against devices, make operations more expedient and convenient in one API call. An example of this is the bulk API extension.
They may also introduce new functionality that is specific to a use case or protocol, such as the BLE transmit API.</t>

<t>Extensions must be defined under the /extensions path element. The extension name is defined as a path parameter after the /extensions path element. Extensions may define their own request and response payloads, as well as their own query parameters.
Extensions must be IANA registered as defined in <xref target="iana-api-ext"/>.</t>

<t>Extensions MAY implement long‑running operations (e.g., firmware updates, bulk actions). For such operations, the server SHOULD respond with 202 Accepted and a Location header referencing a status URI. Clients MAY poll the status URI (GET) to obtain progress. While the operation is in progress, the status endpoint SHOULD return 200 OK with status information; upon completion, the server MAY redirect with 303 See Other to the final result resource, or return 200 OK with the completed result from the status endpoint. This pattern minimizes client state, supports retry, and provides a uniform mechanism for tracking asynchronous execution.</t>

<t>In the appendix <xref target="NIPCextensions"/>, we have defined a few example extensions.</t>

</section>
</section>
<section anchor="errorhandling"><name>NIPC Error Handling</name>

<t>Error types in NIPC APIs must use URI-based error type identifiers as defined in <xref target="iana-problem-details"/>. The error types can be generic or specific to the API category. The error types are organized into the following categories:</t>

<t><list style="symbols">
  <t>Generic: Broadly applicable errors, including authorization, invalid identifiers, and generic failures.</t>
  <t>Property APIs: Errors related to property APIs (read/write).</t>
  <t>Event APIs: Errors related to event APIs (enable/disable).</t>
  <t>Protocol specific: Errors related to protocol-specific operations.</t>
  <t>Extension APIs: Errors related to extension APIs.</t>
</list></t>

<t>NIPC error types are defined in the table below:</t>

<texttable title="Error Codes" anchor="errorcodes">
      <ttcol align='left'>Error Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>Category</ttcol>
      <c>invalid-id</c>
      <c>Invalid device ID or gateway doesn't recognize the ID</c>
      <c>Generic</c>
      <c>invalid-sdf-url</c>
      <c>Invalid SDF URL or SDF affordance not found</c>
      <c>Generic</c>
      <c>extension-operation-not-executed</c>
      <c>Operation was not executed since the previous operation failed</c>
      <c>Generic</c>
      <c>sdf-model-already-registered</c>
      <c>SDF model already registered</c>
      <c>Generic</c>
      <c>sdf-model-in-use</c>
      <c>SDF model in use</c>
      <c>Generic</c>
      <c>unsupported-uri-scheme</c>
      <c>Unsupported URI scheme</c>
      <c>Generic</c>
      <c>property-not-readable</c>
      <c>Property not readable</c>
      <c>Property APIs</c>
      <c>property-not-writable</c>
      <c>Property not writable</c>
      <c>Property APIs</c>
      <c>property-read-failed</c>
      <c>Property read failed</c>
      <c>Property APIs</c>
      <c>property-write-failed</c>
      <c>Property write failed</c>
      <c>Property APIs</c>
      <c>event-already-enabled</c>
      <c>Event already enabled</c>
      <c>Event APIs</c>
      <c>event-not-enabled</c>
      <c>Event not enabled</c>
      <c>Event APIs</c>
      <c>event-not-registered</c>
      <c>Event not registered for any data application</c>
      <c>Event APIs</c>
      <c>trigger-already-enabled</c>
      <c>Trigger already enabled for this event</c>
      <c>Trigger APIs</c>
      <c>protocolmap-ble-already-connected</c>
      <c>Device already connected</c>
      <c>Protocol specific</c>
      <c>protocolmap-ble-no-connection</c>
      <c>No connection found for device</c>
      <c>Protocol specific</c>
      <c>protocolmap-ble-connection-timeout</c>
      <c>BLE connection timeout</c>
      <c>Protocol specific</c>
      <c>protocolmap-ble-bonding-failed</c>
      <c>BLE bonding failed</c>
      <c>Protocol specific</c>
      <c>protocolmap-ble-connection-failed</c>
      <c>BLE connection failed</c>
      <c>Protocol specific</c>
      <c>protocolmap-ble-service-discovery-failed</c>
      <c>BLE service discovery failed</c>
      <c>Protocol specific</c>
      <c>protocolmap-ble-invalid-service-or-characteristic</c>
      <c>Invalid BLE service or characteristic ID</c>
      <c>Protocol specific</c>
      <c>protocolmap-zigbee-connection-timeout</c>
      <c>Zigbee connection timeout</c>
      <c>Protocol specific</c>
      <c>protocolmap-zigbee-invalid-endpoint-or-cluster</c>
      <c>Invalid Zigbee endpoint or cluster ID</c>
      <c>Protocol specific</c>
      <c>extension-transmit-invalid-data</c>
      <c>Invalid transmit data</c>
      <c>Transmit APIs</c>
      <c>extension-firmware-rollback</c>
      <c>Firmware rollback</c>
      <c>Extension APIs</c>
      <c>extension-firmware-update-failed</c>
      <c>Firmware update failed</c>
      <c>Extension APIs</c>
</texttable>

<t>The appropriate HTTP status code is returned in the response.</t>

</section>
<section anchor="pubsub"><name>Publish/Subscribe Interface</name>

<t>Events are delivered via a publish/subscribe interface. Event types include: (1) streaming data (enabled/disabled via the NIPC Events API), (2) broadcasts (e.g., advertisements), and (3) connection status (device link up/down). Event payloads are encoded in CBOR <xref target="RFC8949"/> and MAY be transported over MQTT, webhook, or websocket. CBOR is used because non‑IP device payloads are typically binary; it encodes such data efficiently and is more compact than JSON, reducing bandwidth.</t>

<section anchor="cddl-data-subscription"><name>CDDL Definition</name>

<t>The event streaming format is defined here in CDDL <xref target="RFC8610"/>.
A DataSubscription is a CBOR map containing the raw payload (bytes) and a timestamp (epoch seconds). It MAY include deviceID (the SCIM device identifier) when the payload is associated with a known device. Optional members (e.g., apMacAddress, rssi) MAY be present but can reveal deployment topology and SHOULD be omitted unless required. A choice group within DataSubscription indicates the event type (e.g., advertisement, subscription notification, connection status). An event publication MAY carry one or more DataSubscription entries in an array. Such an array is represented as DataBatch.</t>

<t>The subscription type choice uses a CDDL socket ($$subscription-extension) to allow extensibility. New subscription types registered with IANA (see <xref target="iana-data-subscription-types"/>) can be added using the CDDL plug syntax (//=) without modifying the base schema.</t>

<figure><sourcecode type="cddl" markers="true" name="data_subscription.cddl"><![CDATA[
start = DataBatch

DataBatch = [* DataSubscription]

DataSubscription = {
  ? data: bytes,
  timestamp: float, ; epoch in seconds
  ? deviceID: text,
  ? apMacAddress: text,
  subscription
}

; Subscription type - IANA registered types
subscription = (
  bleSubscription: BleSubscription //
  bleAdvertisement: BleAdvertisement //
  bleConnectionStatus: BleConnectionStatus //
  zigbeeSubscription: ZigbeeSubscription //
  zigbeeConnectionStatus: ZigbeeConnectionStatus //
  $$subscription-extension
)

BleSubscription = {
  serviceID: text,
  characteristicID: text
}

BleAdvertisement = {
  macAddress: text,
  ? rssi: nint,
}

BleConnectionStatus = {
  macAddress: text,
  connected: bool,
  ? reason: int
}

ZigbeeSubscription = {
  type: "attribute_reporting" / "write_event",
  endpointID: uint,
  clusterID: uint,
  attributeID: uint,
  attributeType: uint,
  ? profileID: uint,
  ? manufacturerCode: uint
}

ZigbeeConnectionStatus = {
  connected: bool,   ; true = joined, false = left the network
  ? reason: int,
  ? rssi: int,       ; received signal strength indicator, in dBm
  ? lqi: uint        ; link quality indicator (0-255)
}
]]></sourcecode></figure>

</section>
<section anchor="cbor-examples"><name>CBOR Examples</name>

<t>This section contains a few examples of the DataSubscription struct in CBOR diagnostic notation.</t>

<figure title="Onboarded BLE Device Advertisement"><artwork><![CDATA[
[
  {
    "data": h'02011A020A0C16FF4C001007721F41B0392078',
    "deviceID": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
    "timestamp": 1727484393,
    "bleAdvertisement": {
        "macAddress": "C1:5C:00:00:00:01",
        "rssi": -25
    }
  }
]
]]></artwork></figure>

<figure title="BLE GATT Notification"><artwork><![CDATA[
[
  {
    "data": h'434630374346303739453036',
    "deviceID": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
    "timestamp": 1727484393,
    "bleSubscription": {
        "serviceID": "a4e649f4-4be5-11e5-885d-feff819cdc9f",
        "characteristicID": "c4c1f6e2-4be5-11e5-885d-feff819cdc9f"
    }
  }
]
]]></artwork></figure>

<figure title="BLE Connection status event"><artwork><![CDATA[
[
  {
    "deviceID": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
    "timestamp": 1727484393,
    "bleConnectionStatus": {
        "macAddress": "C1:5C:00:00:00:01",
        "connected": true
    }
  }
]
]]></artwork></figure>

<figure title="Zigbee Attribute Notification"><artwork><![CDATA[
[
  {
    "data": h'434630374346303739453036',
    "deviceID": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
    "timestamp": 1727484393,
    "zigbeeSubscription": {
        "type": "attribute_reporting",
        "endpointID": 1,
        "clusterID": 6,
        "attributeID": 12,
        "attributeType": 1
    }
  }
]
]]></artwork></figure>

<figure title="Zigbee Attribute Write Event"><artwork><![CDATA[
[
  {
    "data": h'434630374346303739453036',
    "deviceID": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
    "timestamp": 1727484393,
    "zigbeeSubscription": {
        "type": "write_event",
        "endpointID": 1,
        "clusterID": 6,
        "attributeID": 12,
        "attributeType": 1
    }
  }
]
]]></artwork></figure>

<figure title="Zigbee Connection status event"><artwork><![CDATA[
[
  {
    "deviceID": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
    "timestamp": 1727484393,
    "zigbeeConnectionStatus": {
        "connected": true,
        "rssi": -55,
        "lqi": 200
    }
  }
]
]]></artwork></figure>

</section>
</section>
<section anchor="examples"><name>Examples</name>

<t>This section contains a few examples on how applications can leverage NIPC operations to communicate with BLE and Zigbee devices.</t>

<section anchor="property-readwrite"><name>Property Read/Write</name>

<t>In this example, we will connect to a device and read and write from a property.</t>

<t>The sequence of operations for this are:</t>

<t><list style="symbols">
  <t>Declare a device instance using the SCIM Interface (out of scope of this
memo)</t>
  <t>Register an SDF model for the device  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[============== NOTE: '\' line wrapping per RFC 8792 ==============

POST /registrations/models
Content-Type: application/sdf+json
Accept: application/nipc+json
Host: localhost

{ ... }

HTTP/1.1 201 Created
content-type: application/nipc+json

[
  {
    "sdfName": "https://example.com/thermometer#/sdfThing/\
                                                      thermometer"
  }
]
]]></artwork></figure>
  <vspace blankLines='1'/>
Request Body: JSON object with the SDF model, from <xref target="thermometer-sdf"/></t>
  <t>Read a property from the BLE device  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[============== NOTE: '\' line wrapping per RFC 8792 ==============

GET /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/properties?\
propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
              2FsdfThing%2Fthermometer%2FsdfProperty%2Fdevice_name
Accept: application/nipc+json
Host: localhost

HTTP/1.1 200 OK
content-type: application/nipc+json

[
  {
    "property": "https://example.com/thermometer#/sdfThing/\
                             thermometer/sdfProperty/device_name",
    "value": "dGVzdA=="
  }
]
]]></artwork></figure>
  </t>
  <t>Write to a property on the BLE device  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[============== NOTE: '\' line wrapping per RFC 8792 ==============

PUT /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/properties
Content-Type: application/nipc+json
Host: localhost

[
  {
    "property": "https://example.com/thermometer#/sdfThing/\
                             thermometer/sdfProperty/device_name",
    "value": "dGVzdA=="
  }
]

HTTP/1.1 200 OK
content-type: application/nipc+json

[
  {
    "status": 200
  }
]
]]></artwork></figure>
  </t>
</list></t>

</section>
<section anchor="enabling-an-event-on-a-device"><name>Enabling an Event on a Device</name>

<t>In this example, we will declare a device instance, and setup an advertisement
subscription event for that device.</t>

<t>The sequence of operations for this are:</t>

<t><list style="symbols">
  <t>Declaring a device instance and endpoint app using the SCIM Interface (out of scope of this
   memo)</t>
  <t>Register an SDF model for the device  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[============== NOTE: '\' line wrapping per RFC 8792 ==============

POST /registrations/models
Content-Type: application/sdf+json
Accept: application/nipc+json
Host: localhost

{ ... }

HTTP/1.1 201 Created
content-type: application/nipc+json

[
  {
    "sdfName": "https://example.com/thermometer#/sdfThing/\
                                                      thermometer"
  }
]
]]></artwork></figure>
  <vspace blankLines='1'/>
Request Body: JSON object with the SDF model, from <xref target="thermometer-sdf"/></t>
  <t>Register the data app with the event  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[============== NOTE: '\' line wrapping per RFC 8792 ==============

POST /registrations/data-apps?dataAppId=0927ce7c-b258-4bfa-a345-\
                                                      bcc9f74385b4
Content-Type: application/nipc+json
Accept: application/nipc+json
Host: localhost

{
  "events": [
    {
      "event": "https://example.com/thermometer#/sdfThing/\
                                   thermometer/sdfEvent/isPresent"
    }
  ],
  "mqttClient": true
}

HTTP/1.1 201 Created
content-type: application/nipc+json

{
  "events": [
    {
      "event": "https://example.com/thermometer#/sdfThing/\
                                   thermometer/sdfEvent/isPresent"
    }
  ],
  "mqttClient": true
}
]]></artwork></figure>
  </t>
  <t>Enable the advertisement event  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[============== NOTE: '\' line wrapping per RFC 8792 ==============

POST /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/events?\
eventName=https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%\
                              2Fthermometer%2FsdfEvent%2FisPresent
Host: localhost
Content-Length: 0

HTTP/1.1 201 Created
Location: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/events?\
                   instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
]]></artwork></figure>
  </t>
  <t>Check the status of the event  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[============== NOTE: '\' line wrapping per RFC 8792 ==============

GET /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/events?\
                   instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
Host: localhost

HTTP/1.1 200 OK
content-type: application/nipc+json

[
  {
    "instanceId": "02ee282c-8915-4b2e-bbd2-88966773134a",
    "event": "https://example.com/thermometer#/sdfThing/\
                                   thermometer/sdfEvent/isPresent"
  }
]
]]></artwork></figure>
  </t>
</list></t>

</section>
<section anchor="enabling-an-event-on-a-group-of-devices"><name>Enabling an Event on a Group of Devices</name>

<t>In this example, we will enable an advertisement subscription event
for a group of devices.</t>

<t>The sequence of operations for this are:</t>

<t><list style="symbols">
  <t>Provision a device and endpoint app using the SCIM Interface (out of scope of this
   memo)</t>
  <t>Register an SDF model for the devices  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[============== NOTE: '\' line wrapping per RFC 8792 ==============

POST /registrations/models
Content-Type: application/sdf+json
Accept: application/nipc+json
Host: localhost

{ ... }

HTTP/1.1 201 Created
content-type: application/nipc+json

[
  {
    "sdfName": "https://example.com/thermometer#/sdfThing/\
                                                      thermometer"
  }
]
]]></artwork></figure>
  <vspace blankLines='1'/>
Request Body: JSON object with the SDF model, from <xref target="thermometer-sdf"/></t>
  <t>Register the data app with the event  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[============== NOTE: '\' line wrapping per RFC 8792 ==============

POST /registrations/data-apps?dataAppId=0927ce7c-b258-4bfa-a345-\
                                                      bcc9f74385b4
Content-Type: application/nipc+json
Accept: application/nipc+json
Host: localhost

{
  "events": [
    {
      "event": "https://example.com/thermometer#/sdfThing/\
                                   thermometer/sdfEvent/isPresent"
    }
  ],
  "mqttClient": true
}

HTTP/1.1 201 Created
content-type: application/nipc+json

{
  "events": [
    {
      "event": "https://example.com/thermometer#/sdfThing/\
                                   thermometer/sdfEvent/isPresent"
    }
  ],
  "mqttClient": true
}
]]></artwork></figure>
  </t>
  <t>Enable the advertisement event on a group of devices  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[============== NOTE: '\' line wrapping per RFC 8792 ==============

POST /groups/0dc729d7-f6c3-491d-9b9d-e7176d2be243/events?\
eventName=https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%\
                              2Fthermometer%2FsdfEvent%2FisPresent
Host: localhost
Content-Length: 0

HTTP/1.1 201 Created
Location: /groups/0dc729d7-f6c3-491d-9b9d-e7176d2be243/events?\
                   instanceId=f1b9f26b-21ce-4deb-9d57-289ba7e17cce
]]></artwork></figure>
  </t>
  <t>Check the status of the event  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[============== NOTE: '\' line wrapping per RFC 8792 ==============

GET /groups/0dc729d7-f6c3-491d-9b9d-e7176d2be243/events?\
                   instanceId=f1b9f26b-21ce-4deb-9d57-289ba7e17cce
Host: localhost

HTTP/1.1 200 OK
content-type: application/nipc+json

[
  {
    "event": "https://example.com/heartrate#/sdfObject/\
                              healthsensor/sdfEvent/fallDetected",
    "deviceId": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
  },
  {
    "event": "https://example.com/heartrate#/sdfObject/\
                              healthsensor/sdfEvent/fallDetected",
    "deviceId": "d62c7fb2-a216-4811-a388-053b17fdbedc"
  },
  {
    "event": "https://example.com/heartrate#/sdfObject/\
                              healthsensor/sdfEvent/fallDetected",
    "deviceId": "01b52a23-b98c-454c-ba9e-086a43bdfd79"
  },
  {
    "type": "https://www.iana.org/assignments/nipc-problem-types#\
                                               event-not-enabled",
    "status": 400,
    "title": "Event Not Enabled",
    "deviceId": "9171ec16-e3c1-4ccf-ad23-b92a1a3f069d",
    "detail": "Failed to enable the event for device 9171ec16-\
                                      e3c1-4ccf-ad23-b92a1a3f069d"
  }
]
]]></artwork></figure>
  </t>
</list></t>

</section>
</section>
<section removeInRFC="true" anchor="implementation-status"><name>Implementation Status</name>

<t>This section records the status of known implementations of the
protocol defined by this specification at the time of posting of
this Internet-Draft, and is based on a proposal described in
<xref target="RFC7942"/>.  The description of implementations in this section is
intended to assist the IETF in its decision processes in
progressing drafts to RFCs.  Please note that the listing of any
individual implementation here does not imply endorsement by the
IETF.  Furthermore, no effort has been spent to verify the
information presented here that was supplied by IETF contributors.
This is not intended as, and must not be construed to be, a
catalog of available implementations or their features.  Readers
are advised to note that other implementations may exist.</t>

<t>According to <xref target="RFC7942"/>, "this will allow reviewers and working
groups to assign due consideration to documents that have the
benefit of running code, which may serve as evidence of valuable
experimentation and feedback that have made the implemented
protocols more mature.  It is up to the individual working groups
to use this information as they see fit".</t>

<section anchor="tiedie-iot"><name>TieDie IoT</name>

<t>Organization: Cisco Systems, North Carolina State University</t>

<t>Description: Open-source implementation of the NIPC APIs and gateway functionality for BLE. Client libraries and sample application functions for Python and Java are also provided.</t>

<t>Level of maturity: Open-source prototype</t>

<t>Coverage: All NIPC APIs for BLE protocol mapping</t>

<t>Version compatibility: All versions up to draft-21</t>

<t>Licensing: Apache License, Version 2.0</t>

<t>URL: <eref target="https://github.com/iot-onboarding/tiedie"></eref></t>

</section>
<section anchor="cisco-sensor-connect-for-iot-services-catalyst"><name>Cisco Sensor Connect for IoT Services (Catalyst)</name>

<t>Organization: Cisco Systems</t>

<t>Description: Commercial solution that delivers advanced BLE capabilities over Cisco Wireless infrastructure.</t>

<t>Level of maturity: Production</t>

<t>Coverage: All NIPC APIs for BLE protocol mapping</t>

<t>Version compatibility: draft-00</t>

<t>Licensing: Proprietary</t>

<t>URL: <eref target="https://developer.cisco.com/docs/spaces-connect-for-iot-services/"></eref></t>

</section>
<section anchor="cisco-sensor-connect-for-iot-services-meraki"><name>Cisco Sensor Connect for IoT Services (Meraki)</name>

<t>Organization: Cisco Systems</t>

<t>Description: Commercial solution that delivers advanced BLE capabilities over Cisco Wireless infrastructure.</t>

<t>Level of maturity: Beta</t>

<t>Coverage: All NIPC APIs for BLE protocol mapping</t>

<t>Version compatibility: draft-21</t>

<t>Licensing: Proprietary</t>

</section>
<section anchor="nipc-prototype"><name>NIPC Prototype</name>

<t>Organization: Ericsson Research</t>

<t>Description: Prototype implementation in C of the NIPC API.</t>

<t>Level of maturity: Research prototype</t>

<t>Coverage: Registration and NIPC operations</t>

<t>Version compatibility: Draft-04</t>

<t>Licensing: Proprietary</t>

<t>Contact: Lorenzo Corneo <eref target="mailto:lorenzo.corneo@ericsson.com">lorenzo.corneo@ericsson.com</eref></t>

</section>
</section>
<section anchor="security-considerations"><name>Security Considerations</name>

<section anchor="payload-encryption-considerations"><name>Payload Encryption Considerations</name>

<t>Responses to NIPC operations requests may contain sensitive or confidential information.  Therefore, application and device implementations should consider payload encryption.
NIPC does not provide any payload encryption mechanism. If payload encryption is required, it MUST be provided by the underlying device protocol (e.g., BLE security modes) or by the transport-layer security mechanism (e.g., TLS).</t>

</section>
<section anchor="tls-support-considerations"><name>TLS Support Considerations</name>

<t>NIPC MUST run on top of a transport-layer security mechanism such as TLS. When leveraging TLS, the NIPC gateway MUST support TLS 1.2 <xref target="RFC5246"/> and TLS 1.3 <xref target="RFC8446"/> and MAY support additional transport-layer mechanisms.  When using TLS, the client MUST perform a TLS/SSL server identity check, per <xref target="RFC6125"/>.  Implementation security considerations for TLS can be found in <xref target="RFC7525"/>.</t>

</section>
<section anchor="http-considerations"><name>HTTP Considerations</name>

<t>NIPC runs on top of HTTP and is thus subject to the security considerations of HTTP <xref section="9" sectionFormat="of" target="RFC7230"/>.</t>

</section>
<section anchor="authorization-considerations"><name>Authorization Considerations</name>

<section anchor="api-authorization-considerations"><name>API authorization Considerations</name>

<t>To enable NIPC gateway functions, the network administrator MUST authorize applications (e.g., via exchange of tokens or public keys). Authorization MAY be role‑based. The following baseline roles are RECOMMENDED:</t>

<t><list style="symbols">
  <t>Provisioning: permitted to create and manage device and endpoint‑app identities via SCIM (typically co‑located with the gateway).</t>
  <t>Control: permitted to invoke NIPC property, action, and event APIs.</t>
  <t>Data: permitted to receive streamed event data.
Deployments MAY further refine authorization at per‑API or per‑affordance granularity.</t>
</list></t>

</section>
<section anchor="authorization-tokenbearer-tokencookie-considerations"><name>Authorization Token/Bearer Token/Cookie Considerations</name>

<t>When using authorization tokens such as those issued by OAuth 2.0 <xref target="RFC6749"/>, implementers MUST take into account threats and countermeasures as documented in <xref section="8" sectionFormat="of" target="RFC7521"/>.</t>

<t>Since the possession of a bearer token, Authorization token, or cookie MAY authorize the holder to perform NIPC Operations on devices, tokens and cookies MUST contain sufficient entropy to prevent random guessing attack; for example, see <xref section="5.2" sectionFormat="of" target="RFC6750"/> and <xref section="5.1.4.2.2" sectionFormat="of" target="RFC6819"/>.</t>

<t>As with all NIPC communications, bearer tokens and HTTP cookies MUST be exchanged using transport-layer security mechanism such as TLS.</t>

<t>Bearer tokens MUST have a limited lifetime that can be determined directly or indirectly (e.g., by checking with a validation service) by the application.  By expiring tokens, applications are forced to obtain a new token (which usually involves re-authentication) for continued authorized access.  For example, in OAuth 2.0, an application MAY use OAuth token refresh to obtain a new bearer token after authenticating to an authorization server.  See <xref section="6" sectionFormat="of" target="RFC6749"/>. As with bearer tokens, an HTTP cookie SHOULD last no longer than the lifetime of a browser session.  An expiry time should be set that limits session cookie lifetime as per <xref section="5.2.1" sectionFormat="of" target="RFC6265"/>.</t>

<t>Implementations supporting OAuth bearer tokens need to factor in security considerations of this authorization method <xref target="RFC7521"/>.
Implementers also need to consider authentication choices coupled with OAuth bearer tokens.  For example, when using OAuth bearer tokens with client authentication via client credentials <xref section="4.4" sectionFormat="of" target="RFC6749"/>, implementers need to consider the security considerations of client authentication via client credentials as described in <xref section="3.2" sectionFormat="of" target="RFC6819"/>.</t>

</section>
</section>
<section anchor="other-security-considerations"><name>Other Security Considerations</name>

<t><list style="symbols">
  <t>Preventing automated attacks: It is recommended to limit the number of requests that any particular application MAY make in a period of time.</t>
  <t>Logging and monitoring: It is recommended to log and monitor API usage to detect potential abuse or attacks.</t>
  <t>Input validation: It is recommended to validate all inputs to prevent injection attacks.</t>
  <t>Error handling: It is recommended to handle errors gracefully without exposing sensitive information.</t>
  <t>Least privilege: It is recommended to follow the principle of least privilege when granting access to resources.</t>
  <t>Storage and handling of sensitive data: Credentials MUST NOT be stored in clear-text, but MUST be stored using an encrypted protection mechanism (e.g., hashing).</t>
</list></t>

</section>
</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<t>This section provides guidance to the Internet Assigned Numbers Authority (IANA) regarding registration of values related to NIPC, in accordance with <xref target="RFC8126"/>.</t>

<section anchor="iana-media-types"><name>Media Type Registration</name>

<t>IANA is requested to add the following media type to the "Media Types" registry <xref target="IANA.media-types"/>. This document registers the "application/nipc+json" media type for messages of the NIPC APIs defined in this document carrying parameters encoded in JSON.</t>

<t>Type name: application</t>

<t>Subtype name: nipc+json</t>

<t>Required parameters: none</t>

<t>Optional parameters: none</t>

<t>Encoding considerations: Encoding considerations are identical to those specified for the "application/json" media type.</t>

<t>Security considerations: See <xref target="security-considerations"/> of this document.</t>

<t>Interoperability considerations: none</t>

<t>Published specification: This document, the NIPC API specification.</t>

<t>Applications that use this media type: Applications implementing NIPC APIs for IoT device management.</t>

<t>Fragment identifier considerations: none</t>

<t>Additional information:</t>

<t><list style="symbols">
  <t>Deprecated alias names for this type: none</t>
  <t>Magic number(s): none</t>
  <t>File extension(s): none</t>
  <t>Macintosh file type code(s): none</t>
</list></t>

<t>Person &amp; email address to contact for further information: ASDF WG mailing list (asdf@ietf.org), or IETF Applications and Real-Time Area (art@ietf.org)</t>

<t>Intended usage: LIMITED USE</t>

<t>Restrictions on usage: To be used for NIPC APIs as defined in this document.</t>

<t>Author/Change controller: IETF</t>

</section>
<section anchor="iana-well-known"><name>Well-known URIs</name>

<t>IANA is requested to register the following well-known URI in the "Well-Known URIs" registry <xref target="IANA.well-known-uris"/> as defined by <xref target="RFC8615"/>:</t>

<texttable>
      <ttcol align='left'>URI Suffix</ttcol>
      <ttcol align='left'>Change Controller</ttcol>
      <ttcol align='left'>Specification Document</ttcol>
      <c>nipc</c>
      <c>IETF</c>
      <c>This document, <xref target="paths-general"></xref></c>
</texttable>

<t>The well-known URI for NIPC is:</t>

<figure><artwork><![CDATA[
/.well-known/nipc
]]></artwork></figure>

</section>
<section anchor="iana-registries"><name>Registries</name>

<t>IANA is requested to create a "Non-Internet-connected Physical Components
(NIPC)" registry group, with the registries defined in this section.</t>

<section anchor="iana-api-ext"><name>API extensions</name>

<t>IANA is requested to create a new registry called "NIPC API extensions" in
the "Non-Internet-connected Physical Components (NIPC)" registry group.</t>

<t>The registration policy for this registry is Specification Required <xref target="RFC8126"/>.</t>

<t>The registry must contain following attributes:</t>

<t><list style="symbols">
  <t>Extension URI</t>
  <t>Extension name</t>
  <t>Description</t>
  <t>Openapi model describing the extension. This model must be reviewed by an expert.</t>
</list></t>

<t>Following API extensions are described in this document:</t>

<texttable>
      <ttcol align='left'>Extension URI</ttcol>
      <ttcol align='left'>Extension name</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>Model reference</ttcol>
      <c>/extensions/{id}/bulk</c>
      <c>Bulk API</c>
      <c>Call multiple NIPC's in a single request</c>
      <c><xref target="NIPCextensions"/></c>
      <c>/extensions/{id}/properties/file</c>
      <c>File write API</c>
      <c>Write a file with multiple property ops</c>
      <c><xref target="NIPCextensions"/></c>
      <c>/extensions/{id}/properties/blob</c>
      <c>Binary write API</c>
      <c>Write a binary blob with multiple property ops</c>
      <c><xref target="NIPCextensions"/></c>
      <c>/extensions/{id}/properties/read/conditional</c>
      <c>Read conditional API</c>
      <c>Read a property until a condition is fulfilled</c>
      <c><xref target="NIPCextensions"/></c>
      <c>/extensions/{id}/events/conditional</c>
      <c>Event conditional API</c>
      <c>Enable an event until a condition is fulfilled</c>
      <c><xref target="NIPCextensions"/></c>
      <c>/extensions/{id}/transmit</c>
      <c>Transmit API</c>
      <c>Transmits a payload to a device</c>
      <c><xref target="NIPCextensions"/></c>
</texttable>

</section>
<section anchor="iana-data-subscription-types"><name>Data Subscription Types</name>

<t>IANA is requested to create a new registry called "NIPC Data Subscription
Types" in the "Non-Internet-connected Physical Components (NIPC)" registry
group.</t>

<t>This registry tracks the subscription types used in the NIPC publish/subscribe
interface for streaming event data from devices. Each subscription type defines
a specific data format for a particular protocol or use case.</t>

<t>The registration policy for this registry is Specification Required <xref target="RFC8126"/>.</t>

<t>The registry must contain the following attributes:</t>

<t><list style="symbols">
  <t>Type Name: The CDDL key name used in the subscription choice</t>
  <t>Description: A brief description of the subscription type</t>
  <t>CDDL Definition: Reference to the CDDL structure defining the subscription data</t>
  <t>Reference: Document defining the subscription type</t>
</list></t>

<t>IANA is requested to register the following initial entries:</t>

<texttable>
      <ttcol align='left'>Type Name</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>CDDL Definition</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>bleSubscription</c>
      <c>BLE GATT notification/indication</c>
      <c>BleSubscription</c>
      <c>This document</c>
      <c>bleAdvertisement</c>
      <c>BLE advertisement data</c>
      <c>BleAdvertisement</c>
      <c>This document</c>
      <c>bleConnectionStatus</c>
      <c>BLE device connection status changes</c>
      <c>BleConnectionStatus</c>
      <c>This document</c>
      <c>zigbeeSubscription</c>
      <c>Zigbee attribute report or write event</c>
      <c>ZigbeeSubscription</c>
      <c>This document</c>
      <c>zigbeeConnectionStatus</c>
      <c>Zigbee device join/leave connection status</c>
      <c>ZigbeeConnectionStatus</c>
      <c>This document</c>
</texttable>

<t>The CDDL definitions for these subscription types are provided in <xref target="cddl-data-subscription"/>.</t>

</section>
<section anchor="iana-protocol-info-types"><name>NIPC Protocols</name>

<t>IANA is requested to create a new registry called "NIPC Protocols" in the
"Non-Internet-connected Physical Components (NIPC)" registry group.</t>

<t>This registry tracks the protocols used in the <spanx style="verb">protocolInformation</spanx> object
for NIPC connection management and service discovery operations. Each protocol
type defines a specific schema for protocol-specific information, as defined
in <xref target="protocol-information-obj"/>.</t>

<t>The registration policy for this registry is Specification Required <xref target="RFC8126"/>.</t>

<t>The registry must contain the following attributes:</t>

<t><list style="symbols">
  <t>Protocol Name: The key name used in the <spanx style="verb">protocolInformation</spanx> object</t>
  <t>Description: A brief description of the protocol type</t>
  <t>Reference: Document defining the protocol type</t>
</list></t>

<t>IANA is requested to register the following initial entries:</t>

<texttable>
      <ttcol align='left'>Protocol Name</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>ble</c>
      <c>Bluetooth Low Energy</c>
      <c>This document</c>
      <c>zigbee</c>
      <c>Zigbee</c>
      <c>This document</c>
</texttable>

</section>
</section>
<section anchor="iana-problem-details"><name>Problem Details for NIPC APIs</name>

<t>IANA is requested to create a new registry, the "NIPC Problem Type" registry,
with following URL: <eref target="https://www.iana.org/assignments/nipc-problem-types"></eref>.</t>

<t>The registration policy for this registry is Specification Required <xref target="RFC8126"/>.</t>

<t>Registrations MUST use the prefix "<eref target="https://www.iana.org/assignments/nipc-problem-types#"></eref>" for the type URI.</t>

<t>The registration requests MUST use the template defined in <xref section="4.2" sectionFormat="of" target="RFC9457"/>.</t>

<t>IANA is requested to register the following URIs in the "NIPC Problem Type"
registry:</t>

<texttable>
      <ttcol align='left'>Problem Type URI</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>https://www.iana.org/assignments/nipc-problem-types#invalid-id</c>
      <c>Invalid device ID or gateway doesn't recognize the ID</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#invalid-sdf-url</c>
      <c>Invalid SDF URL or SDF affordance not found</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#extension-operation-not-executed</c>
      <c>Operation was not executed since the previous operation failed</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#sdf-model-already-registered</c>
      <c>SDF model already registered</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#sdf-model-in-use</c>
      <c>SDF model in use</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#unsupported-uri-scheme</c>
      <c>Unsupported URI scheme</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#property-not-readable</c>
      <c>Property not readable</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#property-read-failed</c>
      <c>Property read failed</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#property-not-writable</c>
      <c>Property not writable</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#property-write-failed</c>
      <c>Property write failed</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#event-already-enabled</c>
      <c>Event already enabled</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#event-not-enabled</c>
      <c>Event not enabled</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#event-not-registered</c>
      <c>Event not registered for any data application</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#trigger-already-enabled</c>
      <c>Trigger already enabled for this event</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#protocolmap-ble-already-connected</c>
      <c>Device already connected</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#protocolmap-ble-no-connection</c>
      <c>No connection found for device</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#protocolmap-ble-connection-timeout</c>
      <c>BLE connection timeout</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#protocolmap-ble-bonding-failed</c>
      <c>BLE bonding failed</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#protocolmap-ble-connection-failed</c>
      <c>BLE connection failed</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#protocolmap-ble-service-discovery-failed</c>
      <c>BLE service discovery failed</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#protocolmap-ble-invalid-service-or-characteristic</c>
      <c>Invalid BLE service or characteristic ID</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#protocolmap-zigbee-connection-timeout</c>
      <c>Zigbee connection timeout</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#protocolmap-zigbee-invalid-endpoint-or-cluster</c>
      <c>Invalid Zigbee endpoint or cluster ID</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#extension-transmit-invalid-data</c>
      <c>Invalid transmit data</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#extension-firmware-rollback</c>
      <c>Firmware rollback</c>
      <c>This document</c>
      <c>https://www.iana.org/assignments/nipc-problem-types#extension-firmware-update-failed</c>
      <c>Firmware update failed</c>
      <c>This document</c>
</texttable>

<t>Each Problem Type URI is intended for use as the "type" member in Problem Details responses as described.</t>

</section>
</section>


  </middle>

  <back>


<references title='References' anchor="sec-combined-references">

    <references title='Normative References' anchor="sec-normative-references">



<reference anchor="RFC8610">
  <front>
    <title>Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures</title>
    <author fullname="H. Birkholz" initials="H." surname="Birkholz"/>
    <author fullname="C. Vigano" initials="C." surname="Vigano"/>
    <author fullname="C. Bormann" initials="C." surname="Bormann"/>
    <date month="June" year="2019"/>
    <abstract>
      <t>This document proposes a notational convention to express Concise Binary Object Representation (CBOR) data structures (RFC 7049). Its main goal is to provide an easy and unambiguous way to express structures for protocol messages and data formats that use CBOR or JSON.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8610"/>
  <seriesInfo name="DOI" value="10.17487/RFC8610"/>
</reference>
<reference anchor="RFC9880">
  <front>
    <title>Semantic Definition Format (SDF) for Data and Interactions of Things</title>
    <author fullname="M. Koster" initials="M." role="editor" surname="Koster"/>
    <author fullname="C. Bormann" initials="C." role="editor" surname="Bormann"/>
    <author fullname="A. Keränen" initials="A." surname="Keränen"/>
    <date month="January" year="2026"/>
    <abstract>
      <t>The Semantic Definition Format (SDF) is a format for domain experts to use in the creation and maintenance of data and interaction models that describe Things, i.e., physical objects that are available for interaction over a network. An SDF specification describes definitions of SDF Objects/SDF Things and their associated interactions (Events, Actions, and Properties), as well as the Data types for the information exchanged in those interactions. Tools convert this format to database formats and other serializations as needed.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9880"/>
  <seriesInfo name="DOI" value="10.17487/RFC9880"/>
</reference>
<reference anchor="RFC9944">
  <front>
    <title>Device Schema Extensions to the System for Cross-Domain Identity Management (SCIM) Model</title>
    <author fullname="M. Shahzad" initials="M." surname="Shahzad"/>
    <author fullname="H. Iqbal" initials="H." surname="Iqbal"/>
    <author fullname="E. Lear" initials="E." surname="Lear"/>
    <date month="May" year="2026"/>
    <abstract>
      <t>The initial core schema for the System for Cross-domain Identity Management (SCIM) was designed for provisioning users. This memo specifies schema extensions that enable provisioning of devices using various underlying bootstrapping systems such as Wi-Fi Easy Connect, FIDO device onboarding vouchers, Bluetooth Low Energy (BLE) passcodes, and MAC Authenticated Bypass (MAB).</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9944"/>
  <seriesInfo name="DOI" value="10.17487/RFC9944"/>
</reference>

<reference anchor="I-D.ietf-asdf-sdf-protocol-mapping">
   <front>
      <title>SDF Protocol Mapping</title>
      <author fullname="Rohit Mohan" initials="R." surname="Mohan">
         <organization>Cisco Systems</organization>
      </author>
      <author fullname="Bart Brinckman" initials="B." surname="Brinckman">
         <organization>Cisco Systems</organization>
      </author>
      <author fullname="Lorenzo Corneo" initials="L." surname="Corneo">
         <organization>Ericsson</organization>
      </author>
      <date day="11" month="August" year="2026"/>
      <abstract>
	 <t>   This document defines protocol mapping extensions for the Semantic
   Definition Format (SDF) to enable mapping of protocol-agnostic SDF
   affordances to protocol-specific operations.  The protocol mapping
   mechanism allows SDF models to specify how properties, actions, and
   events should be accessed using a specific protocol.  This document
   defines protocol mappings for Bluetooth Low Energy and Zigbee, and
   the mechanism can be extended to other protocols such as HTTP and
   CoAP.  This document also describes a method to extend SCIM with an
   SDF model mapping.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-ietf-asdf-sdf-protocol-mapping-10"/>
   
</reference>
<reference anchor="RFC7644">
  <front>
    <title>System for Cross-domain Identity Management: Protocol</title>
    <author fullname="P. Hunt" initials="P." role="editor" surname="Hunt"/>
    <author fullname="K. Grizzle" initials="K." surname="Grizzle"/>
    <author fullname="M. Ansari" initials="M." surname="Ansari"/>
    <author fullname="E. Wahlstroem" initials="E." surname="Wahlstroem"/>
    <author fullname="C. Mortimore" initials="C." surname="Mortimore"/>
    <date month="September" year="2015"/>
    <abstract>
      <t>The System for Cross-domain Identity Management (SCIM) specification is an HTTP-based protocol that makes managing identities in multi-domain scenarios easier to support via a standardized service. Examples include, but are not limited to, enterprise-to-cloud service providers and inter-cloud scenarios. The specification suite seeks to build upon experience with existing schemas and deployments, placing specific emphasis on simplicity of development and integration, while applying existing authentication, authorization, and privacy models. SCIM's intent is to reduce the cost and complexity of user management operations by providing a common user schema, an extension model, and a service protocol defined by this document.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="7644"/>
  <seriesInfo name="DOI" value="10.17487/RFC7644"/>
</reference>
<reference anchor="RFC8259">
  <front>
    <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
    <author fullname="T. Bray" initials="T." role="editor" surname="Bray"/>
    <date month="December" year="2017"/>
    <abstract>
      <t>JavaScript Object Notation (JSON) is a lightweight, text-based, language-independent data interchange format. It was derived from the ECMAScript Programming Language Standard. JSON defines a small set of formatting rules for the portable representation of structured data.</t>
      <t>This document removes inconsistencies with other specifications of JSON, repairs specification errors, and offers experience-based interoperability guidance.</t>
    </abstract>
  </front>
  <seriesInfo name="STD" value="90"/>
  <seriesInfo name="RFC" value="8259"/>
  <seriesInfo name="DOI" value="10.17487/RFC8259"/>
</reference>
<reference anchor="RFC8949">
  <front>
    <title>Concise Binary Object Representation (CBOR)</title>
    <author fullname="C. Bormann" initials="C." surname="Bormann"/>
    <author fullname="P. Hoffman" initials="P." surname="Hoffman"/>
    <date month="December" year="2020"/>
    <abstract>
      <t>The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code size, fairly small message size, and extensibility without the need for version negotiation. These design goals make it different from earlier binary serializations such as ASN.1 and MessagePack.</t>
      <t>This document obsoletes RFC 7049, providing editorial improvements, new details, and errata fixes while keeping full compatibility with the interchange format of RFC 7049. It does not create a new version of the format.</t>
    </abstract>
  </front>
  <seriesInfo name="STD" value="94"/>
  <seriesInfo name="RFC" value="8949"/>
  <seriesInfo name="DOI" value="10.17487/RFC8949"/>
</reference>
<reference anchor="RFC2119">
  <front>
    <title>Key words for use in RFCs to Indicate Requirement Levels</title>
    <author fullname="S. Bradner" initials="S." surname="Bradner"/>
    <date month="March" year="1997"/>
    <abstract>
      <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="2119"/>
  <seriesInfo name="DOI" value="10.17487/RFC2119"/>
</reference>
<reference anchor="RFC8174">
  <front>
    <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
    <author fullname="B. Leiba" initials="B." surname="Leiba"/>
    <date month="May" year="2017"/>
    <abstract>
      <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="8174"/>
  <seriesInfo name="DOI" value="10.17487/RFC8174"/>
</reference>
<reference anchor="RFC7643">
  <front>
    <title>System for Cross-domain Identity Management: Core Schema</title>
    <author fullname="P. Hunt" initials="P." role="editor" surname="Hunt"/>
    <author fullname="K. Grizzle" initials="K." surname="Grizzle"/>
    <author fullname="E. Wahlstroem" initials="E." surname="Wahlstroem"/>
    <author fullname="C. Mortimore" initials="C." surname="Mortimore"/>
    <date month="September" year="2015"/>
    <abstract>
      <t>The System for Cross-domain Identity Management (SCIM) specifications are designed to make identity management in cloud-based applications and services easier. The specification suite builds upon experience with existing schemas and deployments, placing specific emphasis on simplicity of development and integration, while applying existing authentication, authorization, and privacy models. Its intent is to reduce the cost and complexity of user management operations by providing a common user schema and extension model as well as binding documents to provide patterns for exchanging this schema using HTTP.</t>
      <t>This document provides a platform-neutral schema and extension model for representing users and groups and other resource types in JSON format. This schema is intended for exchange and use with cloud service providers.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="7643"/>
  <seriesInfo name="DOI" value="10.17487/RFC7643"/>
</reference>
<reference anchor="RFC9110">
  <front>
    <title>HTTP Semantics</title>
    <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
    <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham"/>
    <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
    <date month="June" year="2022"/>
    <abstract>
      <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document describes the overall architecture of HTTP, establishes common terminology, and defines aspects of the protocol that are shared by all versions. In this definition are core protocol elements, extensibility mechanisms, and the "http" and "https" Uniform Resource Identifier (URI) schemes.</t>
      <t>This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230.</t>
    </abstract>
  </front>
  <seriesInfo name="STD" value="97"/>
  <seriesInfo name="RFC" value="9110"/>
  <seriesInfo name="DOI" value="10.17487/RFC9110"/>
</reference>
<reference anchor="RFC9457">
  <front>
    <title>Problem Details for HTTP APIs</title>
    <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
    <author fullname="E. Wilde" initials="E." surname="Wilde"/>
    <author fullname="S. Dalal" initials="S." surname="Dalal"/>
    <date month="July" year="2023"/>
    <abstract>
      <t>This document defines a "problem detail" to carry machine-readable details of errors in HTTP response content to avoid the need to define new error response formats for HTTP APIs.</t>
      <t>This document obsoletes RFC 7807.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9457"/>
  <seriesInfo name="DOI" value="10.17487/RFC9457"/>
</reference>
<reference anchor="RFC4648">
  <front>
    <title>The Base16, Base32, and Base64 Data Encodings</title>
    <author fullname="S. Josefsson" initials="S." surname="Josefsson"/>
    <date month="October" year="2006"/>
    <abstract>
      <t>This document describes the commonly used base 64, base 32, and base 16 encoding schemes. It also discusses the use of line-feeds in encoded data, use of padding in encoded data, use of non-alphabet characters in encoded data, use of different encoding alphabets, and canonical encodings. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="4648"/>
  <seriesInfo name="DOI" value="10.17487/RFC4648"/>
</reference>
<reference anchor="RFC3986">
  <front>
    <title>Uniform Resource Identifier (URI): Generic Syntax</title>
    <author fullname="T. Berners-Lee" initials="T." surname="Berners-Lee"/>
    <author fullname="R. Fielding" initials="R." surname="Fielding"/>
    <author fullname="L. Masinter" initials="L." surname="Masinter"/>
    <date month="January" year="2005"/>
    <abstract>
      <t>A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource. This specification defines the generic URI syntax and a process for resolving URI references that might be in relative form, along with guidelines and security considerations for the use of URIs on the Internet. The URI syntax defines a grammar that is a superset of all valid URIs, allowing an implementation to parse the common components of a URI reference without knowing the scheme-specific requirements of every possible identifier. This specification does not define a generative grammar for URIs; that task is performed by the individual specifications of each URI scheme. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="STD" value="66"/>
  <seriesInfo name="RFC" value="3986"/>
  <seriesInfo name="DOI" value="10.17487/RFC3986"/>
</reference>
<reference anchor="RFC6570">
  <front>
    <title>URI Template</title>
    <author fullname="J. Gregorio" initials="J." surname="Gregorio"/>
    <author fullname="R. Fielding" initials="R." surname="Fielding"/>
    <author fullname="M. Hadley" initials="M." surname="Hadley"/>
    <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
    <author fullname="D. Orchard" initials="D." surname="Orchard"/>
    <date month="March" year="2012"/>
    <abstract>
      <t>A URI Template is a compact sequence of characters for describing a range of Uniform Resource Identifiers through variable expansion. This specification defines the URI Template syntax and the process for expanding a URI Template into a URI reference, along with guidelines for the use of URI Templates on the Internet. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="6570"/>
  <seriesInfo name="DOI" value="10.17487/RFC6570"/>
</reference>
<reference anchor="RFC9562">
  <front>
    <title>Universally Unique IDentifiers (UUIDs)</title>
    <author fullname="K. Davis" initials="K." surname="Davis"/>
    <author fullname="B. Peabody" initials="B." surname="Peabody"/>
    <author fullname="P. Leach" initials="P." surname="Leach"/>
    <date month="May" year="2024"/>
    <abstract>
      <t>This specification defines UUIDs (Universally Unique IDentifiers) --
also known as GUIDs (Globally Unique IDentifiers) -- and a Uniform
Resource Name namespace for UUIDs. A UUID is 128 bits long and is
intended to guarantee uniqueness across space and time. UUIDs were
originally used in the Apollo Network Computing System (NCS), later
in the Open Software Foundation's (OSF's) Distributed Computing
Environment (DCE), and then in Microsoft Windows platforms.</t>
      <t>This specification is derived from the OSF DCE specification with the
kind permission of the OSF (now known as "The Open Group"). Information from earlier versions of the OSF DCE specification have
been incorporated into this document. This document obsoletes RFC
4122.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9562"/>
  <seriesInfo name="DOI" value="10.17487/RFC9562"/>
</reference>
<reference anchor="RFC7468">
  <front>
    <title>Textual Encodings of PKIX, PKCS, and CMS Structures</title>
    <author fullname="S. Josefsson" initials="S." surname="Josefsson"/>
    <author fullname="S. Leonard" initials="S." surname="Leonard"/>
    <date month="April" year="2015"/>
    <abstract>
      <t>This document describes and discusses the textual encodings of the Public-Key Infrastructure X.509 (PKIX), Public-Key Cryptography Standards (PKCS), and Cryptographic Message Syntax (CMS). The textual encodings are well-known, are implemented by several applications and libraries, and are widely deployed. This document articulates the de facto rules by which existing implementations operate and defines them so that future implementations can interoperate.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="7468"/>
  <seriesInfo name="DOI" value="10.17487/RFC7468"/>
</reference>
<reference anchor="RFC5246">
  <front>
    <title>The Transport Layer Security (TLS) Protocol Version 1.2</title>
    <author fullname="T. Dierks" initials="T." surname="Dierks"/>
    <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
    <date month="August" year="2008"/>
    <abstract>
      <t>This document specifies Version 1.2 of the Transport Layer Security (TLS) protocol. The TLS protocol provides communications security over the Internet. The protocol allows client/server applications to communicate in a way that is designed to prevent eavesdropping, tampering, or message forgery. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="5246"/>
  <seriesInfo name="DOI" value="10.17487/RFC5246"/>
</reference>
<reference anchor="RFC8446">
  <front>
    <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
    <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
    <date month="August" year="2018"/>
    <abstract>
      <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
      <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8446"/>
  <seriesInfo name="DOI" value="10.17487/RFC8446"/>
</reference>
<reference anchor="RFC6125">
  <front>
    <title>Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)</title>
    <author fullname="P. Saint-Andre" initials="P." surname="Saint-Andre"/>
    <author fullname="J. Hodges" initials="J." surname="Hodges"/>
    <date month="March" year="2011"/>
    <abstract>
      <t>Many application technologies enable secure communication between two entities by means of Internet Public Key Infrastructure Using X.509 (PKIX) certificates in the context of Transport Layer Security (TLS). This document specifies procedures for representing and verifying the identity of application services in such interactions. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="6125"/>
  <seriesInfo name="DOI" value="10.17487/RFC6125"/>
</reference>
<reference anchor="RFC7525">
  <front>
    <title>Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)</title>
    <author fullname="Y. Sheffer" initials="Y." surname="Sheffer"/>
    <author fullname="R. Holz" initials="R." surname="Holz"/>
    <author fullname="P. Saint-Andre" initials="P." surname="Saint-Andre"/>
    <date month="May" year="2015"/>
    <abstract>
      <t>Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) are widely used to protect data exchanged over application protocols such as HTTP, SMTP, IMAP, POP, SIP, and XMPP. Over the last few years, several serious attacks on TLS have emerged, including attacks on its most commonly used cipher suites and their modes of operation. This document provides recommendations for improving the security of deployed services that use TLS and DTLS. The recommendations are applicable to the majority of use cases.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="7525"/>
  <seriesInfo name="DOI" value="10.17487/RFC7525"/>
</reference>
<reference anchor="RFC7230">
  <front>
    <title>Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing</title>
    <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
    <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
    <date month="June" year="2014"/>
    <abstract>
      <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document provides an overview of HTTP architecture and its associated terminology, defines the "http" and "https" Uniform Resource Identifier (URI) schemes, defines the HTTP/1.1 message syntax and parsing requirements, and describes related security concerns for implementations.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="7230"/>
  <seriesInfo name="DOI" value="10.17487/RFC7230"/>
</reference>
<reference anchor="RFC6749">
  <front>
    <title>The OAuth 2.0 Authorization Framework</title>
    <author fullname="D. Hardt" initials="D." role="editor" surname="Hardt"/>
    <date month="October" year="2012"/>
    <abstract>
      <t>The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf. This specification replaces and obsoletes the OAuth 1.0 protocol described in RFC 5849. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="6749"/>
  <seriesInfo name="DOI" value="10.17487/RFC6749"/>
</reference>
<reference anchor="RFC7521">
  <front>
    <title>Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants</title>
    <author fullname="B. Campbell" initials="B." surname="Campbell"/>
    <author fullname="C. Mortimore" initials="C." surname="Mortimore"/>
    <author fullname="M. Jones" initials="M." surname="Jones"/>
    <author fullname="Y. Goland" initials="Y." surname="Goland"/>
    <date month="May" year="2015"/>
    <abstract>
      <t>This specification provides a framework for the use of assertions with OAuth 2.0 in the form of a new client authentication mechanism and a new authorization grant type. Mechanisms are specified for transporting assertions during interactions with a token endpoint; general processing rules are also specified.</t>
      <t>The intent of this specification is to provide a common framework for OAuth 2.0 to interwork with other identity systems using assertions and to provide alternative client authentication mechanisms.</t>
      <t>Note that this specification only defines abstract message flows and processing rules. In order to be implementable, companion specifications are necessary to provide the corresponding concrete instantiations.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="7521"/>
  <seriesInfo name="DOI" value="10.17487/RFC7521"/>
</reference>
<reference anchor="RFC6750">
  <front>
    <title>The OAuth 2.0 Authorization Framework: Bearer Token Usage</title>
    <author fullname="M. Jones" initials="M." surname="Jones"/>
    <author fullname="D. Hardt" initials="D." surname="Hardt"/>
    <date month="October" year="2012"/>
    <abstract>
      <t>This specification describes how to use bearer tokens in HTTP requests to access OAuth 2.0 protected resources. Any party in possession of a bearer token (a "bearer") can use it to get access to the associated resources (without demonstrating possession of a cryptographic key). To prevent misuse, bearer tokens need to be protected from disclosure in storage and in transport. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="6750"/>
  <seriesInfo name="DOI" value="10.17487/RFC6750"/>
</reference>
<reference anchor="RFC6819">
  <front>
    <title>OAuth 2.0 Threat Model and Security Considerations</title>
    <author fullname="T. Lodderstedt" initials="T." role="editor" surname="Lodderstedt"/>
    <author fullname="M. McGloin" initials="M." surname="McGloin"/>
    <author fullname="P. Hunt" initials="P." surname="Hunt"/>
    <date month="January" year="2013"/>
    <abstract>
      <t>This document gives additional security considerations for OAuth, beyond those in the OAuth 2.0 specification, based on a comprehensive threat model for the OAuth 2.0 protocol. This document is not an Internet Standards Track specification; it is published for informational purposes.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="6819"/>
  <seriesInfo name="DOI" value="10.17487/RFC6819"/>
</reference>
<reference anchor="RFC6265">
  <front>
    <title>HTTP State Management Mechanism</title>
    <author fullname="A. Barth" initials="A." surname="Barth"/>
    <date month="April" year="2011"/>
    <abstract>
      <t>This document defines the HTTP Cookie and Set-Cookie header fields. These header fields can be used by HTTP servers to store state (called cookies) at HTTP user agents, letting the servers maintain a stateful session over the mostly stateless HTTP protocol. Although cookies have many historical infelicities that degrade their security and privacy, the Cookie and Set-Cookie header fields are widely used on the Internet. This document obsoletes RFC 2965. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="6265"/>
  <seriesInfo name="DOI" value="10.17487/RFC6265"/>
</reference>
<reference anchor="RFC8126">
  <front>
    <title>Guidelines for Writing an IANA Considerations Section in RFCs</title>
    <author fullname="M. Cotton" initials="M." surname="Cotton"/>
    <author fullname="B. Leiba" initials="B." surname="Leiba"/>
    <author fullname="T. Narten" initials="T." surname="Narten"/>
    <date month="June" year="2017"/>
    <abstract>
      <t>Many protocols make use of points of extensibility that use constants to identify various protocol parameters. To ensure that the values in these fields do not have conflicting uses and to promote interoperability, their allocations are often coordinated by a central record keeper. For IETF protocols, that role is filled by the Internet Assigned Numbers Authority (IANA).</t>
      <t>To make assignments in a given registry prudently, guidance describing the conditions under which new values should be assigned, as well as when and how modifications to existing values can be made, is needed. This document defines a framework for the documentation of these guidelines by specification authors, in order to assure that the provided guidance for the IANA Considerations is clear and addresses the various issues that are likely in the operation of a registry.</t>
      <t>This is the third edition of this document; it obsoletes RFC 5226.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="26"/>
  <seriesInfo name="RFC" value="8126"/>
  <seriesInfo name="DOI" value="10.17487/RFC8126"/>
</reference>
<reference anchor="IANA.media-types" target="https://www.iana.org/assignments/media-types">
  <front>
    <title>Media Types</title>
    <author>
      <organization>IANA</organization>
    </author>
  </front>
</reference>
<reference anchor="IANA.well-known-uris" target="https://www.iana.org/assignments/well-known-uris">
  <front>
    <title>Well-Known URIs</title>
    <author>
      <organization>IANA</organization>
    </author>
  </front>
</reference>
<reference anchor="RFC8615">
  <front>
    <title>Well-Known Uniform Resource Identifiers (URIs)</title>
    <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
    <date month="May" year="2019"/>
    <abstract>
      <t>This memo defines a path prefix for "well-known locations", "/.well-known/", in selected Uniform Resource Identifier (URI) schemes.</t>
      <t>In doing so, it obsoletes RFC 5785 and updates the URI schemes defined in RFC 7230 to reserve that space. It also updates RFC 7595 to track URI schemes that support well-known URIs in their registry.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8615"/>
  <seriesInfo name="DOI" value="10.17487/RFC8615"/>
</reference>



    </references>

    <references title='Informative References' anchor="sec-informative-references">

<reference anchor="BLE53" >
  <front>
    <title>Bluetooth Core Specification, Version 5.3</title>
    <author >
      <organization>Bluetooth SIG</organization>
    </author>
    <date year="2021"/>
  </front>
</reference>
<reference anchor="Zigbee22" >
  <front>
    <title>Zigbee Specification, Version 22 1.0</title>
    <author >
      <organization>Connectivity Standards Alliance</organization>
    </author>
    <date year="2017"/>
  </front>
</reference>
<reference anchor="Gatt-REST-API" target="https://www.bluetooth.com/bluetooth-resources/gatt-rest-api/">
  <front>
    <title>A RESTful API used to access data in devices using the functionality defined in the Bluetooth GATT profile</title>
    <author >
      <organization>Bluetooth SIG</organization>
    </author>
    <date year="2017"/>
  </front>
</reference>


<reference anchor="RFC7252">
  <front>
    <title>The Constrained Application Protocol (CoAP)</title>
    <author fullname="Z. Shelby" initials="Z." surname="Shelby"/>
    <author fullname="K. Hartke" initials="K." surname="Hartke"/>
    <author fullname="C. Bormann" initials="C." surname="Bormann"/>
    <date month="June" year="2014"/>
    <abstract>
      <t>The Constrained Application Protocol (CoAP) is a specialized web transfer protocol for use with constrained nodes and constrained (e.g., low-power, lossy) networks. The nodes often have 8-bit microcontrollers with small amounts of ROM and RAM, while constrained networks such as IPv6 over Low-Power Wireless Personal Area Networks (6LoWPANs) often have high packet error rates and a typical throughput of 10s of kbit/s. The protocol is designed for machine- to-machine (M2M) applications such as smart energy and building automation.</t>
      <t>CoAP provides a request/response interaction model between application endpoints, supports built-in discovery of services and resources, and includes key concepts of the Web such as URIs and Internet media types. CoAP is designed to easily interface with HTTP for integration with the Web while meeting specialized requirements such as multicast support, very low overhead, and simplicity for constrained environments.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="7252"/>
  <seriesInfo name="DOI" value="10.17487/RFC7252"/>
</reference>
<reference anchor="RFC7942">
  <front>
    <title>Improving Awareness of Running Code: The Implementation Status Section</title>
    <author fullname="Y. Sheffer" initials="Y." surname="Sheffer"/>
    <author fullname="A. Farrel" initials="A." surname="Farrel"/>
    <date month="July" year="2016"/>
    <abstract>
      <t>This document describes a simple process that allows authors of Internet-Drafts to record the status of known implementations by including an Implementation Status section. This will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature.</t>
      <t>This process is not mandatory. Authors of Internet-Drafts are encouraged to consider using the process for their documents, and working groups are invited to think about applying the process to all of their protocol specifications. This document obsoletes RFC 6982, advancing it to a Best Current Practice.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="205"/>
  <seriesInfo name="RFC" value="7942"/>
  <seriesInfo name="DOI" value="10.17487/RFC7942"/>
</reference>



    </references>

</references>


<?line 3054?>

<section anchor="openapi-definition"><name>OpenAPI definition</name>

<t>The following non-normative model is provided for convenience of the implementer.</t>

<figure anchor="openAPI"><artwork markers="true" name="NIPC.yaml"><![CDATA[
<CODE BEGINS> file "openapi.yml"
=============== NOTE: '\' line wrapping per RFC 8792 ================

# yaml-language-server: $schema=https://json-schema.org/draft/2020-\
                                                            12/schema
openapi: 3.0.3
info:
  title: Non IP Device Control (NIPC) API
  description: |-
    This API specifies RESTful application layer interface for
    gateways providing operations against non-IP devices. The
    described interface is extensible. The examples includes
    leverage Bluetooth Low Energy and Zigbee as they are commonly
    deployed.
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.21.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-21"
    variables:
      gw_host:
        default: localhost
        description: Gateway Host
tags:
  - name: NIPC property APIs
    description: |-
      APIs that allow apps to get and update device properties.
      If the underlying protocol requires connection management, it
      will be performed as part of the API call.
  - name: NIPC event APIs
    description: |-
      APIs that allow apps to enable or disable event reporting on
      devices. If the underlying protocol requires connection
      management, it will be performed as part of the API call.
  - name: NIPC action APIs
    description: |-
      APIs that perform actions on devices or groups.
  - name: NIPC trigger APIs
    description: |-
      APIs that install triggers on actions and events for devices 
      or groups. A trigger always triggers an action. 
  - name: NIPC management APIs
    description: |-
      APIs that manage device connections.
  - name: NIPC registration APIs
    description: |-
      APIs that register sdf models or data applications

paths:
### NIPC Property APIs
  /devices/{id}/properties:
    put:
      tags:
        - NIPC property APIs
      summary: Update a value of one or more properties on a device
      description: |-
        Write a value to a property or multiple properties to a
        device. If underlying protocol requires a connection to be
        set up, this API call will perform the necessary connection
        management. If a connection is already active for this
        device, the existing connection will be leveraged without
        modifying it.
      operationId: UpdateProperties
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: propertyName
        in: query
        description: |-
          The SDF property name that needs to be written to.
        required: false
        allowReserved: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                  thermostat/sdfProperty/temperature"
      requestBody:
        description: |-
          The value to be written to the property or properties.
          If multiple properties are specified, the request body
          should be application/nipc+json.
        content:
          application/nipc+json:
            schema:
              $ref: '#/components/schemas/PropertyValueArray'
          "*/*":
            schema:
              description: |-
                Any other content type, such as 
                application/octet-stream, application/json that will 
                be written to the device.
        required: true
      responses:
        '204':
          description: |-
            Success, no content, used for a single property write
        '200':
          description: Success, used for multiple property writes
          content:
            application/nipc+json:
              schema:
                allOf: 
                  - $ref: '#/components/schemas/\
                                          PropertyValueResponseArray'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - NIPC property APIs
      summary: |-
        Read a value from one or multiple properties on a device
      description: |-
        Read a value to a property or multiple properties from a
        device. If underlying protocol requires a connection to be
        set up, this API call will perform the necessary connection
        management. If a connection is already active for this
        device, the existing connection will be leveraged without
        modifying it. 
      operationId: GetProperties
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: propertyName
        in: query
        description: Properties to be read
        required: true
        allowReserved: true
        schema:
          type: array
          items:
            type: string
            example: "https://example.com/heartrate#/sdfObject/\
                                  thermostat/sdfProperty/temperature"
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf: 
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/\
                                      PropertyValueReadResponseArray'
            "*/*":
              schema:
                type: string
                description: |-
                  Any other content type, such as
                  application/octet-stream, application/json that 
                  will be read from the device.
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
 
 ### NIPC Event APIs
  /devices/{id}/events:
    post:
      tags:
        - NIPC event APIs
      summary: Enable an event on a specific device
      description: |-
        Enable an event on a specific device or for a group of
        devices. If the underlying protocol requires a connection to
        be set up, this API call will perform the necessary
        connection management. If a connection is already active for
        this device, the existing connection will be leveraged
        without modifying it.
      operationId: EnableEvent
      parameters:
      - name: id
        in: path
        description: The ID of the device.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: eventName
        in: query
        description: event that needs to be enabled
        required: true
        allowReserved: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                  healthsensor/sdfEvent/fallDetected"
      responses:
        '201':
          description: Success
          headers:
            Location:
              description: Location of the created event
              schema:
                type: string
                format: uri
                example: "/devices/{id}/events?instanceId={\
                                                         instanceId}"
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    delete:
      tags:
        - NIPC event APIs
      summary: Disable an event on a specific device
      description: |-
        Disable an event on a specific device or a group of devices.
        If the underlying protocol requires a connection to be set
        up, this API call will perform the necessary connection
        management. If a connection is already active for this
        device, the existing connection will be leveraged without
        modifying it.
      operationId: DisableEvent
      parameters:
      - name: id
        in: path
        description: The ID of the device.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: instanceId
        in: query
        description: instance id of the event that needs to be \
                                                             disabled
        required: true
        schema:
          type: string
          format: uuid
          example: 02ee282c-8915-4b2e-bbd2-88966773134a
      responses:
        '204':
          description: Success, no content
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
               
    get:
      tags:
        - NIPC event APIs
      summary: Get status of events on a device
      description: |-
        Get status of an event or multiple events on a specific \
                                                               device
      operationId: GetEvents
      parameters:
      - name: id
        in: path
        description: The ID of the device.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: instanceId
        in: query
        description: |-
          Instance ID of the events that need to be filtered
        required: false
        schema:
          type: array
          items:
            type: string
            format: uuid
            example: 02ee282c-8915-4b2e-bbd2-88966773134a
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                $ref: '#/components/schemas/EventStatusResponseArray'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /groups/{id}/events:
    post:
      tags:
        - NIPC event APIs
      summary: Enable an event on a group of devices
      description: |-
        Enable an event on a group of devices.
        If the underlying protocol requires a connection to be set
        up, this API call will perform the necessary connection
        management. If a connection is already active for this
        device, the existing connection will be leveraged without
        modifying it.
      operationId: EnableGroupEvent
      parameters:
      - name: id
        in: path
        description: |-
          group id for which the event needs to be enabled
        required: true
        schema:
          type: string
          format: uuid
          example: 0dc729d7-f6c3-491d-9b9d-e7176d2be243
      - name: eventName
        in: query
        description: event that needs to be enabled
        required: true
        allowReserved: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                  healthsensor/sdfEvent/fallDetected"
      responses:
        '201':
          description: Success, event enabled
          headers:
            Location:
              description: Location of the created event
              schema:
                type: string
                format: uri
                example: "/groups/{id}/events?instanceId={instanceId\
                                                                   }"
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
    delete:
      tags:
        - NIPC event APIs
      summary: Disable an event on a group of devices
      description: |-
        Disable an event on a group of devices. If the underlying
        protocol requires a connection to be set up, this API call
        will perform the necessary connection management.
        If a connection is already active for this device, the
        existing connection will be leveraged without modifying it.
      operationId: DisableGroupEvent
      parameters:
      - name: id
        in: path
        description: |-
          group id for which the event needs to be disabled
        required: true
        schema:
          type: string
          format: uuid
          example: 0dc729d7-f6c3-491d-9b9d-e7176d2be243
      - name: instanceId
        in: query
        description: instance id of the event that needs to be \
                                                             disabled
        required: true
        schema:
          type: string
          format: uuid
          example: f1b9f26b-21ce-4deb-9d57-289ba7e17cce
      responses:
        '200':
          description: Success, event disabled
          content:
            application/nipc+json:
              schema:
                $ref: '#/components/schemas/\
                                       GroupEventStatusResponseArray'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
    get:
      tags:
        - NIPC event APIs
      summary: Get status of events on a group of devices
      description: |-
        Get status of an event or multiple events on a group of \
                                                             devices.
      operationId: GetGroupEvents
      parameters:
      - name: id
        in: path
        description: group id of the SCIM group
        required: true
        schema:
          type: string
          format: uuid
          example: 0dc729d7-f6c3-491d-9b9d-e7176d2be243
      - name: instanceId
        in: query
        description: |-
          Instance IDs of the events that need to be filtered
        required: false
        schema:
          type: string
          format: uuid
          example: f1b9f26b-21ce-4deb-9d57-289ba7e17cce
      responses:
        '200':
          description: Success, events retrieved
          content:
            application/nipc+json:
              schema:
                $ref: '#/components/schemas/\
                                       GroupEventStatusResponseArray'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

### NIPC action APIs
  /devices/{id}/actions:
    post:
      tags:
        - NIPC action APIs
      summary: Perform an action on a device
      description: |-
        Perform an action on a device.
        If the underlying protocol requires a connection to be set
        up, this API call will perform the necessary connection
        management. If a connection is already active for this
        device, the existing connection will be leveraged without
        modifying it.
      operationId: ActionProperty
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: actionName
        in: query
        description: action that needs to be performed
        required: true
        allowReserved: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                        healthsensor/sdfAction/start"
      requestBody:
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
        required: false
      responses:
        '202':
          description: Accepted, action is being performed
          headers:
            Location:
              description: Location of the action
              schema:
                type: string
                format: uri
                example: "/devices/{id}/actions?instanceId={\
                                                         instanceId}"
            Retry-After:
              description: |-
                Number of seconds to wait before polling the status \
                                                       endpoint again
              schema:
                type: integer
                example: 5
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
    get:
      tags:
        - NIPC action APIs
      summary: Get status of an action on a device
      description: |-
        Get status of an action on a specific device or a group of
        devices. Success is action is active, failure if action not
        active.
      operationId: GetAction
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: instanceId
        in: query
        description: |-
          instance id of the action that needs to be checked
        required: true
        schema:
          type: string
          format: uuid
          example: 02ee282c-8915-4b2e-bbd2-88966773134a
      responses:
        '200':
          description: Success, action is active
          content:
            application/nipc+json:
              schema:
                $ref: '#/components/schemas/ActionResponse'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /groups/{id}/actions:
    post:
      tags:
        - NIPC action APIs
      summary: Perform an action on a group
      description: |-
        Perform an action on a group of decvices
        If the underlying protocol requires a connection to be set
        up, this API call will perform the necessary connection
        management. If a connection is already active for this
        device, the existing connection will be leveraged without
        modifying it.
      operationId: ActionGroupProperty
      parameters:
      - name: id
        in: path
        description: The ID of the group. 
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: actionName
        in: query
        description: action that needs to be performed
        required: true
        allowReserved: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                        healthsensor/sdfAction/start"
      requestBody:
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
        required: false
      responses:
        '202':
          description: Accepted, action is being performed
          headers:
            Location:
              description: Location of the action
              schema:
                type: string
                format: uri
                example: "/groups/{id}/actions?instanceId={\
                                                         instanceId}"
            Retry-After:
              description: |-
                Number of seconds to wait before polling the status \
                                                       endpoint again
              schema:
                type: integer
                example: 5
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
    get:
      tags:
        - NIPC action APIs
      summary: Get status of an action on a group
      description: |-
        Get status of an action on a specific group of
        devices. Success is action is active, failure if action not
        active.
      operationId: GetGroupAction
      parameters:
      - name: id
        in: path
        description: The ID of the group of devices.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: instanceId
        in: query
        description: |-
          instance id of the action that needs to be checked
        required: true
        schema:
          type: string
          format: uuid
          example: 02ee282c-8915-4b2e-bbd2-88966773134a
      responses:
        '200':
          description: Success, action is active
          content:
            application/nipc+json:
              schema:
                $ref: '#/components/schemas/\
                                      GroupActionStatusResponseArray'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

### NIPC Trigger APIs
  /devices/{id}/triggers:
    post:
      tags:
        - NIPC trigger APIs
      summary: create a trigger on an affordance of a device
      description: |-
        Creates a trigger on an affordance of a device. A trigger 
        will trigger an action on another device or a group of \
                                                              devices
      operationId: CreateDeviceTrigger
      parameters:
      - name: id
        in: path
        description: The ID of the device.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: eventName
        in: query
        description: |-
          The SDF global name of the event that will trigger this \
                                                               action
        required: true
        allowReserved: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                  healthsensor/sdfEvent/fallDetected"
      requestBody:
        description: |-
          The NIPC API call to be called when the trigger is 
          executed.
        content:
          application/nipc+json:
            schema:
              $ref: '#/components/schemas/Action'
        required: true
      responses:
        '201':
          description: Success
          headers:
            Location:
              description: Location of the created trigger
              schema:
                type: string
                format: uri
                example: "/devices/{id}/triggers?instanceId={\
                                                         instanceId}"
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - NIPC trigger APIs
      summary: Get information about a trigger or all triggers
      description: |-
        Get information about a trigger for a device or all triggers 
        if none specified
      operationId: GetDeviceTrigger
      parameters:
      - name: id
        in: path
        description: The ID of the device. 
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: instanceId
        in: query
        description: |-
          instance id of the trigger that needs to be checked
        required: false
        schema:
          type: string
          format: uuid
          example: 02ee282c-8915-4b2e-bbd2-88966773134a
      responses:
        '200':
          description: Success, action is active
          content:
            application/nipc+json:
              schema:
                $ref: '#/components/schemas/\
                                          TriggerStatusResponseArray'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    delete:
      tags:
        - NIPC trigger APIs
      summary: Delete a trigger or all triggers for a device
      description: |-
        Delete a trigger for a device or all triggers 
        if none specified
      operationId: DeleteDeviceTrigger
      parameters:
      - name: id
        in: path
        description: The ID of the device. 
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: instanceId
        in: query
        description: |-
          instance id of the trigger that needs to be checked
        required: false
        schema:
          type: string
          format: uuid
          example: 02ee282c-8915-4b2e-bbd2-88966773134a
      responses:
        '204':
          description: Success, no content
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /groups/{id}/triggers:
    post:
      tags:
        - NIPC trigger APIs
      summary: create a trigger on an affordance of a group
      description: |-
        Creates a trigger on an affordance of a group of devices. A \
                                                             trigger 
        will trigger an action on a device or a group of devices
      operationId: CreateGroupTrigger
      parameters:
      - name: id
        in: path
        description: The ID of the group
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: eventName
        in: query
        description: |-
          The SDF global name of the event that will trigger this \
                                                               action
        required: true
        allowReserved: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                  healthsensor/sdfEvent/fallDetected"
      requestBody:
        description: |-
          The NIPC API call to be called when the trigger is 
          executed, as well as the device or group it is to be \
                                                    executed against.
        content:
          application/nipc+json:
            schema:
              $ref: '#/components/schemas/Action'
        required: true
      responses:
        '201':
          description: Success
          headers:
            Location:
              description: Location of the created trigger
              schema:
                type: string
                format: uri
                example: "/groups/{id}/triggers?instanceId={\
                                                         instanceId}"
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
    get:
      tags:
        - NIPC trigger APIs
      summary: Get information about a trigger or all triggers
      description: |-
        Get information about a trigger or all triggers 
        if none specified
      operationId: GetGroupTrigger
      parameters:
      - name: id
        in: path
        description: The ID of the group
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: instanceId
        in: query
        description: |-
          instance id of the trigger that needs to be checked
        required: false
        schema:
          type: string
          format: uuid
          example: 02ee282c-8915-4b2e-bbd2-88966773134a
      responses:
        '200':
          description: Success, action is active
          content:
            application/nipc+json:
              schema:
                $ref: '#/components/schemas/\
                                     GroupTriggerStatusResponseArray'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    delete:
      tags:
        - NIPC trigger APIs
      summary: Delete a trigger or all triggers for a grou of devices
      description: |-
        Delete a trigger for a group of devices or all triggers 
        for a group of devices if none specified
      operationId: DeleteGroupTrigger
      parameters:
      - name: id
        in: path
        description: The ID of the group of devices. 
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: instanceId
        in: query
        description: |-
          instance id of the trigger that needs to be checked
        required: false
        schema:
          type: string
          format: uuid
          example: 02ee282c-8915-4b2e-bbd2-88966773134a
      responses:
        '204':
          description: Success, no content
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

### NIPC management APIs               
  /devices/{id}/connections:
    post:
      tags:
        - NIPC management APIs
      summary: Connect a device
      description: |-
        Connect a device. 3 retries by default, optionally retry
        policy can be defined in the API body. If the protocol
        requires service discovery, full service discovery will be
        performed, unless specific services are described in the API
        body.
      operationId: ActionCreateConnection
      parameters:
        - name: id
          in: path
          description: The ID of the device. Group ID is not allowed.
          required: true
          schema:
            type: string
            format: uuid
            example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      requestBody:
        content:
          application/nipc+json:
            schema:
              anyOf:
                - $ref: '#/components/schemas/Connection'
                - $ref: './protocolinfo/ProtocolInfo.yaml#/\
                          components/schemas/ProtocolInfo-ServiceMap'
            example:
              retries: 3
              protocolInformation:
                ble:
                  services:
                    - serviceID: "00001809-0000-1000-8000-\
                                                        00805f9b34fb"
                  cached: true
                  cacheExpiryDuration: 3600
        required: false
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: './protocolinfo/ProtocolInfo.yaml#/\
                          components/schemas/ProtocolInfo-ServiceMap'
              example:
                id: "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
                protocolInformation:
                  ble:
                    services:
                      - serviceID: "00001809-0000-1000-8000-\
                                                        00805f9b34fb"
                        characteristics:
                          - characteristicID: "00002a19-0000-1000-\
                                                   8000-00805f9b34fb"
                            flags: ["read", "notify"]
                            descriptors:
                              - descriptorID: "00002902-0000-1000-\
                                                   8000-00805f9b34fb"
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
  
    put:
      tags:
        - NIPC management APIs
      summary: Update cached ServiceMap for a device.
      description: |-
        Update cached ServiceMap for a device. Full service discovery
        will be performed, unless specific services are described in
        the API body.
      operationId: ActionUpdateServiceMap
      parameters:
        - name: id
          in: path
          description: The ID of the device. Group ID is not allowed.
          required: true
          schema:
            type: string
            format: uuid
            example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      requestBody:
        content:
          application/nipc+json:
            schema:
              $ref: './protocolinfo/ProtocolInfo.yaml#/components/\
                                     schemas/ProtocolInfo-ServiceMap'
            example:
              retries: 3
              protocolInformation:
                ble:
                  services:
                    - serviceID: "00001809-0000-1000-8000-\
                                                        00805f9b34fb"
                  cached: true
                  cacheExpiryDuration: 3600
        required: false
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: './protocolinfo/ProtocolInfo.yaml#/\
                          components/schemas/ProtocolInfo-ServiceMap'
              example:
                id: "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
                protocolInformation:
                  ble:
                    services:
                      - serviceID: "00001809-0000-1000-8000-\
                                                        00805f9b34fb"
                        characteristics:
                          - characteristicID: "00002a19-0000-1000-\
                                                   8000-00805f9b34fb"
                            flags: ["read", "notify"]
                            descriptors:
                              - descriptorID: "00002902-0000-1000-\
                                                   8000-00805f9b34fb"
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
  
    delete:
      tags:
        - NIPC management APIs
      summary: Disconnect a device 
      description: |-
        Disconnect a device.
      operationId: ActionDeleteConnection
      parameters:
        - name: id
          in: path
          description: The ID of the device. Group ID is not allowed.
          required: true
          schema:
            type: string
            format: uuid
            example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      responses:
        '204':
          description: Success, no content
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
                  
    get:
      tags:
        - NIPC management APIs
      summary: Get connection state for a device
      description: |-
        Get connection status for a device. Success when device(s)
        is/are connected, includes service map for the device if
        available. Failure when a device is not connected
      operationId: ActionGetConnection
      parameters:
        - name: id
          in: path
          description: The ID of the device. Group ID is not allowed.
          required: true
          schema:
            type: string
            format: uuid
            example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: './protocolinfo/ProtocolInfo.yaml#/\
                          components/schemas/ProtocolInfo-ServiceMap'
              example:
                id: "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
                protocolInformation:
                  ble:
                    services:
                      - serviceID: "00001809-0000-1000-8000-\
                                                        00805f9b34fb"
                        characteristics:
                          - characteristicID: "00002a19-0000-1000-\
                                                   8000-00805f9b34fb"
                            flags: ["read", "notify"]
                            descriptors:
                              - descriptorID: "00002902-0000-1000-\
                                              8000-00805f9b34fb"     
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailureResponse'


### Registrations
  /registrations/models:
    post:
      tags:
        - NIPC registration APIs
      summary: Register an sdfObject
      description: |-
        Register an sdfObject, including Properties, Events and
        actions
      operationId: registerSdfObject
      requestBody:
        content:
          application/sdf+json:
            schema:
              $ref: '#/components/schemas/SdfModel'
        required: true
      responses:
        '201':
          description: Created
          content:
            application/nipc+json:
              schema:
                type: array
                items:
                  allOf:
                    - $ref: '#/components/schemas/SdfReference'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - NIPC registration APIs
      summary: Get registered SDF models
      description: |-
        Without sdfName, returns a list of all registered SDF model
        references. With sdfName, returns the full SDF model for that
        name.
      operationId: getSdfRefs
      parameters:
        - name: sdfName
          in: query
          description: |-
            sdfName can be a reference to an sdfThing or sdfObject.
            If omitted, all registered model references are returned.
          required: false
          allowReserved: true
          schema:
            type: string
            example: "https://example.com/heartrate#/sdfObject/\
                                                        healthsensor"
      responses:
        '200':
          description: |-
            Without sdfName, returns a list of SDF model references.
            With sdfName, returns the full SDF model.
          content:
            application/sdf+json:
              schema:
                oneOf:
                  - type: array
                    items:
                      $ref: '#/components/schemas/SdfReference'
                  - $ref: '#/components/schemas/SdfModel'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
    put:
      tags:
        - NIPC registration APIs
      summary: Update an SDF model
      description: |-
        Update an SDF model, including Properties, Events and
        actions
      operationId: updateSdf
      parameters:
        - name: sdfName
          in: query
          description: |-
            sdfName can be a reference to an sdfThing or sdfObject
          required: true
          allowReserved: true
          schema:
            type: string
            example: "https://example.com/heartrate#/sdfObject/\
                                                        healthsensor"
      requestBody:
        content:
          application/sdf+json:
            schema:
              $ref: '#/components/schemas/SdfModel'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SdfReference'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
 
    delete:
      tags:
        - NIPC registration APIs
      summary: Delete an sdfObject
      description: |-
        Delete an sdfObject, including Properties, Events and
        actions
      operationId: deleteSdfObject
      parameters:
        - name: sdfName
          in: query
          description: sdfObject name
          required: true
          schema:
            type: string
            example: "https://example.com/heartrate#/sdfObject/\
                                                        healthsensor"
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SdfReference'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'

  /registrations/data-apps:
    post:
      tags:
        - NIPC registration APIs
      summary: Register a dataApp
      description: |-
        Register a dataApp that is able to receive device data. 
      operationId: registerDataApp
      parameters:
        - name: dataAppId
          in: query
          description: id of the data app that will be registered
          required: true
          schema:
            type: string
            format: uuid
            example: 0927ce7c-b258-4bfa-a345-bcc9f74385b4
      requestBody:
        content:
          application/nipc+json:
            schema:
              $ref: '#/components/schemas/DataApp'
        required: true
      responses:
        '201':
          description: Created
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/DataApp'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'

    put:
      tags:
        - NIPC registration APIs
      summary: Update registration of a dataApp
      description: |-
        Update registration of a dataApp that is able to receive \
                                                        device data. 
      operationId: UpdateDataApp
      parameters:
        - name: dataAppId
          in: query
          description: id of the data app that will be updated
          required: true
          schema:
            type: string
            format: uuid
            example: 0927ce7c-b258-4bfa-a345-bcc9f74385b4
      requestBody:
        content:
          application/nipc+json:
            schema:
              $ref: '#/components/schemas/DataApp'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/DataApp'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  
    delete:
      tags:
        - NIPC registration APIs
      summary: Delete registration of a dataApp
      description: |-
        Delete registration of a dataApp that is able to receive
        device data. 
      operationId: DeleteDataApp
      parameters:
        - name: dataAppId
          in: query
          description: id of the data app that will be updated
          required: true
          schema:
            type: string
            format: uuid
            example: 0927ce7c-b258-4bfa-a345-bcc9f74385b4
      responses:
        '204':
          description: Success, no content
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
  
    get:
      tags:
        - NIPC registration APIs
      summary: Get registration of a dataApp
      description: |-
        Get registrationdetails of a dataApp that is able to receive
        device data. 
      operationId: GetDataApp
      parameters:
        - name: dataAppId
          in: query
          description: id of the data app that will be updated
          required: true
          schema:
            type: string
            format: uuid
            example: 0927ce7c-b258-4bfa-a345-bcc9f74385b4
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/DataApp'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'

components:
  schemas:
# Base objects
## A SCIM id, can be a device or a group
    Id:
      required:
        - id
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: |-
            A SCIM-generated UUID, can be a device or group
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30

## A property
    Property:
      required:
        - property
      type: object
      properties:
        property:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                  thermostat/sdfProperty/temperature"

## A value
    Value:
      required:
        - value
      type: object
      properties:
        value:
          type: string
          format: byte
          example: dGVzdA==

## A value of an property of an Device
    PropertyValue:
      allOf:
        - $ref: '#/components/schemas/Property'
        - $ref: '#/components/schemas/Value'

## An array of Property values
    PropertyValueArray:
      type: array
      items:
        $ref: '#/components/schemas/PropertyValue'

## Event
    Event:
      required:
        - event
      type: object
      properties:
        event:
          type: string
          description: |-
            percent-encoded JSON pointer to the SDF event object
          example: https://example.com/heartrate#/sdfObject/\
                                   healthsensor/sdfEvent/fallDetected

    InstanceId:
      type: object
      properties:
        instanceId:
          type: string
          format: uuid
          description: |-
            A SCIM-generated UUID for the event instance
          example: 02ee282c-8915-4b2e-bbd2-88966773134a

## An Action
    Action:
      type: object
      properties:
        action:
          type: string
          description: |-
            NIPC action operation to execute
          example: /devices/3171ec43-42a5-4415-ab4b-afd0dfbe9615/\
actions?actionName=https%3A%2F%2Fexample.com%2FAlarmSystem%23%\
                                2FsdfObject%2Fbell%2FsdfAction%2Fring
            
## A Connection
    Connection:
      type: object
      properties:
        retries:
          type: integer
          format: int32
          example: 3
          
 ## DataApp
    DataApp:
      oneOf:
        - $ref: '#/components/schemas/DataAppMqttClient'
        - $ref: '#/components/schemas/DataAppMqttBroker'
        - $ref: '#/components/schemas/DataAppWebhook'
        - $ref: '#/components/schemas/DataAppWebsocket'
      type: object
      properties:
        events:
          type: array
          items:
            $ref: '#/components/schemas/Event'


    DataAppMqttClient:
      type: object
      properties: 
        mqttClient:
          type: boolean

    DataAppMqttBroker:
      type: object
      properties: 
        mqttBroker:
          type: object
          required:
            - URI
            - username
            - password
          properties: 
            URI: 
              type: string
              example: mqtt.broker.com:8883
            username:
              type: string
              example: user1
            password: 
              type: string
              example: password1
            brokerCACert:
              description: PEM encoded CA certificate
              type: string
            customTopic:
              type: string
              description: custom MQTT topic to publish to
              example: custom/topic
      
    DataAppWebhook:
      type: object
      properties: 
        webhook:
          type: object
          properties: 
            URI: 
              type: string
              example: webhook.com:443
            headers:
              type: object
              additionalProperties:
                type: string
              example:
                x-api-key: fjelk-3dl33f-2wdsd
            serverCACert: 
              type: string 
          
    DataAppWebsocket:
      type: object
      properties: 
        websocket:
          type: object
          properties: 
            URI: 
              type: string
              example: websocket.com:443
            headers:
              type: object
              additionalProperties:
                type: string
              example:
                x-api-key: fjelk-3dl33f-2wdsd
            serverCACert: 
              type: string 

 ## sdfObject registration definition
    SdfReference:
      type: object
      description: SDF URL referring to the sdfobject
      properties: 
        sdfName:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                                        healthsensor"

 ## Event name reference for triggers
    EventNameReference:
      type: object
      description: SDF global name of the event associated with a \
                                                              trigger
      properties:
        eventName:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                  healthsensor/sdfEvent/fallDetected"
    
    SdfModel:
      allOf:
        - type: object
          description: Sample SDF model
          properties:
            namespace:
              type: object
              additionalProperties:
                type: string
              example:
                heartrate: https://example.com/heartrate
            defaultNamespace:
              type: string
              example: heartrate
        - oneOf:
          - $ref: '#/components/schemas/SdfThing'
          - $ref: '#/components/schemas/SdfObject'

    SdfThing:
      type: object
      description: Sample SDF thing
      properties:
        sdfThing:
          additionalProperties:
            anyOf:
                - $ref: '#/components/schemas/SdfProperty'
                - $ref: '#/components/schemas/SdfEvent'
                - $ref: '#/components/schemas/SdfAction'
                - $ref: '#/components/schemas/SdfObject'
          example:
            multipleSensor:
              sdfEvent:
                isPresent:
                  sdfProtocolMap:
                    ble:
                      type: advertisement
              sdfObject:
                healthsensor:
                  sdfProperty:
                    heartrate:
                      sdfProtocolMap:
                        ble:
                          serviceID: 00001809-0000-1000-8000-\
                                                         00805f9b34fb
                          characteristicID: 00002a1c-0000-1000-8000-\
                                                         00805f9b34fb
                  sdfEvent:
                    fallDetected:
                        sdfProtocolMap:
                          ble:
                            serviceID: 00001809-0000-1000-8000-\
                                                         00805f9b34fb
                            characteristicID: 00002a1c-0000-1000-\
                                                    8000-00805f9b34fb
                  sdfAction:
                    start:
                      sdfProtocolMap:
                        ble:
                          serviceID: 00001809-0000-1000-8000-\
                                                         00805f9b34fb
                          characteristicID: 00002a1c-0000-1000-8000-\
                                                         00805f9b34fb

    SdfObject:
      type: object
      description: Sample SDF object
      properties:
        sdfObject:
          additionalProperties:
            anyOf:
              - $ref: '#/components/schemas/SdfProperty'
              - $ref: '#/components/schemas/SdfEvent'
              - $ref: '#/components/schemas/SdfAction'
          example:
            healthsensor:
              sdfProperty:
                heartrate:
                  sdfProtocolMap:
                    ble:
                      serviceID: 00001809-0000-1000-8000-00805f9b34fb
                      characteristicID: 00002a1c-0000-1000-8000-\
                                                         00805f9b34fb
              sdfEvent:
                fallDetected:
                  sdfProtocolMap:
                    ble:
                      type: advertisements
              sdfAction:
                start:
                  sdfProtocolMap:
                    ble:
                      serviceID: 00001809-0000-1000-8000-00805f9b34fb
                      characteristicID: 00002a1c-0000-1000-8000-\
                                                         00805f9b34fb

    SdfProperty:
      type: object
      description: Sample SDF property
      properties:
        sdfProperty:
          additionalProperties: 
            allOf:
              - $ref: './protocolmaps/ProtocolMap.yaml#/components/\
                                                 schemas/ProtocolMap'
          example:
            heartrate:
              sdfProtocolMap:
                ble:
                  serviceID: 00001809-0000-1000-8000-00805f9b34fb
                  characteristicID: 00002a1c-0000-1000-8000-\
                                                         00805f9b34fb
          
    SdfEvent:
      type: object
      description: Sample SDF event
      properties:
        sdfEvent:
          additionalProperties: #example, this will be the \
                                                     registered event
            allOf:
              - $ref: './protocolmaps/ProtocolMap.yaml#/components/\
                                                 schemas/ProtocolMap'
          example:
            fallDetected:
                sdfProtocolMap:
                  ble:
                    type: gatt
                    serviceID: 00001809-0000-1000-8000-00805f9b34fb
                    characteristicID: 00002a1c-0000-1000-8000-\
                                                         00805f9b34fb
    
    SdfAction:
      type: object
      description: Sample SDF action
      properties:
        sdfAction:
          additionalProperties: 
            allOf:
              - $ref: './protocolmaps/ProtocolMap.yaml#/components/\
                                                 schemas/ProtocolMap'
          example:
            start:
              sdfProtocolMap:
                ble:
                  serviceID: 00001809-0000-1000-8000-00805f9b34fb
                  characteristicID: 00002a1c-0000-1000-8000-\
                                                         00805f9b34fb

# responses

    SuccessResponse:
      type: object
      properties:
        status:
          type: integer
          format: int32
          example: 200
          description: HTTP status code

## Error 500 application Failure response
    FailureResponse:
      type: object
      properties:
        type:
          type: string
          description: URI to the error type
          enum:
            - https://www.iana.org/assignments/nipc-problem-types#\
                                                           invalid-id
            - https://www.iana.org/assignments/nipc-problem-types#\
                                                      invalid-sdf-url
            - https://www.iana.org/assignments/nipc-problem-types#\
                                     extension-operation-not-executed
            - https://www.iana.org/assignments/nipc-problem-types#\
                                         sdf-model-already-registered
            - https://www.iana.org/assignments/nipc-problem-types#\
                                                     sdf-model-in-use
            - https://www.iana.org/assignments/nipc-problem-types#\
                                               unsupported-uri-scheme
            - https://www.iana.org/assignments/nipc-problem-types#\
                                                property-not-readable
            - https://www.iana.org/assignments/nipc-problem-types#\
                                                 property-read-failed
            - https://www.iana.org/assignments/nipc-problem-types#\
                                                property-not-writable
            - https://www.iana.org/assignments/nipc-problem-types#\
                                                property-write-failed
            - https://www.iana.org/assignments/nipc-problem-types#\
                                                event-already-enabled
            - https://www.iana.org/assignments/nipc-problem-types#\
                                                    event-not-enabled
            - https://www.iana.org/assignments/nipc-problem-types#\
                                                 event-not-registered
            - https://www.iana.org/assignments/nipc-problem-types#\
                                              trigger-already-enabled
            - https://www.iana.org/assignments/nipc-problem-types#\
                                    protocolmap-ble-already-connected
            - https://www.iana.org/assignments/nipc-problem-types#\
                                        protocolmap-ble-no-connection
            - https://www.iana.org/assignments/nipc-problem-types#\
                                   protocolmap-ble-connection-timeout
            - https://www.iana.org/assignments/nipc-problem-types#\
                                       protocolmap-ble-bonding-failed
            - https://www.iana.org/assignments/nipc-problem-types#\
                                    protocolmap-ble-connection-failed
            - https://www.iana.org/assignments/nipc-problem-types#\
                             protocolmap-ble-service-discovery-failed
            - https://www.iana.org/assignments/nipc-problem-types#\
                    protocolmap-ble-invalid-service-or-characteristic
            - https://www.iana.org/assignments/nipc-problem-types#\
                                protocolmap-zigbee-connection-timeout
            - https://www.iana.org/assignments/nipc-problem-types#\
                       protocolmap-zigbee-invalid-endpoint-or-cluster
            - https://www.iana.org/assignments/nipc-problem-types#\
                                      extension-transmit-invalid-data
            - https://www.iana.org/assignments/nipc-problem-types#\
                                          extension-firmware-rollback
            - https://www.iana.org/assignments/nipc-problem-types#\
                                     extension-firmware-update-failed
            - about:blank
        status:
          type: integer
          format: int32
          example: 400
          description: HTTP status code
        title:
          type: string
          example: Invalid Device ID
          description: Human-readable error title
        detail:
          type: string
          example: |-
            Device ID 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30 does not
            exist or is not a device
          description: Human-readable error message  

## Property operations responses
    
    PropertyValueResponseArrayItem:
      oneOf:
        - $ref: '#/components/schemas/SuccessResponse'
        - $ref: '#/components/schemas/FailureResponse'
    
    PropertyValueResponseArray:
      type: array
      items:
          $ref: '#/components/schemas/PropertyValueResponseArrayItem'

    PropertyValueReadResponseArrayItem:
      oneOf:
        - $ref: '#/components/schemas/PropertyValue'
        - $ref: '#/components/schemas/FailureResponse'
    
    PropertyValueReadResponseArray:
      type: array
      items:
        allOf:
          - $ref: '#/components/schemas/\
                                  PropertyValueReadResponseArrayItem'

## Event operations responses
    EventStatusResponseArrayItem:
      oneOf:
        - allOf:
          - $ref: '#/components/schemas/Event'
          - $ref: '#/components/schemas/InstanceId'
        - $ref: '#/components/schemas/FailureResponse'

    EventStatusResponseArray:
      type: array
      items:
          $ref: '#/components/schemas/EventStatusResponseArrayItem'

    GroupEventStatusResponse:
      type: object
      oneOf:
        - allOf:
          - $ref: '#/components/schemas/Event'
          - type: object
            properties:
              deviceId:
                type: string
                format: uuid
                example: 0dc729d7-f6c3-491d-9b9d-e7176d2be243
        - allOf:
          - $ref: '#/components/schemas/FailureResponse'
          - type: object
            properties:
              deviceId:
                type: string
                format: uuid
                example: 9171ec16-e3c1-4ccf-ad23-b92a1a3f069d

    GroupEventStatusResponseArray:
      type: array
      items:
          $ref: '#/components/schemas/GroupEventStatusResponse'
    
    ActionResponse:
      required:
        - status
      type: object
      properties:
        status:
          type: string
          enum:
            - IN_PROGRESS
            - COMPLETED
          example: COMPLETED
          description: |-
            Status of the action, can be IN_PROGRESS or COMPLETED
    
    GroupActiontStatusResponse:
      type: object
      oneOf:
        - allOf:
          - $ref: '#/components/schemas/ActionResponse'
          - type: object
            properties:
              deviceId:
                type: string
                format: uuid
                example: 0dc729d7-f6c3-491d-9b9d-e7176d2be243
        - $ref: '#/components/schemas/FailureResponse'

    GroupActionStatusResponseArray:
      type: array
      items:
          $ref: '#/components/schemas/GroupActiontStatusResponse'
    
    TriggerResponse:
      type: object
      allOf:
        - $ref: '#/components/schemas/EventNameReference'
        - $ref: '#/components/schemas/Action'
        - $ref: '#/components/schemas/InstanceId'

    TriggerStatusResponseArray:
      type: array
      items:
          $ref: '#/components/schemas/TriggerResponse'  

    GroupTriggerResponse:
      type: object
      allOf:
        - type: object
          properties:
            deviceId:
              type: string
              format: uuid
              example: 0dc729d7-f6c3-491d-9b9d-e7176d2be243
        - $ref: '#/components/schemas/EventNameReference'
        - $ref: '#/components/schemas/Action'

    GroupTriggerStatusResponseArray:
      type: array
      items:
          $ref: '#/components/schemas/GroupTriggerResponse'  
<CODE ENDS>
]]></artwork></figure>

</section>
<section anchor="protocol-mapping"><name>Protocol Mapping</name>

<t>The OpenAPI model for SDF protocol mapping is provided in <xref section="B" sectionFormat="of" target="I-D.ietf-asdf-sdf-protocol-mapping"/>.</t>

</section>
<section anchor="protocol-information"><name>Protocol Information</name>

<figure><sourcecode type="yaml" markers="true" name="ProtocolInfo.yaml"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

openapi: 3.0.3
info:
  title: SDF Protocol Information
  description: |-
    SDF Protocol Information. When adding a
    new protocol information schema please add a reference to the \
                                                        protocol info
    for all the schemas in this file.
  version: 0.10.0
externalDocs:
  description: SDF Protocol Mapping IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-sdf-protocol\
                                                            -mapping/

paths: {}

components:
  schemas:
# Protocol Information
## Protocol Info for Service Discovery result
    ProtocolInfo-ServiceMap:
      type: object
      properties:
        protocolInformation:
          oneOf:
            - $ref: './ProtocolInfo-BLE.yaml#/components/schemas/\
                                         ProtocolInfo-BLE-ServiceMap'
            - $ref: './ProtocolInfo-Zigbee.yaml#/components/schemas/\
                                      ProtocolInfo-Zigbee-ServiceMap'

## Protocol Info for Broadcasts
    ProtocolInfo-Broadcast:
      type: object
      properties:
        protocolInformation:
          oneOf:  
            - $ref: './ProtocolInfo-BLE.yaml#/components/schemas/\
                                          ProtocolInfo-BLE-Broadcast'
            - $ref: './ProtocolInfo-Zigbee.yaml#/components/schemas/\
                                       ProtocolInfo-Zigbee-Broadcast'
]]></sourcecode></figure>

<section anchor="protocol-information-for-ble"><name>Protocol Information for BLE</name>

<figure><sourcecode type="yaml" markers="true" name="ProtocolInfo-BLE.yaml"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

openapi: 3.0.3
info:
  title: SDF Protocol Information for BLE
  description: |-
    SDF Protocol Information for BLE devices.
  version: 0.10.0
externalDocs:
  description: SDF Protocol Mapping IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-sdf-protocol\
                                                            -mapping/

paths: {}

components:
  schemas:
# BLE Protocol Info
## A Service is a device with optional service IDs
    ProtocolInfo-BLE-ServiceMap:
      type: object
      properties:
        ble:
          type: object
          properties:
            services:
              type: array
              items:
                type: object
                allOf:
                  - $ref: '#/components/schemas/ProtocolInfo-BLE-\
                                                             Service'
            cached:
              description: |-
                If we can cache information, then device doesn't need
                to be rediscovered before every connected.
              type: boolean
              default: false
            cacheExpiryDuration:
              description: cache expiry period in seconds, when \
                                                        device allows
              type: integer
              example: 3600 # default 1 hour
            autoUpdate:
              description: |-
                autoupdate services if device supports it (default)
              type: boolean
              example: true
            bonding: #optional, by default defined in SCIM object 
              type: string
              example: default
              enum:
                - default 
                - none
                - justworks
                - passkey
                - oob

    ProtocolInfo-BLE-Service:
      required:
        - serviceID
      type: object
      properties:
        serviceID:
          type: string
          format: uuid
          example: 00001809-0000-1000-8000-00805f9b34fb
        characteristics:
          type: array
          items:
            $ref: '#/components/schemas/ProtocolInfo-BLE-\
                                                      Characteristic'

    ProtocolInfo-BLE-Characteristic:
      type: object
      properties:
        characteristicID:
          type: string
          format: uuid
          example: 00002a1c-0000-1000-8000-00805f9b34fb
        flags:
          type: array
          example:
          - read
          - write
          items:
            type: string
            enum:
              - read
              - write
              - notify
              - indicate
              - write-no-response
        descriptors:
          type: array
          items:
            $ref: '#/components/schemas/ProtocolInfo-BLE-Descriptor'

    ProtocolInfo-BLE-Descriptor:
      type: object
      properties:
        descriptorID:
          type: string
          format: uuid
          example: 00002902-0000-1000-8000-00805f9b34fb

##  Protocol Info for BLE Broadcast
    ProtocolInfo-BLE-Broadcast:
      required:
        - ble
      type: object
      properties:
        ble:
          type: object
          properties:
            connectable:
              type: boolean
]]></sourcecode></figure>

</section>
<section anchor="protocol-information-for-zigbee"><name>Protocol Information for Zigbee</name>

<figure><sourcecode type="yaml" markers="true" name="ProtocolInfo-Zigbee.yaml"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

openapi: 3.0.3
info:
  title: SDF Protocol Information for Zigbee
  description: |-
    SDF Protocol Information for Zigbee devices.
  version: 0.10.0
externalDocs:
  description: SDF Protocol Mapping IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-sdf-protocol\
                                                            -mapping/

paths: {}

components:
  schemas:
# Zigbee Protocol Information
##  Protocol Information for Zigbee Service Map
    ProtocolInfo-Zigbee-ServiceMap:
      required:
        - zigbee
      type: object
      properties:
        zigbee:
          type: object
          properties:
            endpoints:
              type: array
              items:
                $ref: '#/components/schemas/ProtocolInfo-Zigbee-\
                                                            Endpoint'

    ProtocolInfo-Zigbee-Endpoint:
      required:
        - endpointID
      type: object
      properties:
        endpointID:
          type: integer
          format: int32
          example: 10
        clusters:
          type: array
          items:
            $ref: '#/components/schemas/ProtocolInfo-Zigbee-Cluster'

    ProtocolInfo-Zigbee-Cluster:
      type: object
      properties:
        clusterID:
          type: integer
          format: int32
          example: 0
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/ProtocolInfo-Zigbee-\
                                                           Attribute'

    ProtocolInfo-Zigbee-Attribute:
      type: object
      properties:
        attributeID:
          type: integer
          format: int32
          example: 1
        attributeType:
          type: integer
          format: int32
          example: 32
        flags:
          type: array
          example:
          - read
          - report
          items:
            type: string
            enum:
              - read
              - write
              - report
          
## Protocol Information for Zigbee broadcast
    ProtocolInfo-Zigbee-Broadcast:
      required:
        - zigbee
      type: object
      properties:
        zigbee:
          type: object
]]></sourcecode></figure>

</section>
</section>
<section anchor="NIPCextensions"><name>NIPC API extensions</name>

<t>The following OpenAPI models define a few example extensions to the NIPC API.</t>

<section anchor="nipc-api-write-binary-blob-extension"><name>NIPC API write binary blob extension</name>

<figure><sourcecode type="yaml" markers="true" name="Extension-Blob.yaml"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

# yaml-language-server: $schema=https://json-schema.org/draft/2020-\
                                                            12/schema
openapi: 3.0.3
info:
  title: Non IP Device Control (NIPC) API write binary blob extension
  description: |-
    Non IP Device Control (NIPC) API write binary blob extension
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.21.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-21"
    variables:
      gw_host:
        default: localhost
        description: Gateway Host
tags:
  - name:  NIPC API extensions
    description: |-
      APIs that simplify application interaction by implementing
      one or more basic APIs into a single API call.

paths:
### Extensions
  /extensions/{id}/properties/blob:
    put:
      tags:
        - NIPC API extensions
      summary: Write a binary blob to a property on a device
      description: |-
        Write a binary blob to a property on a device. Will chunk up
        the binary blob and perform multiple writes. If the 
        underlying protocol requires a connection to be set up, 
        this API call will perform the necessary connection 
        management. If a connection is already active for this 
        device, the existing connection will be leveraged without 
        modifying it. ID cannot be a group-id.
      operationId: writeBlob
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: propertyName
        in: query
        description: |-
          The SDF property name that needs to be written to.
        required: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                     thermostat/sdfProperty/firmware"
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Extension-Blob'
        required: true
      responses:
        '204':
          description: Success, no content
        'default':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '../NIPC.yaml#/components/schemas/\
                                                    FailureResponse' 

components:
  schemas:
# Extensions
## A binary blob Extension
    Extension-Blob:
      required:
        - blob
      type: object
      properties:
        blob:
          type: string
          format: byte
        chunksize:
          type: integer
]]></sourcecode></figure>

</section>
<section anchor="nipc-api-bulk-operations-extension"><name>NIPC API bulk operations extension</name>

<figure><sourcecode type="yaml" markers="true" name="Extension-Bulk.yaml"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

# yaml-language-server: $schema=https://json-schema.org/draft/2020-\
                                                            12/schema
openapi: 3.0.3
info:
  title: Non IP Device Control (NIPC) API bulk extension
  description: |-
    Non IP Device Control (NIPC) API bulk extension
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.21.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-21"
    variables:
      gw_host:
        default: localhost
        description: Gateway Host
tags:
  - name: NIPC API extensions
    description: |-
      APIs that simplify application interaction by implementing
      one or more basic APIs into a single API call.

paths:
  ### Extensions
  /extensions/{id}/bulk:
    post:
      tags:
        - NIPC API extensions
      summary: Compound operations on a device
      description: Compound operations on a device
      operationId: Bulk
      parameters:
        - name: id
          in: path
          description: The ID of the device. Group ID is not allowed.
          required: true
          schema:
            type: string
            format: uuid
            example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Extension-Bulk"
            examples:
              bulkRequest:
                $ref: "#/components/examples/bulkRequest"
              firmwareUpgradeRequest:
                $ref: "#/components/examples/firmwareUpgradeRequest"
        required: true
      responses:
        "202":
          description: Accepted
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-\
bcdbe0a32e30/bulk/status?instanceId=02ee282c-8915-4b2e-bbd2-\
                                                         88966773134a
              description: URL to get the bulk status response
        "401":
          description: Unauthorized
        "405":
          description: Invalid request
        "500":
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: "../NIPC.yaml#/components/schemas/\
                                                     FailureResponse"
      callbacks:
        bulkEvent:
          "{$request.body#/callback.url}":
            post:
              description: Callback for bulk response
              operationId: bulkCallback
              requestBody:
                content:
                  application/json:
                    schema:
                      allOf:
                        - $ref: "../NIPC.yaml#/components/schemas/Id"
                        - $ref: "#/components/schemas/Extension-\
                                                        BulkResponse"
              responses:
                "200":
                  description: OK
                "400":
                  description: Bad request
                "401":
                  description: Unauthorized
                "405":
                  description: Invalid request
                "500":
                  description: Server-side failure
    get:
      tags:
        - NIPC API extensions
      summary: Get Bulk response
      description: Get Bulk response
      operationId: getBulkResponse
      parameters:
        - name: id
          in: path
          description: The ID of the device. Group ID is not allowed.
          required: true
          schema:
            type: string
            format: uuid
            example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
        - name: instanceId
          in: query
          description: Instance ID of the bulk operation
          required: true
          schema:
            type: string
            format: uuid
            example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      responses:
        "200":
          description: OK
          headers:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "../NIPC.yaml#/components/schemas/Id"
                  - $ref: "#/components/schemas/Extension-\
                                                        BulkResponse"
              examples:
                bulkResponse:
                  $ref: "#/components/examples/bulkResponse"
                firmwareUpgradeResponse:
                  $ref: "#/components/examples/\
                                             firmwareUpgradeResponse"
                errorBulkResponse:
                  $ref: "#/components/examples/errorBulkResponse"

  /extensions/{id}/bulk/status:
    get:
      tags:
        - NIPC API extensions
      summary: Get Bulk status
      description: Get Bulk status
      operationId: getBulkStatus
      parameters:
        - name: id
          in: path
          description: The ID of the device. Group ID is not allowed.
          required: true
          schema:
            type: string
            format: uuid
            example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
        - name: instanceId
          in: query
          description: Instance ID of the bulk operation
          required: true
          schema:
            type: string
            format: uuid
            example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      responses:
        "200":
          description: OK
          headers:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./Extension-Async.yaml#/components/\
                                    schemas/Extension-StatusResponse"
        "303":
          description: See Other
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-\
    bcdbe0a32e30/bulk?instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
              description: URL to get the bulk response
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./Extension-Async.yaml#/components/\
                                    schemas/Extension-StatusResponse"
              examples:
                successExample:
                  summary: Success
                  value:
                    status: COMPLETED

components:
  schemas:
    # Extensions
    ## Bulk schema Extension
    Extension-Bulk:
      allOf:
        - $ref: "./Extension-Async.yaml#/components/schemas/\
                                                  Extension-Callback"
        - type: object
          properties:
            operations:
              type: array
              items:
                $ref: "#/components/schemas/Extension-BulkOperation"
            trigger:
              type: string
              description: |-
                When to trigger the operations. If not specified, \
                            the operations are triggered immediately.
              default: immediate
              enum:
                - immediate
                - advertisement

    ## Extension that defines an operation in a bulk API
    Extension-BulkOperation:
      required:
        - method
        - path
      allOf:
        - type: object
          properties:
            method:
              type: string
              enum:
                - POST
                - PUT
                - GET
            path:
              type: string
              enum:
                - /devices/{id}/properties?propertyName={\
                                                        propertyName}
                - /devices/{id}/actions/?actionName={actionName}
                - /extensions/{id}/properties/read/conditional?\
                                          propertyName={propertyName}
                - /extensions/{id}/events/conditional?eventName={\
                                                           eventName}
                - /extensions/{id}/properties/file?propertyName={\
                                                        propertyName}
              example: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30\
/properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                 2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            data:
              type: object
              oneOf:
                - $ref: "../NIPC.yaml#/components/schemas/Value"
                - $ref: "./Extension-ReadConditional.yaml#/\
                        components/schemas/Extension-ConditionalRead"

    ## Multiple returns for a bulk operation
    Extension-BulkResponse:
      type: object
      properties:
        operations:
          type: array
          items:
            $ref: "#/components/schemas/Extension-OperationResponse"

    ## Return for an operation
    Extension-OperationResponse:
      allOf:
        - type: object
          properties:
            method:
              type: string
              enum:
                - POST
                - PUT
                - GET
            path:
              type: string
              enum:
                - /devices/{id}/properties?propertyName={\
                                                        propertyName}
                - /devices/{id}/actions/?actionName={actionName}
                - /extensions/{id}/properties/read/conditional?\
                                          propertyName={propertyName}
                - /extensions/{id}/events/conditional?eventName={\
                                                           eventName}
              example: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30\
/properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                 2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              anyOf:
                - $ref: "../NIPC.yaml#/components/schemas/Value"
                - $ref: "../NIPC.yaml#/components/schemas/\
                                                     SuccessResponse"
                - $ref: "../NIPC.yaml#/components/schemas/\
                                                     FailureResponse"

  examples:
    bulkRequest:
      summary: Bulk request example
      value:
        operations:
          - method: GET
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                 2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                 2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            data:
              value: dGVzdA==
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties/read/conditional?propertyName=https%3A%2F%2Fexample.com%\
2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            data:
              value: dGVzdA==
              maxRepeat: 5
              retryTime: 1
    bulkResponse:
      summary: Bulk response example
      value:
        operations:
          - method: GET
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                 2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              value: dGVzdA==
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                 2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              status: 200
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties/read/conditional?propertyName=https%3A%2F%2Fexample.com%\
2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              value: dGVzdA==
    errorBulkResponse:
      summary: Error Bulk response example
      value:
        operations:
          - method: GET
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                 2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              type: https://www.iana.org/assignments/nipc-problem-\
                                          types#property-not-readable
              status: 400
              title: Property not readable
              detail: Property https://example.com/thermometer#/\
         sdfThing/thermometer/sdfProperty/temperature is not readable
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                 2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              type: https://www.iana.org/assignments/nipc-problem-\
                               types#extension-operation-not-executed
              status: 400
              title: Operation not executed
              detail: Operation was not executed since the previous \
                                                     operation failed
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties/read/conditional?propertyName=https%3A%2F%2Fexample.com%\
2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              type: https://www.iana.org/assignments/nipc-problem-\
                               types#extension-operation-not-executed
              status: 400
              title: Operation not executed
              detail: Operation was not executed since the previous \
                                                     operation failed
    firmwareUpgradeRequest:
      summary: Firmware upgrade request example
      value:
        operations:
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                    2FsdfThing%2Fthermometer%2FsdfProperty%2FstartOTA
            data:
              value: dGVzdA==
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
events/conditional?eventName=https%3A%2F%2Fexample.com%2Fthermometer\
                 %23%2FsdfThing%2Fthermometer%2FsdfEvent%2FotaStarted
            data:
              value: MQ==
              timeout: 5
          - method: PUT
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties/file?propertyName=https%3A%2F%2Fexample.com%2Fthermometer\
                %23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ffirmware
            data:
              fileURL: https://example.com/firmware.bin
              chunkSize: 20
              sha256Checksum: \
     abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                   2FsdfThing%2Fthermometer%2FsdfProperty%2FfinishOTA
            data:
              value: dGVzdA==
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties/read/conditional?propertyName=https%3A%2F%2Fexample.com%\
2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%\
                                                       2FupdateStatus
            data:
              value: MQ==
              maxRepeat: 5
              retryTime: 1
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                 2FsdfThing%2Fthermometer%2FsdfProperty%2FactivateOTA
            data:
              value: dGVzdA==
    firmwareUpgradeResponse:
      summary: Firmware upgrade response example
      value:
        operations:
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                    2FsdfThing%2Fthermometer%2FsdfProperty%2FstartOTA
            response:
              status: 200
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
events/conditional?eventName=https%3A%2F%2Fexample.com%2Fthermometer\
                 %23%2FsdfThing%2Fthermometer%2FsdfEvent%2FotaStarted
            response:
              value: MQ==
          - method: PUT
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties/file?propertyName=https%3A%2F%2Fexample.com%2Fthermometer\
                %23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ffirmware
            response:
              status: 204
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                   2FsdfThing%2Fthermometer%2FsdfProperty%2FfinishOTA
            response:
              status: 200
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties/read/conditional?propertyName=https%3A%2F%2Fexample.com%\
2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%\
                                                       2FupdateStatus
            response:
              value: MQ==
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/\
properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
                 2FsdfThing%2Fthermometer%2FsdfProperty%2FactivateOTA
            data:
              status: 200
]]></sourcecode></figure>

</section>
<section anchor="nipc-api-write-file-extension"><name>NIPC API write file extension</name>

<figure><sourcecode type="yaml" markers="true" name="Extension-File.yaml"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

# yaml-language-server: $schema=https://json-schema.org/draft/2020-\
                                                            12/schema
openapi: 3.0.3
info:
  title: Non IP Device Control (NIPC) API write file extension
  description: |-
    Non IP Device Control (NIPC) API write file extension
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.21.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-21"
    variables:
      gw_host:
        default: localhost
        description: Gateway Host
tags:
  - name:  NIPC API extensions
    description: |-
      APIs that simplify application interaction by implementing
      one or more basic APIs into a single API call.

paths:
### Extensions
  /extensions/{id}/properties/file:
    put:
      tags:
        - NIPC API extensions
      summary: Write a file to a property on a device
      description: |-
        Write a file to a property on a device. Will chunk up the 
        file and perform multiple writes. If the underlying protocol
        requires a connection to be set up, this API call will 
        perform the necessary connection management. If a connection
        is already active for this device, the existing connection 
        will be leveraged without modifying it. ID cannot be a
        group-id.
      operationId: writeFile
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: propertyName
        in: query
        description: |-
          The SDF property name that needs to be written to.
        required: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                     thermostat/sdfProperty/firmware"
      requestBody:
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/Extension-File'
                - $ref: './Extension-Async.yaml#/components/schemas/\
                                                  Extension-Callback'
        required: true
      responses:
        '202':
          description: Accepted
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-\
bcdbe0a32e30/properties/file/status?propertyName=https%3A%2F%\
2Fexample.com%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%\
           2Ffirmware&instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
              description: |-
                URL to get the file write status
            Retry-After:
              schema:
                type: integer
              description: |-
                Time in seconds to wait before retrying
        'default':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '../NIPC.yaml#/components/schemas/\
                                                     FailureResponse'
      callbacks:
        callbackEvent:
          "{$request.body#/callback.url}":
            post:
              requestBody:
                content:
                  application/json:
                    schema:
                      anyOf:
                        - allOf:
                          - $ref: '../NIPC.yaml#/components/schemas/\
                                                                  Id'
                          - $ref: '../NIPC.yaml#/components/schemas/\
                                                       PropertyValue'
                        - $ref: '../NIPC.yaml#/components/schemas/\
                                                     FailureResponse'
                    examples:
                      successExample:
                        summary: Success
                        value:
                          id: 02ee282c-8915-4b2e-bbd2-88966773134a
                          property: https://example.com/heartrate#/\
                            sdfObject/thermostat/sdfProperty/firmware
                      failedResponse:
                        summary: Failed
                        value:
                          id: 02ee282c-8915-4b2e-bbd2-88966773134a
                          status: 400
                          type: https://www.iana.org/assignments/\
                                        nipc-problem-types#invalid-id
                          title: Invalid ID
                          detail: "Invalid request"
                          property: https://example.com/heartrate#/\
                            sdfObject/thermostat/sdfProperty/firmware
              responses:
                '200':
                  description: Success
    get:
      tags:
        - NIPC API extensions
      summary: Get the status of a file write operation
      description: |-
        Get the status of a file write operation. This will return
        the status of the file write operation, including any errors
        that may have occurred.
      operationId: getFileWriteStatus
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: propertyName
        in: query
        description: |-
          The SDF property name that needs to be written to.
        required: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                     thermostat/sdfProperty/firmware"
      - name: instanceId
        in: query
        description: |-
          The Instance ID for the file write operation.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      responses:
        '204':
          description: Success, no content
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '../NIPC.yaml#/components/schemas/\
                                                     FailureResponse'
  /extensions/{id}/properties/file/status:
    get:
      tags:
        - NIPC API extensions
      summary: Get the status of a file write operation
      description: |-
        Get the status of a file write operation. This will return
        the status of the file write operation, including any errors
        that may have occurred.
      operationId: getFileWriteStatus
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: propertyName
        in: query
        description: |-
          The SDF property name that needs to be written to.
        required: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/\
                                     thermostat/sdfProperty/firmware"
      - name: instanceId
        in: query
        description: |-
          The Instance ID for the file write operation.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      responses:
        '200':
          description: Success, returns the status of the file \
                                                     write operation.
          content:
            application/json:
              schema:
                $ref: './Extension-Async.yaml#/components/schemas/\
                                            Extension-StatusResponse'
        '303':
          description: See Other
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-\
bcdbe0a32e30/properties/file?propertyName=https%3A%2F%2Fexample.com%\
2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2Ffirmware&\
                      instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
              description: URL to get the file write response
          content:
            application/json:
              schema:
                $ref: './Extension-Async.yaml#/components/schemas/\
                                            Extension-StatusResponse'
              examples:
                successExample:
                  summary: Completed
                  value:
                    id: 02ee282c-8915-4b2e-bbd2-88966773134a
                    status: COMPLETED

components:
  schemas:
# Extensions
## A File Extension
    Extension-File:
      required:
        - fileURL
      type: object
      properties:
        fileURL:
          type: string
          example: "https://domain.com/firmware.dat"
          description: |-
            URL to the firmware file. 
            The HTTP method is assumed to be a GET.
        chunkSize:
          type: integer
        sha256Checksum:
          type: string
          description: firmware checksum
        headers:
          type: object
          additionalProperties:
            type: string
          example:
            x-api-key: fjelk-3dl33f-2wdsd
]]></sourcecode></figure>

</section>
<section anchor="nipc-api-conditional-read-extension"><name>NIPC API conditional read extension</name>

<figure><sourcecode type="yaml" markers="true" name="Extension-ReadConditional.yaml"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

# yaml-language-server: $schema=https://json-schema.org/draft/2020-\
                                                            12/schema
openapi: 3.0.3
info:
  title: Non IP Device Control (NIPC) API read conditional extension
  description: |-
    Non IP Device Control (NIPC) API read conditional extension
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.21.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-21"
    variables:
      gw_host:
        default: localhost
        description: Gateway Host
tags:
  - name:  NIPC API extensions
    description: |-
      APIs that simplify application interaction by implementing
      one or more basic APIs into a single API call.

paths:
### Extensions
  /extensions/{id}/properties/read/conditional:
    post:
      tags:
        - NIPC API extensions
      summary: Conditional read of a property
      description: Conditional read of a property
      operationId: conditionalRead
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: propertyName
        in: query
        description: |-
          The SDF property name that needs to be read conditionally.
        required: true
        allowReserved: true
        schema:
          type: string
          example: "#/sdfObject/thermostat/sdfProperty/temperature"
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Extension-ConditionalRead'
        required: true
      responses:
        '202':
          description: Accepted
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-\
bcdbe0a32e30/properties/read/conditional/status?propertyName=https%\
3A%2F%2Fexample.com%2Fheartrate%23%2FsdfObject%2Fthermostat%\
2FsdfProperty%2Ftemperature&instanceId=02ee282c-8915-4b2e-bbd2-\
                                                         88966773134a
              description: |-
                URL to get the conditional read status
            Retry-After:
              schema:
                type: integer
              description: |-
                Time in seconds to wait before retrying
        'default':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '../NIPC.yaml#/components/schemas/\
                                                     FailureResponse'
      callbacks:
        callbackEvent:
          "{$request.body#/callback.url}":
            post:
              requestBody:
                content:
                  application/json:
                    schema:
                      anyOf:
                        - allOf:
                          - $ref: '../NIPC.yaml#/components/schemas/\
                                                                  Id'
                          - $ref: '../NIPC.yaml#/components/schemas/\
                                                       PropertyValue'
                        - $ref: '../NIPC.yaml#/components/schemas/\
                                                     FailureResponse'
                    examples:
                      successExample:
                        summary: Success
                        value:
                          id: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
                          property: https://example.com/heartrate#/\
                         sdfObject/thermostat/sdfProperty/temperature
                          value: dGVzdA==
                      failedResponse:
                        summary: Failed
                        value:
                          id: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
                          status: 400
                          type: https://www.iana.org/assignments/\
                                        nipc-problem-types#invalid-id
                          title: Invalid ID
                          detail: "Invalid request"
                          property: https://example.com/heartrate#/\
                         sdfObject/thermostat/sdfProperty/temperature
                          value: dGVzdA==
                          
              responses:
                '200':
                  description: Success
    get:
      tags:
        - NIPC API extensions
      summary: Get Conditional read response of a property
      description: Conditional read response of a property
      operationId: getConditionalRead
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: propertyName
        in: query
        description: |-
          The SDF property name that needs to be read conditionally.
        required: true
        allowReserved: true
        schema:
          type: string
          example: "#/sdfObject/thermostat/sdfProperty/temperature"
      - name: instanceId
        in: query
        description: |-
          Instance ID of the conditional read operation
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      responses:
        '200':
          description: Success
          headers:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/Value'
            application/octet-stream:
              schema:
                type: string
                format: binary
              description: Binary data of the property value
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/\
                                                     FailureResponse'
  /extensions/{id}/properties/read/conditional/status:
    get:
      tags:
        - NIPC API extensions
      summary: Get Conditional read status of a property
      description: Conditional read status of a property
      operationId: getConditionalReadStatus
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: propertyName
        in: query
        description: |-
          The SDF property name that needs to be read conditionally.
        required: true
        allowReserved: true
        schema:
          type: string
          example: "#/sdfObject/thermostat/sdfProperty/temperature"
      - name: instanceId
        in: query
        description: Instance ID of the conditional read operation
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      responses:
        '200':
          description: OK
          headers:
          content:
            application/json:
              schema:
                $ref: './Extension-Async.yaml#/components/schemas/\
                                            Extension-StatusResponse'
        '303':
          description: See Other
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-\
bcdbe0a32e30/properties/read/conditional?propertyName=https%3A%2F%\
2Fexample.com%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%\
        2Ftemperature&instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
              description: URL to get the conditional read response
          content:
            application/json:
              schema:
                $ref: './Extension-Async.yaml#/components/schemas/\
                                            Extension-StatusResponse'
              examples:
                successExample:
                  summary: Completed
                  value:
                    id: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
                    status: COMPLETED

components:
  schemas:
# Extensions
    Extension-ConditionalRead:
      allOf:
        - $ref: '../NIPC.yaml#/components/schemas/Value'
        - $ref: './Extension-Async.yaml#/components/schemas/\
                                                  Extension-Callback'
        - type: object
          properties:
            maxRepeat:
              description: |-
                maximum time the conditional read should repeat
                (default 5, max 10)
              type: integer
              example: 5
            retryTime:
              description: |-
                time between reads in seconds (default 1, max 10)
              type: integer
              example: 1
]]></sourcecode></figure>

</section>
<section anchor="nipc-api-conditional-event-extension"><name>NIPC API conditional event extension</name>

<figure><sourcecode type="yaml" markers="true" name="Extension-EventConditional.yaml"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

# yaml-language-server: $schema=https://json-schema.org/draft/2020-\
                                                            12/schema
openapi: 3.0.3
info:
  title: Non IP Device Control (NIPC) API event conditional extension
  description: |-
    Non IP Device Control (NIPC) API event conditional extension
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.21.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-21"
    variables:
      gw_host:
        default: localhost
        description: Gateway Host
tags:
  - name:  NIPC API extensions
    description: |-
      APIs that simplify application interaction by implementing
      one or more basic APIs into a single API call.

paths:
### Extensions
  /extensions/{id}/events/conditional:
    post:
      tags:
        - NIPC API extensions
      summary: Enable an event until a condition is met
      description: Enable an event until a condition is met
      operationId: conditionalEvent
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: eventName
        in: query
        description: |-
          The SDF event name that needs to be enabled.
        required: true
        allowReserved: true
        schema:
          type: string
          example: "#/sdfObject/thermostat/sdfEvent/temperature"
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Extension-ConditionalEvent'
        required: true
      responses:
        '202':
          description: Accepted
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-\
bcdbe0a32e30/events/conditional/status?eventName=https%3A%2F%\
2Fexample.com%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfEvent%\
        2Ftemperature&instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
              description: |-
                URL to get the conditional event status
            Retry-After:
              schema:
                type: integer
              description: |-
                Time in seconds to wait before retrying
        'default':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '../NIPC.yaml#/components/schemas/\
                                                     FailureResponse'
      callbacks:
        callbackEvent:
          "{$request.body#/callback.url}":
            post:
              requestBody:
                content:
                  application/json:
                    schema:
                      anyOf:
                        - allOf:
                          - $ref: '../NIPC.yaml#/components/schemas/\
                                                                  Id'
                          - $ref: '../NIPC.yaml#/components/schemas/\
                                                       PropertyValue'
                        - $ref: '../NIPC.yaml#/components/schemas/\
                                                     FailureResponse'
                    examples:
                      successExample:
                        summary: Success
                        value:
                          id: 02ee282c-8915-4b2e-bbd2-88966773134a
                          event: https://example.com/heartrate#/\
                            sdfObject/thermostat/sdfEvent/temperature
                          value: dGVzdA==
                      failedResponse:
                        summary: Failed
                        value:
                          id: 02ee282c-8915-4b2e-bbd2-88966773134a
                          status: 400
                          type: https://www.iana.org/assignments/\
                                        nipc-problem-types#invalid-id
                          title: Invalid ID
                          detail: "Invalid request"
                          event: https://example.com/heartrate#/\
                            sdfObject/thermostat/sdfEvent/temperature
                          value: dGVzdA==
                          
              responses:
                '200':
                  description: Success
    get:
      tags:
        - NIPC API extensions
      summary: Get Conditional event response
      description: Conditional event response
      operationId: getConditionalEvent
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: eventName
        in: query
        description: |-
          The name of the SDF event that is enabled.
        required: true
        allowReserved: true
        schema:
          type: string
          example: "#/sdfObject/thermostat/sdfEvent/temperature"
      - name: instanceId
        in: query
        description: |-
          Instance ID of the conditional event operation
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      responses:
        '200':
          description: Success
          headers:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/Value'
            application/octet-stream:
              schema:
                type: string
                format: binary
              description: Binary data of the event value
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/\
                                                     FailureResponse'
  /extensions/{id}/events/conditional/status:
    get:
      tags:
        - NIPC API extensions
      summary: Get Conditional event status
      description: Conditional event status
      operationId: getConditionalEventStatus
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      - name: eventName
        in: query
        description: |-
          The name of the SDF event that is enabled.
        required: true
        allowReserved: true
        schema:
          type: string
          example: "#/sdfObject/thermostat/sdfEvent/temperature"
      - name: instanceId
        in: query
        description: Instance ID of the conditional event operation
        required: true
        schema:
          type: string
          format: uuid
          example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      responses:
        '200':
          description: OK
          headers:
          content:
            application/json:
              schema:
                $ref: './Extension-Async.yaml#/components/schemas/\
                                            Extension-StatusResponse'
        '303':
          description: See Other
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-\
bcdbe0a32e30/events/conditional?eventName=https%3A%2F%2Fexample.com%\
2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfEvent%2Ftemperature&\
                      instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
              description: URL to get the conditional event response
          content:
            application/json:
              schema:
                $ref: './Extension-Async.yaml#/components/schemas/\
                                            Extension-StatusResponse'
              examples:
                successExample:
                  summary: Completed
                  value:
                    id: 02ee282c-8915-4b2e-bbd2-88966773134a
                    status: COMPLETED

components:
  schemas:
# Extensions
    Extension-ConditionalEvent:
      allOf:
        - $ref: './Extension-Async.yaml#/components/schemas/\
                                                  Extension-Callback'
        - $ref: '../NIPC.yaml#/components/schemas/Value'
        - type: object
          properties:
            timeout:
              description: |-
                Time in seconds to keep the event enabled.
                If the event condition is not met within this time,
                the event will be disabled and marked as failed.
              type: integer
              example: 5
]]></sourcecode></figure>

</section>
<section anchor="nipc-api-property-extensions"><name>NIPC API property extensions</name>

<figure><sourcecode type="yaml" markers="true" name="Extension-Transmit.yaml"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

# yaml-language-server: $schema=https://json-schema.org/draft/2020-\
                                                            12/schema
openapi: 3.0.3
info:
  title: Non IP Device Control (NIPC) API properties extension
  description: |-
    Non IP Device Control (NIPC) API properties extension
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.21.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-21"
    variables:
      gw_host:
        default: localhost
        description: Gateway Host
tags:
  - name:  NIPC API extensions
    description: |-
      APIs that simplify application interaction by implementing
      one or more basic APIs into a single API call.

paths:
### Extensions
  /extensions/{id}/transmit:
    post:
      tags:
        - NIPC API extensions
      summary: Transmit to a device
      description: |-
        Transmit a payload to a device. The transmission is \
                   performed on the AP where the device was last seen
      operationId: ActionTransmit
      parameters:
        - name: id
          in: path
          description: The ID of the device. Group ID is not allowed.
          required: true
          schema:
            type: string
            format: uuid
            example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Transmit'
        required: true
      responses:
        '200':
          description: Success
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '../NIPC.yaml#/components/schemas/\
                                                     FailureResponse'

components:
  schemas:
    Transmit:
      allOf:
        - $ref: '../protocolinfo/ProtocolInfo.yaml#/components/\
                                      schemas/ProtocolInfo-Broadcast'
      required:
        - cycle
      type: object
      properties:
        cycle:
          type: string
          example: single
          enum:
            - single
            - repeat
        # transmit time in ms
        transmitTime:
          type: integer
          example: 3000
        # interval between transmits in ms
        transmitInterval:
          type: integer
          example: 500
        payload:
          type: string
          format: byte
          example: AgEaAgoMFv9MABAHch9BsDkgeA==
]]></sourcecode></figure>

</section>
</section>
<section anchor="nipc-api-cddl-definition"><name>NIPC API CDDL Definition</name>

<t>The following is a combined reference of all NIPC API CDDL definitions used in this document.</t>

<figure><sourcecode type="cddl" markers="true" name="combined.cddl"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

; This file is auto-generated from individual NIPC API CDDL files

; ============================================
; From: cddl/api/action_response.cddl
; ============================================
ActionResponse = {
  status: ActionStatus
}

ActionStatus = "IN_PROGRESS" / "COMPLETED"
; ============================================
; From: cddl/api/action.cddl
; ============================================
Action = {
  action: text  ; NIPC action operation to execute
}

; ============================================
; From: cddl/api/data_app.cddl
; ============================================
DataApp = {
  events: [* EventRef],
  ( DataAppMqttClient //
    DataAppMqttBroker //
    DataAppWebhook //
    DataAppWebsocket )
}

EventRef = {
  event: text    ; SDF global name (absolute URI with fragment)
}

DataAppMqttClient = {
  mqttClient: bool
}

DataAppMqttBroker = {
  mqttBroker: {
    URI: text,
    username: text,
    password: text,
    ? brokerCACert: text,   ; PEM-encoded CA certificate
    ? customTopic: text     ; optional custom MQTT topic
  }
}

DataAppWebhook = {
  webhook: {
    URI: text,
    ? headers: { * text => text },  ; key/value headers
    ? serverCACert: text
  }
}

DataAppWebsocket = {
  websocket: {
    URI: text,
    ? headers: { * text => text },  ; key/value headers
    ? serverCACert: text
  }
}
; ============================================
; From: cddl/api/event_status_array.cddl
; ============================================
EventStatusResponseArray = [* EventStatusResponseArrayItem]

EventStatusResponseArrayItem = ( EventInstanceSuccess // \
                                                    FailureResponse )

; Success item = { event, instanceId }
EventInstanceSuccess = {
  event: text,        ; SDF global name of the event (absolute URI \
                                                       with fragment)
  instanceId: text    ; UUID (as text)
}

; ============================================
; From: cddl/api/failure_response.cddl
; ============================================
FailureResponse = {
  type: FailureTypeURI,
  status: uint,
  title: text,
  detail: text
}

; Enumerated problem type URIs registered for NIPC
FailureTypeURI = (
  "https://www.iana.org/assignments/nipc-problem-types#invalid-id" /
  "https://www.iana.org/assignments/nipc-problem-types#invalid-sdf-\
                                                               url" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-\
                                            operation-not-executed" /
  "https://www.iana.org/assignments/nipc-problem-types#sdf-model-\
                                                already-registered" /
  "https://www.iana.org/assignments/nipc-problem-types#sdf-model-in-\
                                                               use" /
  "https://www.iana.org/assignments/nipc-problem-types#unsupported-\
                                                        uri-scheme" /
  "https://www.iana.org/assignments/nipc-problem-types#property-not-\
                                                          readable" /
  "https://www.iana.org/assignments/nipc-problem-types#property-read\
                                                           -failed" /
  "https://www.iana.org/assignments/nipc-problem-types#property-not-\
                                                          writable" /
  "https://www.iana.org/assignments/nipc-problem-types#property-\
                                                      write-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#event-already\
                                                          -enabled" /
  "https://www.iana.org/assignments/nipc-problem-types#event-not-\
                                                           enabled" /
  "https://www.iana.org/assignments/nipc-problem-types#event-not-\
                                                        registered" /
  "https://www.iana.org/assignments/nipc-problem-types#trigger-\
                                                   already-enabled" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                             ble-already-connected" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                                 ble-no-connection" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                            ble-connection-timeout" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                                ble-bonding-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                             ble-connection-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                      ble-service-discovery-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                             ble-invalid-service-or-characteristic" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                         zigbee-connection-timeout" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-\
                                zigbee-invalid-endpoint-or-cluster" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-\
                                             transmit-invalid-data" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-\
                                                 firmware-rollback" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-\
                                            firmware-update-failed" /
  "about:blank"
)
; ============================================
; From: cddl/api/group_event_status_response_array.cddl
; ============================================
GroupEventStatusResponseArray = [* GroupEventStatusResponse]

GroupEventSuccessResponse = { event: text, deviceId: text }

; Each item is either an event+deviceId success or a \
                                                 GroupFailureResponse
GroupEventStatusResponse = (GroupEventSuccessResponse // \
                                                GroupFailureResponse)

GroupFailureResponse = {
  FailureResponse,
  ? deviceId: text
}

; ============================================
; From: cddl/api/group_trigger_status_array.cddl
; ============================================
; Group Trigger status response array and item shape

GroupTriggerStatusResponseArray = [* GroupTriggerResponse]

GroupTriggerResponse = (GroupTriggerSuccessResponse // \
                                         GroupTriggerFailureResponse)

GroupTriggerSuccessResponse = {
  eventName: text,      ; SDF event name
  action: text,      ; NIPC action operation to execute
  deviceId: text     ; UUID (as text)
}

GroupTriggerFailureResponse = {
  FailureResponse,
  ? deviceId: text
}

; ============================================
; From: cddl/api/trigger_status_array.cddl
; ============================================
; Trigger status response array and item shape

TriggerStatusResponseArray = [* TriggerResponse]

TriggerResponse = {
  eventName: text,      ; SDF event name
  action: text,      ; NIPC action operation to execute
  instanceId: text     ; UUID (as text)
}

; ============================================
; From: cddl/api/property_value_array.cddl
; ============================================
PropertyValueArray = [* PropertyValue]

; Minimal PropertyValue shape (matches allOf of Property + Value)
PropertyValue = {
  property: text,        ; SDF global name of the property
  value: b64text         ; base64-encoded bytes (RFC 4648 Section 4)
}

; Helper type for base64-with-padding encoded text
b64text = text
; ============================================
; From: cddl/api/property_value_read_response_array.cddl
; ============================================
PropertyValueReadResponseArray = [* \
                                  PropertyValueReadResponseArrayItem]

PropertyValueReadResponseArrayItem = ( PropertyValue // \
                                                    FailureResponse )

; ============================================
; From: cddl/api/property_value_response_array.cddl
; ============================================
PropertyValueResponseArray = [* PropertyValueResponseArrayItem]

PropertyValueResponseArrayItem = ( SuccessResponse // \
                                                    FailureResponse )

; Minimal success shape (may be extended)
SuccessResponse = {
  status: uint
}

; ============================================
; From: cddl/api/sdf_reference.cddl
; ============================================
SdfGlobalName = text    ; absolute URI with fragment referencing an \
                                                sdfThing or sdfObject

SdfReference = {
  sdfName: SdfGlobalName
}

SdfReferenceArray = [* SdfReference]
; ============================================
; From: cddl/api/connection.cddl
; ============================================
ConnectionRequest = {
  ? retries: uint,
  ? protocol-info-service-map
}

ConnectionResponse = {
  id: text,  ; Device ID
  ? protocol-info-service-map
}

; ============================================
; From: cddl/api/protocolinfo.cddl
; ============================================
; Top-level wrappers
protocol-info-service-map = (
  ? protocolInformation: ble-service-map / zigbee-service-map
)

protocol-info-broadcast = (
  ? protocolInformation: ble-broadcast / zigbee-broadcast
)

; BLE protocol information
ble-service-map = {
  ble: {
    ? services: [* ble-service],
    ? cached: bool,
    ? cacheExpiryDuration: int,
    ? autoUpdate: bool,
    ? bonding: bonding-type,
  }
}

bonding-type = "default" / "none" / "justworks" / "passkey" / "oob"

ble-service = {
  serviceID: uuid,
  ? characteristics: [* ble-characteristic],
}

ble-characteristic = {
  characteristicID: uuid,
  ? flags: [* ble-flag],
  ? descriptors: [* ble-descriptor],
}

ble-flag = "read" / "write" / "notify" / "indicate" / "write-no-\
                                                            response"

ble-descriptor = {
  descriptorID: uuid,
}

ble-broadcast = {
  ble: {
    ? connectable: bool,
  },
}

; Zigbee protocol information
zigbee-service-map = {
  zigbee: {
    ? endpoints: [* zigbee-endpoint],
  },
}

zigbee-endpoint = {
  endpointID: uint,
  ? clusters: [* zigbee-cluster],
}

zigbee-cluster = {
  clusterID: uint,
  ? attributes: [* zigbee-attribute],
}

zigbee-attribute = {
  attributeID: uint,
  attributeType: uint,
  ? flags: [* zigbee-flag],
}

zigbee-flag = "read" / "write" / "report"

zigbee-broadcast = {
  zigbee: {
  },
}

; Basic types
uuid = tstr .regexp "(?i)^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-\
                                                 f]{4}-[0-9a-f]{12}$"

]]></sourcecode></figure>

</section>
<section anchor="thermometer-sdf"><name>Example SDF model with protocol mappings for BLE</name>

<figure title="Example SDF model with protocol mappings for BLE"><sourcecode type="json" markers="true" name="thermometer.sdf.json"><![CDATA[
{
  "namespace": {
    "thermometer": "https://example.com/thermometer"
  },
  "defaultNamespace": "thermometer",
  "sdfThing": {
    "thermometer": {
      "sdfObject": {
        "health_thermometer": {
          "description": "Health Thermometer",
          "sdfProperty": {
            "temperature_type": {
              "description": "Temperature Type",
              "observable": false,
              "writable": false,
              "readable": true,
              "sdfProtocolMap": {
                "ble": {
                  "serviceID": "1809",
                  "characteristicID": "2A1D"
                }
              }
            },
            "measurement_interval": {
              "description": "Measurement Interval",
              "observable": false,
              "writable": false,
              "readable": true,
              "sdfProtocolMap": {
                "ble": {
                  "serviceID": "1809",
                  "characteristicID": "2A21"
                }
              }
            }
          },
          "sdfEvent": {
            "temperature_measurement": {
              "description": "Temperature Measurement",
              "sdfProtocolMap": {
                "ble": {
                  "type": "gatt",
                  "serviceID": "1809",
                  "characteristicID": "2A1C"
                }
              }
            },
            "intermediate_temperature": {
              "description": "Intermediate Temperature",
              "sdfProtocolMap": {
                "ble": {
                  "type": "gatt",
                  "serviceID": "1809",
                  "characteristicID": "2A1E"
                }
              }
            }
          }
        }
      },
      "description": "Generic Access, Device Information",
      "sdfProperty": {
        "device_name": {
          "description": "Device Name",
          "observable": false,
          "writable": true,
          "readable": true,
          "sdfProtocolMap": {
            "ble": {
              "serviceID": "1800",
              "characteristicID": "2A00"
            }
          }
        },
        "appearance": {
          "description": "Appearance",
          "observable": false,
          "writable": false,
          "readable": true,
          "sdfProtocolMap": {
            "ble": {
              "serviceID": "1800",
              "characteristicID": "2A01"
            }
          }
        },
        "manufacturer_name_string": {
          "description": "Manufacturer Name String",
          "observable": false,
          "writable": false,
          "readable": true,
          "sdfProtocolMap": {
            "ble": {
              "serviceID": "180A",
              "characteristicID": "2A29"
            }
          }
        },
        "model_number_string": {
          "description": "Model Number String",
          "observable": false,
          "writable": false,
          "readable": true,
          "sdfProtocolMap": {
            "ble": {
              "serviceID": "180A",
              "characteristicID": "2A24"
            }
          }
        },
        "hardware_revision_string": {
          "description": "Hardware Revision String",
          "observable": false,
          "writable": false,
          "readable": true,
          "sdfProtocolMap": {
            "ble": {
              "serviceID": "180A",
              "characteristicID": "2A27"
            }
          }
        },
        "firmware_revision_string": {
          "description": "Firmware Revision String",
          "observable": false,
          "writable": false,
          "readable": true,
          "sdfProtocolMap": {
            "ble": {
              "serviceID": "180A",
              "characteristicID": "2A26"
            }
          }
        },
        "system_id": {
          "description": "System ID",
          "observable": false,
          "writable": false,
          "readable": true,
          "sdfProtocolMap": {
            "ble": {
              "serviceID": "180A",
              "characteristicID": "2A23"
            }
          }
        }
      },
      "sdfEvent": {
        "isPresent": {
          "description": "BLE advertisements",
          "sdfProtocolMap": {
            "ble": {
              "type": "advertisements"
            }
          }
        },
        "isConnected": {
          "description": "BLE connection events",
          "sdfProtocolMap": {
            "ble": {
              "type": "connection_events"
            }
          }
        }
      }
    }
  }
}
]]></sourcecode></figure>

</section>
<section numbered="false" anchor="acknowledgements"><name>Acknowledgements</name>

<t>This document relies on SDF models described in <xref target="RFC9880"/>, as such, we are grateful to the authors of this
document for putting their time and effort into defining SDF in depth, allowing us to make use of it.
The authors would like to thank Ari Keränen, Carsten Bormann, Eliot Lear, Michael Richardson, and Sriram Sekar for their reviews and contributions that helped improve this document.</t>

</section>


  </back>

<!-- ##markdown-source:
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

-->

</rfc>

