<?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 3.4.6) -->


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

<!ENTITY RFC7644 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7644.xml">
<!ENTITY I-D.ietf-scim-device-model SYSTEM "https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-scim-device-model.xml">
<!ENTITY I-D.ietf-asdf-sdf SYSTEM "https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-asdf-sdf.xml">
<!ENTITY RFC8259 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8259.xml">
<!ENTITY RFC8949 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8949.xml">
<!ENTITY RFC2119 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC8174 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml">
<!ENTITY RFC7643 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7643.xml">
<!ENTITY I-D.ietf-asdf-sdf-protocol-mapping SYSTEM "https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-asdf-sdf-protocol-mapping.xml">
<!ENTITY RFC9110 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9110.xml">
<!ENTITY RFC9457 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9457.xml">
<!ENTITY RFC4648 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4648.xml">
<!ENTITY RFC3986 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml">
<!ENTITY RFC6570 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6570.xml">
<!ENTITY RFC9562 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9562.xml">
<!ENTITY RFC7468 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7468.xml">
<!ENTITY RFC8610 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8610.xml">
<!ENTITY RFC5246 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5246.xml">
<!ENTITY RFC8446 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8446.xml">
<!ENTITY RFC6125 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6125.xml">
<!ENTITY RFC7525 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7525.xml">
<!ENTITY RFC7230 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7230.xml">
<!ENTITY RFC6749 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6749.xml">
<!ENTITY RFC7521 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7521.xml">
<!ENTITY RFC6750 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6750.xml">
<!ENTITY RFC6819 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6819.xml">
<!ENTITY RFC6265 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6265.xml">
<!ENTITY RFC8126 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8126.xml">
<!ENTITY RFC8615 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8615.xml">
<!ENTITY RFC7252 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7252.xml">
<!ENTITY RFC7942 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7942.xml">
]>


<rfc ipr="trust200902" docName="draft-ietf-asdf-nipc-16" 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="January" day="20"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 66?>

<t>This memo describes an API that allows applications to perform operations against a gateway serving one or more devices described by an SDF model. The document describes a RESTful application layer interface to perform 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 70?>

<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="144" width="688" viewBox="0 0 688 144" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
<path d="M 8,48 L 8,96" fill="none" stroke="black"/>
<path d="M 120,48 L 120,96" fill="none" stroke="black"/>
<path d="M 240,48 L 240,96" fill="none" stroke="black"/>
<path d="M 320,48 L 320,96" fill="none" stroke="black"/>
<path d="M 440,48 L 440,96" fill="none" stroke="black"/>
<path d="M 512,48 L 512,96" fill="none" stroke="black"/>
<path d="M 8,48 L 120,48" fill="none" stroke="black"/>
<path d="M 240,48 L 320,48" fill="none" stroke="black"/>
<path d="M 440,48 L 512,48" fill="none" stroke="black"/>
<path d="M 128,64 L 232,64" fill="none" stroke="black"/>
<path d="M 328,64 L 432,64" fill="none" stroke="black"/>
<path d="M 8,96 L 120,96" fill="none" stroke="black"/>
<path d="M 240,96 L 320,96" fill="none" stroke="black"/>
<path d="M 440,96 L 512,96" fill="none" stroke="black"/>
<polygon class="arrowhead" points="440,64 428,58.4 428,69.6" fill="black" transform="rotate(0,432,64)"/>
<polygon class="arrowhead" points="336,64 324,58.4 324,69.6" fill="black" transform="rotate(180,328,64)"/>
<polygon class="arrowhead" points="240,64 228,58.4 228,69.6" fill="black" transform="rotate(0,232,64)"/>
<polygon class="arrowhead" points="136,64 124,58.4 124,69.6" fill="black" transform="rotate(180,128,64)"/>
<g class="text">
<text x="64" y="68">Application</text>
<text x="280" y="68">Gateway</text>
<text x="476" y="68">Device</text>
<text x="176" y="84">Application</text>
<text x="380" y="84">Device</text>
<text x="176" y="100">network</text>
<text x="384" y="100">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.</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>
</list></t>

</section>
<section anchor="non-ip-gateway"><name>Non-IP 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, leveraging different protocols. These NIPC APIs consist of reading or writing properties of devices, invoking actions on devices, as well as enabling or disabling events on devices.</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 is its identity, in the form of a unique UUID and any credentials/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="I-D.ietf-scim-device-model"/>.</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, described in <xref target="I-D.ietf-asdf-sdf"/>.</t>
</list></t>

<t>Once these prerequisites are met, the gateway can resolve a referenced SDF affordance 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 a repository of device objects.</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 proxy traffic 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-IP Control, 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="I-D.ietf-asdf-sdf"/>.</t>
  <t>SDF Affordance: An interaction point on a device as defined in an SDF
model. Examples of affordances are properties, actions &amp; 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>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="I-D.ietf-scim-device-model"/>). 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="I-D.ietf-asdf-sdf"/> 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="432" viewBox="0 0 432 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="I-D.ietf-scim-device-model"/>, 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. Thsec SDF models define the protocol-neutral affordances of a class of devices, as well as protocol mappings that relate these affordances to protocol-specific operations. The SDF model fro a class of devices can be registered trough 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="I-D.ietf-scim-device-model"/> 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 SDF model registration. 
SDF models are described in <xref target="I-D.ietf-asdf-sdf"/>.</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 determine which data-streams are consumed by which 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="I-D.ietf-asdf-sdf"/>. 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 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 action or an event on one device to trigger an action on another device.</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>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="5" sectionFormat="of" target="RFC4648"/>.
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>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>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 action or an event on one device to trigger an action on another device. Triggers are not protocol-specific. As an example, an event on a BLE device can trigger an action on a Zigbee device.</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<br />
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",
    "/extensions/{id}/properties/write"
  ]
}
]]></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="I-D.ietf-asdf-sdf"/>. 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 hte 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.</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-u\
rl" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-ope\
ration-not-executed" /
  "https://www.iana.org/assignments/nipc-problem-types#sdf-model-alr\
eady-registered" /
  "https://www.iana.org/assignments/nipc-problem-types#sdf-model-in-\
use" /
  "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-writ\
e-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#event-already\
-enabled" /
  "https://www.iana.org/assignments/nipc-problem-types#event-not-ena\
bled" /
  "https://www.iana.org/assignments/nipc-problem-types#event-not-reg\
istered" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-already-connected" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-no-connection" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-connection-timeout" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-bonding-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-connection-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-service-discovery-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-invalid-service-or-characteristic" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-z\
igbee-connection-timeout" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-z\
igbee-invalid-endpoint-or-cluster" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-bro\
adcast-invalid-data" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-fir\
mware-rollback" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-fir\
mware-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#inval\
\id-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="I-D.ietf-asdf-sdf"/>.</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.</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.</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>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>
</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>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>
</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="I-D.ietf-scim-device-model"/>.</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/healthsenso\
r/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/healthsenso\
r/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 identical to the request body for the register data application API <xref target="register-data-app"/>.</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 &amp; 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="I-D.ietf-asdf-sdf"/>:</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>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="I-D.ietf-scim-device-model"/>). Affordances are referenced by their SDF global name (absolute URI with fragment) as described in <xref section="4" sectionFormat="of" target="I-D.ietf-asdf-sdf"/>.</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="5" 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. 
-or-</t>
  <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.
 -or-</t>
  <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="5" 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 5)
}

; 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.
-or-</t>
  <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 // FailureRespons\
e )

; 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#inv\
alid-property",
    "status": 400,
    "title": "Invalid Property",
    "detail": "Property https://example.com/heartrate#/sdfObject/the\
rmostat/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="5" 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
-or-</t>
  <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 = [* PropertyValueReadResponseArrayIt\
em]

PropertyValueReadResponseArrayItem = ( PropertyValue // FailureRespo\
nse )
]]></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>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?insta\
nceId=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 // FailureResp\
onse )

; Success item = { event, instanceId }
EventInstanceSuccess = {
  event: text,        ; SDF global name of the event (absolute URI w\
ith 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?instan\
ceId=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 FailureResponse
GroupEventStatusResponse = (GroupEventSuccessResponse // FailureResp\
onse)

; FailureResponse (Problem Details subset; align with your existing \
definition if present)
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#eve\
nt-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 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 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 FailureResponse
GroupEventStatusResponse = (GroupEventSuccessResponse // FailureResp\
onse)

; FailureResponse (Problem Details subset; align with your existing \
definition if present)
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#eve\
nt-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>
<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. 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?inst\
anceId=02ee282c-8915-4b2e-bbd2-88966773134a
]]></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>
<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 can be an action or an event. the global name of the trigger is passed as a path parameter.</t>

<t>The operation is always 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: "/devices/3171ec43-42a5-4415-ab4b-afd0dfbe9615/actions?actionName=https://example.com/AlarmSystem#/sdfObject/bell/sdfAction/ring"</t>

<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{?sdfName}</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.</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>sdfName: the sdfName of the affordance that is associated with the trigger. This can be either an event or an action. the event to enable. The sdfName must be a URL encoded string that is the absolute URI that is the global name of an <spanx style="verb">sdfEvent</spanx> or an <spanx style="verb">sdfAction</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?a\
ctionName=https%3A%2F%2Fexample.com%2FAlarmSystem%23%2FsdfObject%2Fb\
ell%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/trigger?inst\
anceId=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 event.</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 affordance and an action.
 - instanceId: must be the instance ID for each installed trigger, as returned by the NIPC GW when the trigger was created.
 - sdfName: 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="trigger_status_array.cddl"><![CDATA[
; Trigger status response array and item shape

TriggerStatusResponseArray = [* TriggerResponse]

TriggerResponse = {
  SdfReference,
  ? 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",
    "sdfName": "https://example.com/heartrate#/sdfObject/healthsenso\
r",
    "action": "/devices/3171ec43-42a5-4415-ab4b-afd0dfbe9615/actions\
?actionName=https%3A%2F%2Fexample.com%2FAlarmSystem%23%2FsdfObject%2\
Fbell%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{?sdfName}</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.</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>sdfName: the sdfName of the affordance that is associated with the trigger. This can be either an event or an action. the event to enable. The sdfName must be a URL encoded string that is the absolute URI that is the global name of an <spanx style="verb">sdfEvent</spanx> or an <spanx style="verb">sdfAction</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?ac\
tionName=https%3A%2F%2Fexample.com%2FAlarmSystem%23%2FsdfObject%2Fbe\
ll%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/trigger?inst\
anceId=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 event.</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
Query Parameters:</t>
  <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
Response:</t>
</list></t>

<t>The response must be an array of triggers, each containing an instanceId, the sdfName of an affordance and an action.
 - instanceId: must be the instance ID for each installed trigger, as returned by the NIPC GW when the trigger was created.
 - sdfName: 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="trigger_status_array.cddl"><![CDATA[
; Trigger status response array and item shape

TriggerStatusResponseArray = [* TriggerResponse]

TriggerResponse = {
  SdfReference,
  ? 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 group triggers response" anchor="exgetmgrouptriggers"><sourcecode type="json" markers="true"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

[
  {
    "instanceId": "02ee282c-8915-4b2e-bbd2-88966773134a",
    "sdfName": "https://example.com/heartrate#/sdfObject/healthsenso\
r",
    "action": "/devices/3171ec43-42a5-4415-ab4b-afd0dfbe9615/actions\
?actionName=https%3A%2F%2Fexample.com%2FAlarmSystem%23%2FsdfObject%2\
Fbell%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 ================

; CDDL translation of NIPC ProtocolInfo schemas (version 0.10.0)
; Source: nipc-openapi/protocolinfo/ProtocolInfo.yaml (+ BLE/Zigbee \
variants)

; 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,
    cacheExpiry?: int,
    autoUpdate?: bool,
    bonding?: bonding,
    ...
  },
  ...
}

bonding = "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"

ble-descriptor = {
  descriptorID?: uuid,
  ...
}

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

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

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

zigbee-cluster = {
  clusterID?: int,
  properties?: [* zigbee-property],
  ...
}

zigbee-property = {
  attributeID?: int,
  propertyType?: int,
  ...
}

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>

<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,
      "cacheExpiry": 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>"cacheExpiry" 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,
      "cacheExpiry": 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 mapping 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 200 OK with device ID on successful disconnect.</t>

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

<figure title="Example disconnect response" anchor="exdisconnresp"><sourcecode type="json" markers="true"><![CDATA[
{
  "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
}
]]></sourcecode></figure>

<t>where "id" is the ID of the device.</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>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>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="publishsubscribe-interface"><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-definition"><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>

<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 = (
  bleSubscription: BleSubscription //
  bleAdvertisement: BleAdvertisement //
  bleConnectionStatus: BleConnectionStatus //
  zigbeeSubscription: ZigbeeSubscription //
  rawPayload: RawPayload
)

BleSubscription = {
  serviceID: text,
  characteristicID: text
}

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

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

ZigbeeSubscription = {
  endpointID: int,
  clusterID: int,
  attributeID: int
  attributeType: int
}

RawPayload = {
  contextID: text
}
]]></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="Non-Onboarded BLE Device Advertisement"><artwork><![CDATA[
[
  {
    "data": h'02011A020A0C16FF4C001007721F41B0392078',
    "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": {
        "endpointID": 1,
        "clusterID": 6,
        "attributeID": 12,
        "type": 1
    }
  }
]
]]></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 200 OK
content-type: application/nipc+json

[
  {
    "sdfName": "https://example.com/thermometer#/sdfThing/thermom\
eter"
  }
]
]]></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?prop\
ertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2F\
thermometer%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/thermo\
meter/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/thermo\
meter/sdfProperty/device_name",
    "value": "dGVzdA=="
  }
]

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

[
  {
    "property": "https://example.com/thermometer#/sdfThing/thermo\
meter/sdfProperty/device_name",
    "value": "dGVzdA=="
  }
]
]]></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 200 OK
content-type: application/nipc+json

[
  {
    "sdfName": "https://example.com/thermometer#/sdfThing/thermom\
eter"
  }
]
]]></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": [
    "https://example.com/thermometer#/sdfThing/thermometer/sdfEve\
nt/isPresent"
  ],
  "mqttClient": true
}

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

{
  "events": [
    "https://example.com/thermometer#/sdfThing/thermometer/sdfEve\
nt/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?eventNa\
me=https%23%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermo\
meter%2FsdfEvent%2FisPresent
Host: localhost
Content-Length: 0

HTTP/1.1 201 Created
Location: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/events?in\
stanceId=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?instance\
Id=02ee282c-8915-4b2e-bbd2-88966773134a
Host: localhost

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

{
  "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 200 OK
content-type: application/nipc+json

[
  {
    "sdfName": "https://example.com/thermometer#/sdfThing/thermom\
eter"
  }
]
]]></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": [
    "https://example.com/thermometer#/sdfThing/thermometer/sdfEve\
nt/isPresent"
  ],
  "mqttClient": true
}

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

{
  "events": [
    "https://example.com/thermometer#/sdfThing/thermometer/sdfEve\
nt/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?eventNa\
me=https%23%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermo\
meter%2FsdfEvent%2FisPresent
Host: localhost
Content-Length: 0

HTTP/1.1 201 Created
Location: /groups/0dc729d7-f6c3-491d-9b9d-e7176d2be243/events?in\
stanceId=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?instance\
Id=f1b9f26b-21ce-4deb-9d57-289ba7e17cce
Host: localhost

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

[
  {
    "event": "https://example.com/heartrate#/sdfObject/healthsen\
sor/sdfEvent/fallDetected",
    "deviceId": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
  },
  {
    "event": "https://example.com/heartrate#/sdfObject/healthsen\
sor/sdfEvent/fallDetected",
    "deviceId": "d62c7fb2-a216-4811-a388-053b17fdbedc"
  },
  {
    "event": "https://example.com/heartrate#/sdfObject/healthsen\
sor/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-e\
3c1-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-16</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-16</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 Section 3.2 of <xref 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>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 the <xref target="security-considerations"/> section 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:</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:</t>

<t>Change controller: IETF</t>

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

<t>IANA is requested to create a new registry called "NIPC API extensions".</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-well-known"><name>Well-known URIs</name>

<t>IANA is requested to register the following well-known URI in the "Well-Known URIs" registry 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-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>Registrations MUST use the prefix <eref target="&quot;https://iana.org/assignments/nipc-problem-types#&quot;"></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#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-broadcast-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">

&RFC7644;
&I-D.ietf-scim-device-model;
&I-D.ietf-asdf-sdf;
&RFC8259;
&RFC8949;
&RFC2119;
&RFC8174;
&RFC7643;
&I-D.ietf-asdf-sdf-protocol-mapping;
&RFC9110;
&RFC9457;
&RFC4648;
&RFC3986;
&RFC6570;
&RFC9562;
&RFC7468;
&RFC8610;
&RFC5246;
&RFC8446;
&RFC6125;
&RFC7525;
&RFC7230;
&RFC6749;
&RFC7521;
&RFC6750;
&RFC6819;
&RFC6265;
&RFC8126;
&RFC8615;


    </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>
&RFC7252;
&RFC7942;


    </references>

</references>


<?line 2932?>

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

<t>The following non-normative model is provided for convenience of the implementor.</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-1\
\2/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.16.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-16"
    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/thermos\
\tat/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/PropertyValueRespons\
\eArray'
        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/therm\
\ostat/sdfProperty/temperature"
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf: 
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/PropertyValueReadRes\
\ponseArray'
            "*/*":
              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/healths\
\ensor/sdfEvent/fallDetected"
      responses:
        '201':
          description: Success
          headers:
            Location:
              description: Location of the created event
              schema:
                type: string
                format: uri
                example: "/devices/{id}/events?instanceId={instanceI\
\d}"
        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 disab\
\led
        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 devi\
\ce
      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/healths\
\ensor/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 disab\
\led
        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/GroupEventStatusResponse\
\Array'
        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 devi\
\ces.
      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/GroupEventStatusResponse\
\Array'
        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/healths\
\ensor/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={instance\
\Id}"
        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/healths\
\ensor/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={instanceI\
\d}"
        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 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/GroupActionStatusRespons\
\eArray'
        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 devic\
\es
      operationId: CreateTrigger
      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: sdfName
        in: query
        description: |-
          sdf affordance that will trigger this action, this can be 
          either an event or an action
        required: true
        allowReserved: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/healths\
\ensor/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={instanc\
\eId}"
        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: GetTrigger
      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 action 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/TriggerStatusResponseArr\
\ay'
        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: DeteteTrigger
      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 action 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: CreateTrigger
      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: sdfName
        in: query
        description: |-
          sdf affordance that will trigger this action, this can be 
          either an event or an action
        required: true
        allowReserved: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/healths\
\ensor/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 execu\
\ted 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: "/devices/{id}/triggers?instanceId={instanc\
\eId}"
        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: GetTrigger
      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 action 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/TriggerResponse'
        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: DeteteTrigger
      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: false
        schema:
          type: string
          format: uuid
          example: 02ee282c-8915-4b2e-bbd2-88966773134a
      responses:
        '200':
          description: Success, trigger deleted
          content:
            application/nipc+json:
              schema:
                $ref: '#/components/schemas/TriggerStatusResponseArr\
\ay'
        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#/component\
\s/schemas/ProtocolInfo-ServiceMap'
            example:
              retries: 3
              protocolInformation:
                ble:
                  services:
                    - serviceID: "00001809-0000-1000-8000-00805f9b34\
\fb"
                  cached: true
                  cacheExpiryDuration: 3600
        required: false
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: './protocolinfo/ProtocolInfo.yaml#/compone\
\nts/schemas/ProtocolInfo-ServiceMap'
              example:
                id: "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
                protocolInformation:
                  ble:
                    services:
                      - serviceID: "00001809-0000-1000-8000-00805f9b\
\34fb"
                        characteristics:
                          - characteristicID: "00002a19-0000-1000-80\
\00-00805f9b34fb"
                            flags: ["read", "notify"]
                            descriptors:
                              - descriptorID: "00002902-0000-1000-80\
\00-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/sc\
\hemas/ProtocolInfo-ServiceMap'
            example:
              retries: 3
              protocolInformation:
                ble:
                  services:
                    - serviceID: "00001809-0000-1000-8000-00805f9b34\
\fb"
                  cached: true
                  cacheExpiryDuration: 3600
        required: false
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: './protocolinfo/ProtocolInfo.yaml#/compone\
\nts/schemas/ProtocolInfo-ServiceMap'
              example:
                id: "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
                protocolInformation:
                  ble:
                    services:
                      - serviceID: "00001809-0000-1000-8000-00805f9b\
\34fb"
                        characteristics:
                          - characteristicID: "00002a19-0000-1000-80\
\00-00805f9b34fb"
                            flags: ["read", "notify"]
                            descriptors:
                              - descriptorID: "00002902-0000-1000-80\
\00-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:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
        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#/compone\
\nts/schemas/ProtocolInfo-ServiceMap'
              example:
                id: "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
                protocolInformation:
                  ble:
                    services:
                      - serviceID: "00001809-0000-1000-8000-00805f9b\
\34fb"
                        characteristics:
                          - characteristicID: "00002a19-0000-1000-80\
\00-00805f9b34fb"
                            flags: ["read", "notify"]
                            descriptors:
                              - descriptorID: "00002902-0000-1000-80\
\00-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:
        '200':
          description: Success
          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 all registered SDF model names
      description: |-
        Get all registered SDF model names.
      operationId: getSdfRefs
      parameters:
        - name: sdfName
          in: query
          description: |-
            sdfName can be a reference to an sdfThing or sdfObject
          required: false
          allowReserved: true
          schema:
            type: string
            example: "https://example.com/heartrate#/sdfObject/healt\
\hsensor"
      responses:
        '200':
          description: Success
          content:
            application/sdf+json:
              schema:
                $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/healt\
\hsensor"
      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/healt\
\hsensor"
      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:
        '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'

    put:
      tags:
        - NIPC registration APIs
      summary: Update registration of a dataApp
      description: |-
        Update registration of a dataApp that is able to receive dev\
\ice 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:
        '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'
  
    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/thermos\
\tat/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/healthse\
\nsor/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/act\
\ions?actionName=https%3A%2F%2Fexample.com%2FAlarmSystem%23%2FsdfObj\
\ect%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/healths\
\ensor"
    
    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:
                  sdfOutputData:
                    sdfProtocolMap:
                      ble:
                        type: advertisement
              sdfObject:
                healthsensor:
                  sdfProperty:
                    heartrate:
                      sdfProtocolMap:
                        ble:
                          serviceID: 00001809-0000-1000-8000-00805f9\
\b34fb
                          characteristicID: 00002a1c-0000-1000-8000-\
\00805f9b34fb
                  sdfEvent:
                    fallDetected:
                      sdfOutputData:
                        sdfProtocolMap:
                          ble:
                            serviceID: 00001809-0000-1000-8000-00805\
\f9b34fb
                            characteristicID: 00002a1c-0000-1000-800\
\0-00805f9b34fb
                  sdfAction:
                    start:
                      sdfProtocolMap:
                        ble:
                          serviceID: 00001809-0000-1000-8000-00805f9\
\b34fb
                          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-0080\
\5f9b34fb
              sdfEvent:
                fallDetected:
                  sdfOutputData:
                    sdfProtocolMap:
                      ble:
                        type: advertisements
              sdfAction:
                start:
                  sdfProtocolMap:
                    ble:
                      serviceID: 00001809-0000-1000-8000-00805f9b34fb
                      characteristicID: 00002a1c-0000-1000-8000-0080\
\5f9b34fb

    SdfProperty:
      type: object
      description: Sample SDF property
      properties:
        sdfProperty:
          additionalProperties: 
            allOf:
              - $ref: './protocolmaps/ProtocolMap.yaml#/components/s\
\chemas/ProtocolMap'
          example:
            heartrate:
              sdfProtocolMap:
                ble:
                  serviceID: 00001809-0000-1000-8000-00805f9b34fb
                  characteristicID: 00002a1c-0000-1000-8000-00805f9b\
\34fb
          
    SdfEvent:
      type: object
      description: Sample SDF property
      properties:
        sdfEvent:
          additionalProperties: #example, this will be the registere\
\d event
            type: object
            properties:
              sdfOutputData:
                allOf:
                  - $ref: './protocolmaps/ProtocolMap.yaml#/componen\
\ts/schemas/ProtocolMap'
          example:
            fallDetected:
              sdfOutputData:
                sdfProtocolMap:
                  ble:
                    serviceID: 00001809-0000-1000-8000-00805f9b34fb
                    characteristicID: 00002a1c-0000-1000-8000-00805f\
\9b34fb
    
    SdfAction:
      type: object
      description: Sample SDF property
      properties:
        sdfAction:
          additionalProperties: 
            allOf:
              - $ref: './protocolmaps/ProtocolMap.yaml#/components/s\
\chemas/ProtocolMap'
          example:
            start:
              sdfProtocolMap:
                ble:
                  serviceID: 00001809-0000-1000-8000-00805f9b34fb
                  characteristicID: 00002a1c-0000-1000-8000-00805f9b\
\34fb

# 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#in\
\valid-id
            - https://www.iana.org/assignments/nipc-problem-types#in\
\valid-sdf-url
            - https://www.iana.org/assignments/nipc-problem-types#ex\
\tension-operation-not-executed
            - https://www.iana.org/assignments/nipc-problem-types#sd\
\f-model-already-registered
            - https://www.iana.org/assignments/nipc-problem-types#sd\
\f-model-in-use
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\operty-not-readable
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\operty-read-failed
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\operty-not-writable
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\operty-write-failed
            - https://www.iana.org/assignments/nipc-problem-types#ev\
\ent-already-enabled
            - https://www.iana.org/assignments/nipc-problem-types#ev\
\ent-not-enabled
            - https://www.iana.org/assignments/nipc-problem-types#ev\
\ent-not-registered
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\otocolmap-ble-already-connected
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\otocolmap-ble-no-connection
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\otocolmap-ble-connection-timeout
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\otocolmap-ble-bonding-failed
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\otocolmap-ble-connection-failed
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\otocolmap-ble-service-discovery-failed
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\otocolmap-ble-invalid-service-or-characteristic
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\otocolmap-zigbee-connection-timeout
            - https://www.iana.org/assignments/nipc-problem-types#pr\
\otocolmap-zigbee-invalid-endpoint-or-cluster
            - https://www.iana.org/assignments/nipc-problem-types#ex\
\tension-broadcast-invalid-data
            - https://www.iana.org/assignments/nipc-problem-types#ex\
\tension-firmware-rollback
            - https://www.iana.org/assignments/nipc-problem-types#ex\
\tension-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/PropertyValueReadResponseArr\
\ayItem'

## 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
        - $ref: '#/components/schemas/FailureResponse'

    GroupEventStatusResponseArray:
      type: array
      items:
          $ref: '#/components/schemas/GroupEventStatusResponse'
    
    ActionResponse:
      required:
        - action
      type: object
      properties:
        status:
          type: string
          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/InstanceId'
        - $ref: '#/components/schemas/SdfReference'
        - $ref: '#/components/schemas/Action'

    TriggerStatusResponseArray:
      type: array
      items:
          $ref: '#/components/schemas/TriggerResponse'  
<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 pr\
otocol 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/Pro\
tocolInfo-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/Pro\
tocolInfo-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-Ser\
vice'
            cached:
              description: |-
                If we can cache information, then device doesn't need
                to be rediscovered before every connected.
              type: boolean
              default: false
            cacheExpiry:
              description: cache expiry period in seconds, when devi\
ce 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-Characteris\
tic'

    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
        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-Endp\
oint'

    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
        properties:
          type: array
          items:
            $ref: '#/components/schemas/ProtocolInfo-Zigbee-Property'

    ProtocolInfo-Zigbee-Property:
      type: object
      properties:
        attributeID:
          type: integer
          format: int32
          example: 1
        propertyType:
          type: integer
          format: int32
          example: 32
          
## 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-1\
2/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.16.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-16"
    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/thermos\
tat/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/FailureRespo\
nse' 

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-1\
2/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.16.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-16"
    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-bcdbe0a\
32e30/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/FailureRespo\
nse"
      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-Bulk\
Response"
              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-BulkRespon\
se"
              examples:
                bulkResponse:
                  $ref: "#/components/examples/bulkResponse"
                firmwareUpgradeResponse:
                  $ref: "#/components/examples/firmwareUpgradeRespon\
se"
                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/schema\
s/Extension-StatusResponse"
        "303":
          description: See Other
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
32e30/bulk?instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
              description: URL to get the bulk response
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./Extension-Async.yaml#/components/schema\
s/Extension-StatusResponse"
              examples:
                successExample:
                  summary: Success
                  value:
                    status: COMPLETED

components:
  schemas:
    # Extensions
    ## Bulk schema Extension
    Extension-Bulk:
      allOf:
        - $ref: "./Extension-Async.yaml#/components/schemas/Extensio\
n-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, th\
e 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={propertyNam\
e}
                - /devices/{id}/actions/?actionName={actionName}
                - /extensions/{id}/properties/read/conditional?prope\
rtyName={propertyName}
                - /extensions/{id}/events/conditional?eventName={eve\
ntName}
                - /extensions/{id}/properties/file?propertyName={pro\
pertyName}
              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#/component\
s/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={propertyNam\
e}
                - /devices/{id}/actions/?actionName={actionName}
                - /extensions/{id}/properties/read/conditional?prope\
rtyName={propertyName}
                - /extensions/{id}/events/conditional?eventName={eve\
ntName}
              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/SuccessRes\
ponse"
                - $ref: "../NIPC.yaml#/components/schemas/FailureRes\
ponse"

  examples:
    bulkRequest:
      summary: Bulk request example
      value:
        operations:
          - method: GET
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%2Fthermometer%2FsdfProperty%2Ftemperature
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%2Fthermometer%2FsdfProperty%2Ftemperature
            data:
              value: dGVzdA==
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/p\
roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\
thermometer%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/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              value: dGVzdA==
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              status: 200
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/p\
roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\
thermometer%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/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              type: https://www.iana.org/assignments/nipc-problem-ty\
pes#property-not-readable
              status: 400
              title: Property not readable
              detail: Property https://example.com/thermometer#/sdfT\
hing/thermometer/sdfProperty/temperature is not readable
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              type: https://www.iana.org/assignments/nipc-problem-ty\
pes#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/p\
roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\
thermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              type: https://www.iana.org/assignments/nipc-problem-ty\
pes#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/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%2Fthermometer%2FsdfProperty%2FstartOTA
            data:
              value: dGVzdA==
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/e\
vents/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/p\
roperties/file?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%\
23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ffirmware
            data:
              fileURL: https://example.com/firmware.bin
              chunkSize: 20
              sha256Checksum: abcdef1234567890abcdef1234567890abcdef\
1234567890abcdef1234567890
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%2Fthermometer%2FsdfProperty%2FfinishOTA
            data:
              value: dGVzdA==
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/p\
roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\
thermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2FupdateStatus
            data:
              value: MQ==
              maxRepeat: 5
              retryTime: 1
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%2Fthermometer%2FsdfProperty%2FactivateOTA
            data:
              value: dGVzdA==
    firmwareUpgradeResponse:
      summary: Firmware upgrade response example
      value:
        operations:
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%2Fthermometer%2FsdfProperty%2FstartOTA
            response:
              status: 200
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/e\
vents/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/p\
roperties/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/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%2Fthermometer%2FsdfProperty%2FfinishOTA
            response:
              status: 200
          - method: POST
            path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/p\
roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\
thermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2FupdateStatus
            response:
              value: MQ==
          - method: PUT
            path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Thing%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-1\
\2/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.16.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-16"
    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/thermos\
\tat/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-bcdbe0a\
\32e30/properties/file/status?propertyName=https%3A%2F%2Fexample.com\
\%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2Ffirmware&i\
\nstanceId=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/FailureRespo\
\nse'
      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/Fa\
\ilureResponse'
                    examples:
                      successExample:
                        summary: Success
                        value:
                          id: 02ee282c-8915-4b2e-bbd2-88966773134a
                          property: https://example.com/heartrate#/s\
\dfObject/thermostat/sdfProperty/firmware
                      failedResponse:
                        summary: Failed
                        value:
                          id: 02ee282c-8915-4b2e-bbd2-88966773134a
                          status: 400
                          type: https://www.iana.org/assignments/nip\
\c-problem-types#invalid-id
                          title: Invalid ID
                          detail: "Invalid request"
                          property: https://example.com/heartrate#/s\
\dfObject/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/thermos\
\tat/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/FailureRespo\
\nse'
  /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/thermos\
\tat/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/Ex\
\tension-StatusResponse'
        '303':
          description: See Other
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
\32e30/properties/file?propertyName=https%3A%2F%2Fexample.com%2Fhear\
\trate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2Ffirmware&instance\
\Id=02ee282c-8915-4b2e-bbd2-88966773134a
              description: URL to get the file write response
          content:
            application/json:
              schema:
                $ref: './Extension-Async.yaml#/components/schemas/Ex\
\tension-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-1\
2/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.16.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-16"
    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-bcdbe0a\
32e30/properties/read/conditional/status?propertyName=https%3A%2F%2F\
example.com%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2F\
temperature&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/FailureRespo\
nse'
      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/Fa\
ilureResponse'
                    examples:
                      successExample:
                        summary: Success
                        value:
                          id: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
                          property: https://example.com/heartrate#/s\
dfObject/thermostat/sdfProperty/temperature
                          value: dGVzdA==
                      failedResponse:
                        summary: Failed
                        value:
                          id: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
                          status: 400
                          type: https://www.iana.org/assignments/nip\
c-problem-types#invalid-id
                          title: Invalid ID
                          detail: "Invalid request"
                          property: https://example.com/heartrate#/s\
dfObject/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/FailureR\
esponse'
  /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/Ex\
tension-StatusResponse'
        '303':
          description: See Other
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
32e30/properties/read/conditional?propertyName=https%3A%2F%2Fexample\
.com%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2Ftempera\
ture&instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
              description: URL to get the conditional read response
          content:
            application/json:
              schema:
                $ref: './Extension-Async.yaml#/components/schemas/Ex\
tension-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/Extensio\
n-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-1\
2/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.16.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-16"
    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-bcdbe0a\
32e30/events/conditional/status?eventName=https%3A%2F%2Fexample.com%\
2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfEvent%2Ftemperature&ins\
tanceId=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/FailureRespo\
nse'
      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/Fa\
ilureResponse'
                    examples:
                      successExample:
                        summary: Success
                        value:
                          id: 02ee282c-8915-4b2e-bbd2-88966773134a
                          event: https://example.com/heartrate#/sdfO\
bject/thermostat/sdfEvent/temperature
                          value: dGVzdA==
                      failedResponse:
                        summary: Failed
                        value:
                          id: 02ee282c-8915-4b2e-bbd2-88966773134a
                          status: 400
                          type: https://www.iana.org/assignments/nip\
c-problem-types#invalid-id
                          title: Invalid ID
                          detail: "Invalid request"
                          event: https://example.com/heartrate#/sdfO\
bject/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/FailureR\
esponse'
  /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/Ex\
tension-StatusResponse'
        '303':
          description: See Other
          headers:
            Location:
              schema:
                type: string
                example: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
32e30/events/conditional?eventName=https%3A%2F%2Fexample.com%2Fheart\
rate%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/Ex\
tension-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/Extensio\
n-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-Property.yaml"><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

# yaml-language-server: $schema=https://json-schema.org/draft/2020-1\
2/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.16.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-16"
    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 performe\
d 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/FailureRespo\
nse'
   
  /extensions/{id}/properties/write:
    post:
      tags:
        - NIPC API extensions
      summary: Write a value to an property using protocol mapping
      description: |-
        Write a value to an unregistered property, embedding property
        protocol mapping in the API, this does not require
        property registration. You cannot write to a group id.
      operationId: ActionPropWrite
      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:
              allOf:
                - $ref: '../NIPC.yaml#/components/schemas/Value' 
                - $ref: '../protocolmaps/ProtocolMap.yaml#/component\
s/schemas/ProtocolMap-Property'
        required: true
      responses:
        '204':
          description: Success, no content
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '../NIPC.yaml#/components/schemas/FailureRespo\
nse'
                
  /extensions/{id}/properties/read:
    post:
      tags:
        - NIPC API extensions
      summary: Read a value to an property using protocol mapping
      description: |-
        Read a value from an unregistered property, embedding 
        property protocol mapping in the API, this does not require
        property registration. You cannot read from a group id.
      operationId: ActionPropRead
      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: '../protocolmaps/ProtocolMap.yaml#/components/sc\
hemas/ProtocolMap-Property'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                allOf: 
                  - $ref: '../NIPC.yaml#/components/schemas/Value'
        default:
          description: Error response
          content:
            application/problem+json:
              schema:
                $ref: '../NIPC.yaml#/components/schemas/FailureRespo\
nse'

components:
  schemas:
    Transmit:
      allOf:
        - $ref: '../protocolinfo/ProtocolInfo.yaml#/components/schem\
as/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 // FailureResp\
onse )

; Success item = { event, instanceId }
EventInstanceSuccess = {
  event: text,        ; SDF global name of the event (absolute URI w\
ith 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-u\
rl" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-ope\
ration-not-executed" /
  "https://www.iana.org/assignments/nipc-problem-types#sdf-model-alr\
eady-registered" /
  "https://www.iana.org/assignments/nipc-problem-types#sdf-model-in-\
use" /
  "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-writ\
e-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#event-already\
-enabled" /
  "https://www.iana.org/assignments/nipc-problem-types#event-not-ena\
bled" /
  "https://www.iana.org/assignments/nipc-problem-types#event-not-reg\
istered" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-already-connected" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-no-connection" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-connection-timeout" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-bonding-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-connection-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-service-discovery-failed" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
le-invalid-service-or-characteristic" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-z\
igbee-connection-timeout" /
  "https://www.iana.org/assignments/nipc-problem-types#protocolmap-z\
igbee-invalid-endpoint-or-cluster" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-bro\
adcast-invalid-data" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-fir\
mware-rollback" /
  "https://www.iana.org/assignments/nipc-problem-types#extension-fir\
mware-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 FailureResponse
GroupEventStatusResponse = (GroupEventSuccessResponse // FailureResp\
onse)

; FailureResponse (Problem Details subset; align with your existing \
definition if present)
GroupFailureResponse = {
  FailureResponse,
  ? deviceId: text
}
; ============================================
; From: cddl/api/trigger_status_array.cddl
; ============================================
; Trigger status response array and item shape

TriggerStatusResponseArray = [* TriggerResponse]

TriggerResponse = {
  SdfReference,
  ? 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 5)
}

; Helper type for base64-with-padding encoded text
b64text = text
; ============================================
; From: cddl/api/property_value_read_response_array.cddl
; ============================================
PropertyValueReadResponseArray = [* PropertyValueReadResponseArrayIt\
em]

PropertyValueReadResponseArrayItem = ( PropertyValue // FailureRespo\
nse )

; ============================================
; From: cddl/api/property_value_response_array.cddl
; ============================================
PropertyValueResponseArray = [* PropertyValueResponseArrayItem]

PropertyValueResponseArrayItem = ( SuccessResponse // FailureRespons\
e )

; 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,
  ? retryMultipleAPs: bool,
  ? protocolInformation: ProtocolInformation
}

ConnectionResponse = {
  id: text,  ; UUID of the connection
  ? protocolInformation: ProtocolInformation
}

ProtocolInformation = {
  ? ble: BLEProtocolInfo,
  ? zigbee: ZigbeeProtocolInfo
}

; BLE Protocol Information
BLEProtocolInfo = {
  ? services: [* BLEService],
  ? cached: bool,              ; default: false
  ? cacheExpiryDuration: uint, ; in seconds, default: 3600
  ? autoUpdate: bool,          ; default: true
  ? bonding: BondingType
}

BLEService = {
  serviceID: text,  ; UUID format
  ? characteristics: [* BLECharacteristic]
}

BLECharacteristic = {
  characteristicID: text,  ; UUID format
  ? flags: [* BLEFlag],
  ? descriptors: [* BLEDescriptor]
}

BLEDescriptor = {
  descriptorID: text  ; UUID format
}

BLEFlag = (
  "read" /
  "write" /
  "notify"
)

BondingType = (
  "default" /
  "none" /
  "justworks" /
  "passkey" /
  "oob"
)

; Zigbee Protocol Information
ZigbeeProtocolInfo = {
  ? endpoints: [* ZigbeeEndpoint]
}

ZigbeeEndpoint = {
  endpointID: uint,
  ? clusters: [* ZigbeeCluster]
}

ZigbeeCluster = {
  clusterID: uint,
  ? properties: [* ZigbeeProperty]
}

ZigbeeProperty = {
  attributeID: uint,
  propertyType: uint,
}

; ============================================
; From: cddl/api/protocolinfo.cddl
; ============================================
; CDDL translation of NIPC ProtocolInfo schemas (version 0.10.0)
; Source: nipc-openapi/protocolinfo/ProtocolInfo.yaml (+ BLE/Zigbee \
variants)

; 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,
    cacheExpiry?: int,
    autoUpdate?: bool,
    bonding?: bonding,
    ...
  },
  ...
}

bonding = "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"

ble-descriptor = {
  descriptorID?: uuid,
  ...
}

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

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

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

zigbee-cluster = {
  clusterID?: int,
  properties?: [* zigbee-property],
  ...
}

zigbee-property = {
  attributeID?: int,
  propertyType?: int,
  ...
}

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",
              "sdfOutputData": {
                "sdfProtocolMap": {
                  "ble": {
                    "type": "gatt",
                    "serviceID": "1809",
                    "characteristicID": "2A1C"
                  }
                }
              }
            },
            "intermediate_temperature": {
              "description": "Intermediate Temperature",
              "sdfOutputData": {
                "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",
          "sdfOutputData": {
            "sdfProtocolMap": {
              "ble": {
                "type": "advertisements"
              }
            }
          }
        },
        "isConnected": {
          "description": "BLE connection events",
          "sdfOutputData": {
            "sdfProtocolMap": {
              "ble": {
                "type": "connection_events"
              }
            }
          }
        }
      }
    }
  }
}
]]></sourcecode></figure>

</section>


  </back>

<!-- ##markdown-source:
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
PM+G2aToX6Hbmmcl5dXm029lN8SjeX5jsQDaCM04ae0TLbqYRKPWcuyFkbpW
41KPM83FTnse9Jc1Elvw3dqPQo4V6U3vgmhxRwo8yvsEHA8wM2/AzVmeoa3t
G4Bbfe3hz/UcypnM4GaVzDP1zlK6XLiVHEqW2PEWy/kVSyiVL2EebEx7FC95
Kgqfz5Ksq7Fi/JKFdoztdf9G4R3zvB29/v747ZsXbw9PTqSI7v6bV8doxz+4
QwldXtsNFXRn1R9R+cOdTTULnCAUNa5j5h6IF+TcoO6encGRlHwj/Jek2okz
rmHbHU8iUnE5KQruquWIbtqZGp+LRtiZyG1Vv4+JcmQ8UkZzm6V/6LJrSs4h
LZNYYjaML64d+wwzkMmsMLmCnb/QNxlXHHhlSmaahTdPN/WsSX2TShpa8nQ2
ISWSsEbXooFT9vxa5bNV5x83dj7G6BSQYJP6gUIeyS6ZJBSQfwo7XCs8SfEQ
2/FlQgoZky2nkxEXUkGMImgIEg1vSqboiE05bZNmUR8KSeyiAkoJOjISlcPC
U7RBTQARCPfo1jZzZ+rxcjgWhrBukiy8tdnc2oiAZm8B4Y46W51m1IvX4l4n
2d1ef2yovRVfvqrTZvb6UT44uQJsGrj6TCfp91dN3qVVvGxeEndULzORAYob
2KCxA2PKgFPGDIWAc1YkPMp0hsY6I/6Sq7SicoktyOb5X0dOymrtBeQVvmtU
L27/3hG95KUvnKXOuDTaf1KVdms1In5IV7fOKj3fu1lSrq5pel0y7rsode7m
zGKiqlm89kw78vuuX8WQg8dmxiTc3efWq4Qmfxiuaqdv8qsWRdZNrSeBcwD9
eMySNUuIix79qZ4UOoOHde6V2fxgzo24V7jKQRjWJtPUiSGIUPr/ojYs8wuT
J8/Ei3adLJMerammwZ9KZtgqa6InSuwrjZ20f7RuyellsouUYgxx0WVpxcS0
czfqt/WUJ6VTNoQdt4+nd3sDnSDF1HQihizhKcM5PVhWX57J0u1J+LugRMT/
dXPvXzeew/85pBz+coj5v25swgND0OF3510ARJ0f8qbAbybsVSmL/WuMfOKL
WGXILZLg4yHc3Y308CtxeJf13F5Ru7U7VRmSd/V516Sws5ljreO7ZY+z3Ihs
rV0r3cqXd2dic2iI5oTc7gLP8OuosAu4L193gs2iru4VMOo9aWXXqrr+XFum
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
7MnjztZCVP22SCQ7tETA8UPtFt95JYdAs3g5w/FqWhyzCVuRwaZJGfxtPGYP
X1+tvTtGf5LL8rC/yURektJ6Zl6as0XTB8DShcQMBuHX9J/XkTI+kVxJLl1I
cq3wT35NbA5+GrjW4qx7Il4mw7PxeTtcq+CLLX2IL25b/lDWnQ55rlocab4K
iGbzaKv3qVCh46ItpuPSTv/SqopZMa+V173Iiu9fg/AP8q3YET7lpawqnpVP
r3c2p8tfL7SK3YFWZ5wqifF1fkXWCquyVlBfU/AWItcxOu2T74Rn3PlZJa3i
s6j1WdT6LGp9FrV+2WV52H+TqDWtHLB28gC4KzVp1+LuzsZuvNPsbXc3m1u7
63Fzt7MbN5Od9Z3teKOTbGxt/prkr1ssuyJ+9dY7u72N7U5zY72bNLfipNPc
jR/vNDee7HainWR9p9tNPhnx61YLLklfcy/4Z7HfzpTDZlf6lI3MciuH9aJ+
/wCQkK42HXuZ3DYukByKP/zY+BRmHG9vdHd6nY1mtLG+3dx6sr4OfOfJk+ba
483O+k4Pph13P60Zr613Hm9EG5vNzu6TLsB4C3hmtJs0155sR1ubnbgX7+zO
mrFcrpoJX15etjBospXlZ6tRgclXyC2VEMxEUpJbLM/4USVkxJ1qobfnWzZl
Kt0tjyn30hLL6K+zsVD6qevcpWKysCnJJmDQVrfba0YxLXsjWo82e2vbu6Vv
MdYTv3zOjstONXUr5zhBFXaAd8GMIaYLa4/CI5OJhpQE9hwIrts5COIXSTrM
e12b6Me7hcbouTwuSpSOvTdTr1clgaYMoJ+6tVLzMeJUMXiZT2Vl0J0JQ8h7
ATUmNWKYjJsHedQbN9T31qQi5fuUrCCfT5uXJbi+/hpo6M7u1gb6yVI0bOwE
QsJI5WmX68uCjoLe1sOY9wZRreC5Hh2ePsfm6RiddLusGME0MLUZ+V0GGghO
Ttg4cbp+hwkVMBfJRQQImbAlHPvEyum8bowUCpzSsv482RvYFCPClxhMFWe5
yB2cIDfAOcJYzyc5c+U8wQoX6MaMKTTOIwBhwiXkyUUW82akPf7UzVdtfURp
XJouxh1qZXYcjsBBlVzRtSHDxMtaEYKmqECMJAKYgqXxTYciMdCnTdMnQYMA
8CLqZwwJTe9WxbFcsh30QBqgMOKQ7m6xIhldU8Sgr3KvFs4ZBceXu8KkC8mP
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
CkhZRXNaCzrx/wFqoBoI1c8DAA==

-->

</rfc>

