<?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-22" 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="September" day="15"/>

    
    
    <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 //
  zigbeeClusterCommand: ZigbeeClusterCommand //
  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
}

ZigbeeClusterCommand = {
  endpointID: uint,
  clusterID: uint,
  commandID: uint,
  direction: "client_to_server" / "server_to_client",
  ? 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 Cluster Command"><artwork><![CDATA[
[
  {
    "data": h'010001',
    "deviceID": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
    "timestamp": 1727484393,
    "zigbeeClusterCommand": {
        "endpointID": 1,
        "clusterID": 6,
        "commandID": 1,
        "direction": "client_to_server"
    }
  }
]
]]></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-22</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-22</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 notif-ication/indication</c>
      <c>BleSubscription</c>
      <c>This document</c>
      <c>bleAdvertisement</c>
      <c>BLE advertise-ment 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>zigbeeClusterCommand</c>
      <c>Zigbee cluster command</c>
      <c>ZigbeeClusterCommand</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="15" month="September" 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-12"/>
   
</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 3082?>

<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.22.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-22"
    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.22.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-22"
    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.22.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-22"
    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.22.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-22"
    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.22.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-22"
    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.22.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-22"
    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.22.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-22"
    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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
t8G8pMlvblquqxAMWcDb/rjKzYiFIKj9YZi7xGRwb6xeZRC+kSfuHlcmwnOg
CoCuUbDD4KrKg50zO5uAjNLjQwyTThCfkeVZxtJ0ydVxERHxWwcSTIkIigaI
l8ZrYSJ5XKI+VBDAQG56U/RD9nEML2OdIkRpGqFDEX6hg923Pj4DA64knaEn
OOfB0BRvTFgoEZGQwcOjkAgSyiqBEceoE8CmT1HfLlwFyGc6iCqHD/aHCXEB
mvoKubDh+jiP4U1tHPylqk0AK2n+7lEEDSQFRKbZtSUrIXhWzodTYmtKB3Iw
CUT/oNFc+zD0pKBfL8Nhgo5KQm6VQLIYPVaCUHr36OcJ+vKMzBT2ed0URsma
LPE/Zy/o1RPhWyh6k35SGFcVTmecaWyD8sFhB4Xu41MYkLUZkEGqtIPEmDMY
zXtKbkPlyaviZVw3XsY1QrLsJLr96HrK9QkR9Fn6M1BKeD1MQ9DoeiDk0Bi1
zhQ4jMh5CIlA/YUIBUBkMrguOVLEgQnDviYcxZ7XBn1VY1CPHOMEwLoiWkbJ
BX8MkTas04QGMrgRcgbCYX+RAda1Uit+4TmKDJJq6zuPWY1InWb/HxDIOB+G
BavRMlWdXpMMrP5rNVlkDnaZaZ1qs5qvtclroUf211/+PzjgKYzDNpwuuapJ
K0Bl26W06Kcg0nAs1HXIOhSeCGybPcxXCCarjmPkNnjyohiv1Vg7ISSw81uG
Vlqp82nV/vM9Q3P/fT17lPczf6k+2nCnRI/TGzhreH+Io8x0rVVGeQ+71ktD
8pqWFvF7GIgk622A4SjwD7aJPv3OH+br4DTO0Bd06yilFR0U2TA4GkeTYqkV
zf5p7ovzYfFG8fCEP35d8zd8ILwcpHi3MZQfyElmsBuwJOG38Iv9E/O3ei8V
u6B4VRbxnj+rjUwf5sByZnzduEfATJGR1q5wNl7oRzDT8xpYKni5E3YX/bfo
Tr8Sc+jQOt8WG2WpM+14dsOsf6G+3WchGL7BPnwDyhS5gtCHe3ODz4CaCprF
lIS0KDA9erxvrORuyZQyysecewc2lZtkTrMiMkmBLcLXJ2ss4o2BsHq4xvql
Pwu8zw8COYKWh8y57EZ9yobqidW/QivcRNBF7hVj6pkC+56Llq7MUpGmpAk7
tmE0SsaiyIBqFaUjurVRyxNNZYYUDOHUfEUqG+lijpPQ0/jkvhSedS9mYIGe
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
lk2vBxCVZcQBgNknfZlL+yVpEwGv85I9UrjUK+2keVa3P9ixXorzuC5S6kol
pYWKtKZMPVLDRSgF4m0Uo46FLP8f3GUIJNqdcw4s/IhbjmiJyeXlmulLDusq
K8HQav61pZB9uMWXbfK9b77FP/cnk+OoouE4vUGqky6s3pjxu5rfLWeoPGSd
9qIVe0L2BMGbUhPIkHMFML93wQBLBAf+EQ2xGRSmQAfSOGGcFvFtQ/qHQ4cs
n8Sg9iQKVy43TyxKB8xtukh6RQvJoauHS/HmMQR+bAq8eGx0SP1EIhFQgZTk
t9qqGQITN67STHZJPy01BH862Md+aTwMlz02vWUP9oM+prwPeKzqeoJVLWyy
poP2gWukozPkIN3g2bVmezRViwTGot0lKL6euikMgrdK4eu/MwT4+/XfmVRB
+Bv1i59IWsTZT0X6E2o+RF2/fzuzj5FEWnGhOUxP4VQBjQTG0kYMsIAmmRdG
8ET+Cmt4XFDP42aQUOjwrRfAXFNtRlvux2aalbht2LyddZhgu0x9DnNkpmaK
17hcjGMeOa5eqkXqi6IrSA6Y0Q1X1gCJpGVIYVR4BasfUh6aaRSk9QmjZEB6
aSEzaUKCzKvFrDWCs1kVdwRy+f7MaJBM2xjYfO/gUScEVJHJKQR51zGbqmV+
5CGpYoUpSvbEKS5NWa4z5wUkNJsxcO1uLSc92BJghgJq96gdHKFXXRMeUP+T
ZClNg30XX7coXwq4RGJKZUjDLVksj+Wygvqz78/ddBMNuSg6tYvb3nki6XPj
+GpI/WWcB7/69/FXzrGSU1WW1zXnSqr5zTlZRig/zNnS8oEBV1TzJxBb2Wiw
fMVB58o3DJTd5SyIKifVahJLn1V5tXRar/IvZ3X5syq4/Ain1dulT35evdkf
5sQ6vp1DFtbiAlH170//yKnjb+IB1X5aDeS5l0atC9bXaS3OD6yclX7Qgp6V
b2Vda+hg0clcMLqOg2iZIiQ4XhVaHtjVSlEnLT0rC7DPqrp5Q7DzoZesncBV
As13jlZnvvu2rKjhL7Ssk6OXM3Q1edFTxhQd8KKpxC/Kj7X64MUPzqoU+7wk
o/zUrudbewxvgn/k6b75Pf/3QxOnBcpeZ8qWJ+W9EjVjHlMFDNluA4jKi08F
yh3dcygBfgJRNsszZ0sE1Xjn+DiZGng3WiWLvr+zz66+HMMKDf7B1OCzpA4T
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
cHAYQG6eKPzq64H6/x/XyTAKrCEEAA==

-->

</rfc>

