<?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.29 (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-15" 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="2025" month="December" day="02"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 61?>

<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>



  </front>

  <middle>


<?line 65?>

<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 device is onboarded (its identity and any credentials/trust material are provisioned). Onboarding 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 registered with 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 onboarded 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 Onboarding: Registration of a device identity and metadata before NIPC operations.</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>Device onboarding: The device identity and required trust material are provisioned (e.g., via SCIM <xref target="RFC7644"/> with <xref target="I-D.ietf-scim-device-model"/>). This yields the device ID referenced in NIPC API paths.</t>
  <t>Interaction model: 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>
<section anchor="onboarding"><name>Onboarding</name>

<t>Onboarding is the process of declaring a device’s identity to the NIPC gateway and provisioning the trust material required to communicate with the device. The device object MUST include sufficient information to bootstrap trust and establish connectivity, as NIPC operations assume connectivity can be established without separate API calls. While onboarding 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="registrations"><name>Registrations</name>

<t>NIPC registration APIs allow applications to declare information about a device class or authorize a data application. These APIs do not operate on specific devices or groups of devices.</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.
Optionally, the SDF model reference and/or data‑app registration MAY be included in the 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>
</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 three 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>
</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 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="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"><![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"><![CDATA[
NipcWellKnown = {
  base_path: text,
  ? versions: [* uri / text],
  ? extensions: [* uri / text]
}
]]></sourcecode></figure>

</section>
<section anchor="nipc-registrations"><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>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 during onboarding (e.g., by a SCIM server). The identifier is returned when the device object is created and is used by both the application and the NIPC gateway. The application must store this UUID in order to use it to identify the device on which it wants to perform NIPC operations.
If the NIPC gateway is not co‑located with the SCIM server, it retrieves the device object from SCIM using this ID.</t>

</section>
</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 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"><![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"><artwork><![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"
}
]]></artwork></figure>

</section>
</section>
</section>
<section anchor="nipc-registrations-1"><name>NIPC Registrations</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"><![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"><artwork><![CDATA[
[
 {
  "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
 }
]
]]></artwork></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"><![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"><artwork><![CDATA[
[
 {
  "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
 },
 {
  "sdfName": "https://example.com/thermometer#/sdfObject/thermometer"
 }
]
]]></artwork></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"><![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"><![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"><![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"><![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"><![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"><artwork><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

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

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

<figure title="Example with mqttBroker" anchor="exregmqttbrokerrsp"><artwork><![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"
  }
}
]]></artwork></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"><![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"><![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"><![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"><artwork><![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"
  }
]
]]></artwork></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"><![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"><artwork><![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=="
  }
]
]]></artwork></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"><![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"><artwork><![CDATA[
=============== NOTE: '\' line wrapping per RFC 8792 ================

[
  {
    "instanceId": "02ee282c-8915-4b2e-bbd2-88966773134a",
    "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
sdfEvent/fallDetected"
  }
]
]]></artwork></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:
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"><![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><artwork><![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"
  }
]
]]></artwork></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: 
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"><![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"><artwork><![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"
  }
]
]]></artwork></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:
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:
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"><![CDATA[
ActionResponse = {
  status: ActionStatus
}

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

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

<figure title="Example action status response" anchor="exactionstatusresp"><artwork><![CDATA[
{
  "status": "COMPLETED"
}
]]></artwork></figure>

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

<t>Many protocols do not require connection management, so for these protocols, these APIs will not apply.
NIPC Gateways perform implicit connection management for protocols that require connection management (such as BLE), so in principle the user of the NIPC API does not have to perform connection management. In some cases however, a user might want to keep a connection open, perform an action, evaluate the result and perform a second action based on that result. In this case it is useful to perform explicit connection management so the connection remains established to execute subsequent actions.  These APIs allow applications to explicitly manage device connections.
The examples in this section will be based on BLE, which requires connection management.</t>

<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 map object. In the case of BLE, if no protocol map 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"><artwork><![CDATA[
{
  "retries": 3,
  "retryMultipleAPs": true
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"retries" defines the number of retries in case the operation does not 
succeed</t>
  <t>"retryMultipleAPs" can be used in case there is an infrastructure with 
multiple access points or radios that can reach the device. If set to "true"
a different access point may be used for retries.</t>
</list></t>

<t>In case the application would like to discover specific properties of a device,
a protocol mapping can be added 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"><artwork><![CDATA[
{
  "retries": 3,
  "retryMultipleAPs": true,
  "sdfProtocolMap": {
    "ble": {
      "services": [
        {
          "serviceID": "00001809-0000-1000-8000-00805f9b34fb"
        }
      ],
      "cached": false,
      "cacheIdlePurge": 3600,
      "autoUpdate": true,
      "bonding": "default"
    }
  }
}
]]></artwork></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>"cacheIdlePurge" 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 when 
onboarding the device</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>

<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"><artwork><![CDATA[
{
  "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
  "sdfProtocolMap": {
    "ble": [
      {
        "serviceID": "00001809-0000-1000-8000-00805f9b34fb",
        "characteristics": [
          {
            "characteristicID": 
              "00002a1c-0000-1000-8000-00805f9b34fb",
            "flags": [
              "read",
              "write"
            ],
            "descriptors": [
              {
                "descriptorID": 
                  "00002902-0000-1000-8000-00805f9b34fb"
              }
            ]
          }
        ]
      }
    ]
  }
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id" is the ID of the device</t>
  <t>"sdfProtocolMap" 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 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 map object. In the case of BLE, if no protocol map 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"><artwork><![CDATA[
{
  "sdfProtocolMap": {
    "ble": {
      "services": [
        {
          "serviceID": "00001809-0000-1000-8000-00805f9b34fb"
        }
      ],
      "cached": false,
      "cacheIdlePurge": 3600,
      "autoUpdate": true
    }
  }
}
]]></artwork></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>"cacheIdlePurge" 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"><artwork><![CDATA[
{
  "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
  "sdfProtocolMap": {
    "ble": [
      {
        "serviceID": "00001809-0000-1000-8000-00805f9b34fb",
        "characteristics": [
          {
            "characteristicID": 
              "00002a1c-0000-1000-8000-00805f9b34fb",
            "flags": [
              "read",
              "write"
            ],
            "descriptors": [
              {
                "descriptorID": 
                  "00002902-0000-1000-8000-00805f9b34fb"
              }
            ]
          }
        ]
      }
    ]
  }
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id" is the ID of the device</t>
  <t>"sdfProtocolMap" 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="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"><artwork><![CDATA[
{
  "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
}
]]></artwork></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"><artwork><![CDATA[
{
  "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
  "sdfProtocolMap": {
    "ble": [
      {
        "serviceID": "00001809-0000-1000-8000-00805f9b34fb",
        "characteristics": [
          {
            "characteristicID": 
              "00002a1c-0000-1000-8000-00805f9b34fb",
            "flags": [
              "read",
              "write"
            ],
            "descriptors": [
              {
                "descriptorID": 
                  "00002902-0000-1000-8000-00805f9b34fb"
              }
            ]
          }
        ]
      }
    ]
  }
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id" is the ID of the device</t>
  <t>"sdfProtocolMap" 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 onboarded 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"><![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>Onboard a device 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 onboard a device, and setup an advertisement
subscription event for that device.</t>

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

<t><list style="symbols">
  <t>Onboard a device 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>Onboard devices 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-15</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-15</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>Onboarding: 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 2555?>

<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><![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.15.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-15"
    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.
  - 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'
               
  /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: './protocolmaps/ProtocolMap.yaml#/components\
\/schemas/ProtocolMap-ServiceList'
        required: false
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: './protocolmaps/ProtocolMap.yaml#/componen\
\ts/schemas/ProtocolMap-ServiceMap'
        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: './protocolmaps/ProtocolMap.yaml#/components/sch\
\emas/ProtocolMap-ServiceList'
        required: false
      responses:
        '200':
          description: Success
          content:
            application/nipc+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: './protocolmaps/ProtocolMap.yaml#/componen\
\ts/schemas/ProtocolMap-ServiceMap'
        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: './protocolmaps/ProtocolMap.yaml#/componen\
\ts/schemas/ProtocolMap-ServiceMap'
        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"

    ActionResponse:
      required:
        - action
      type: object
      properties:
        status:
          type: string
          example: COMPLETED
          description: |-
            Status of the action, can be IN_PROGRESS or COMPLETED

## 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
            
## A Connection
    Connection:
      type: object
      properties:
        retries:
          type: integer
          format: int32
          example: 3
        retryMultipleAPs:
          type: boolean
          example: true
          
 ## 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-Property'
          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-Event'
          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-Property'
          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'
    
<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="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><artwork><![CDATA[
<CODE BEGINS> file "Extension-Blob.yaml"
=============== 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.15.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-15"
    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
<CODE ENDS>
]]></artwork></figure>

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

<figure><artwork><![CDATA[
<CODE BEGINS> file "Extension-Bulk.yaml"
=============== 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.15.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-15"
    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
<CODE ENDS>
]]></artwork></figure>

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

<figure><artwork><![CDATA[
<CODE BEGINS> file "Extension-File.yaml"
=============== 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.15.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-15"
    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
<CODE ENDS>
]]></artwork></figure>

</section>
<section anchor="nipc-api-conditional-read-extension"><name>NIPC API conditional read extension</name>

<figure><artwork><![CDATA[
<CODE BEGINS> file "Extension-ReadConditional.yaml"
=============== 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.15.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-15"
    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
<CODE ENDS>
]]></artwork></figure>

</section>
<section anchor="nipc-api-conditional-event-extension"><name>NIPC API conditional event extension</name>

<figure><artwork><![CDATA[
<CODE BEGINS> file "Extension-EventConditional.yaml"
=============== 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.15.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-15"
    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
<CODE ENDS>
]]></artwork></figure>

</section>
<section anchor="nipc-api-property-extensions"><name>NIPC API property extensions</name>

<figure><artwork><![CDATA[
<CODE BEGINS> file "Extension-Property.yaml"
=============== 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.15.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-15"
    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: '../protocolmaps/ProtocolMap.yaml#/components/schema\
s/ProtocolMap-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==
<CODE ENDS>
]]></artwork></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 title="NIPC API CDDL Definitions"><artwork><![CDATA[
<CODE BEGINS> file "combined.cddl"
=============== 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/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/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]
<CODE ENDS>
]]></artwork></figure>

</section>
<section anchor="example-sdf-model-with-protocol-mappings-for-ble"><name>Example SDF model with protocol mappings for BLE</name>

<figure title="Example SDF model with protocol mappings for BLE" anchor="thermometer-sdf"><artwork><![CDATA[
<CODE BEGINS> file "thermometer.sdf.json"
{
  "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"
              }
            }
          }
        }
      }
    }
  }
}
<CODE ENDS>
]]></artwork></figure>

</section>


  </back>

<!-- ##markdown-source:
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
3wQ9kRLTjJcBSHU14qyEMD0d3qRG+m9XFuNk5JLmn06aoVkf7G+/L87LIYtU
i8d76/TBr/uD6Nz/xOvejnJoV1J8yz3ZpcIgStPCB84ylaIhHTpVgrOYgp0s
fpeyAGNRJmJZyC0YSMN+XNgBj035jKrUmAYsAJTG34m2uwuOT9/QRhZGphdo
vS40hqeUV3XNe/pdoUcHdyv6vSlhwZqLAeVV2ZU93dpZjDXzz0d/lkHVG33K
T76bwVmr7C6eumuNLkbgRRIKGKgOuCX9jRoUUM6jB/tKQxD1zXFw6AFOu0AS
MBSxz3eprOyexyOuJklZm0Y9oMSaUklnDdrLIEahk5gwkvibG+kDOnTucmEq
xU8LydQtTGbmXpyhFEtXwuXlwANoCqUln09Rnyyxc1xy0HHs741wOhpQyiCl
/RaQ6Lvo5nxVLUxyKt1NE/+saf/6NO2RClS214JF91esmczUPqbjKktAGYdK
hPK+tYxPVMlYTMdYWq341LWKz0L/SoT+z6Jv6P18Fn29n9WJvkzWPwu/M4Xf
Q6REfJND99wV90KVEfczhOD6LpcSSg1hmBHEbu/ZbRGGUiy7TGblpKcC5WS0
KpyzE6mQI2ZhW+vnQQx0bC9lQJrp9TEDJSo7KyhFylLJ9MYP1/ONIMk3I3sJ
jjqRcNrcyCpDUbCcUH7QSqJLWBfnMXiu0KNaCaYN38iYnpfVmgz6fOZoVXT/
M0eTn9Uac/DszOFpFc40PyFr+wT4muQAZJ29kwySybW45CZUKYdrObGyJJo9
+hmjhHuVhuyBRcWC0SgTXeemWJMn1+dtHieLB5IOFyNLitK/JIAd4IL1nVMf
yy1MNEndFkb0tyVbWuG+ZFTFarVGv4gl9F/1JaKr0FB8T219GvEuWof3oHyg
OSPfMLfurCepNyQqWL7jkOZ5c+tx9eLxIL0m53Lycbmk4j+kxnCUTzfNr3Os
jiFdkjJB6RtjwhBci3NRjNOPeMPIG0gdnSlDGsGBX7ZKmyG6j7HT4HSo1hhW
yPJrI5XLITUVNk3pjRQVtIPBuk2XsN9H5nfCkjR3cjYXK2fBnFOb+1WdZTFZ
2miSpb1pV7S7aJD8DbV1Aig6DA/5b8pAOBziee7CDmd4hS/pCjvTwXub6JU1
WtC78D5PNx2pJjzqJ9nwCvmnndhGy10G+S1O5c7+H3//P5t2uf/4+//ldI0x
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
9c4/EMBL3np1okGl3Xj7Y1XriqpctXpqncY7l+zMd9VYQfqJEtOqRL1ZBHTO
KuaTp1ritArStCyKAqSc3hQ59+fdqt0NO8s0/xdFmCpZ0y+QKAUPrCea8CX2
Myt6o9zR2eQWt6o7W1vOYw/b/nB2dqLJlfCChP0MyKns4daW6zBmUiB5zmYF
164l10jNSiuc7XHw7dtjNYXGNE/8yF31aFqoctA0Zrirq6tWEo2iVpqdb0Z5
npyPSJAi/76meMQ1scP8QYJ07zIaJL1mwUnxzv0Bdjen2WAFncY/InEGuR5A
0zTOo81ROmnGP8bdqe+8edtRcizX2G+SNbYphVOalQFsKxkhGTWnefFK9Da9
jjPolckQgQQnjt64K+4au21i0v+VgKI46assmdzDpLHbeHWzpogo9PxR9ChX
N71z14TV99PtSpGZwazsswlvDFSKmeJWPMwobXbLlZBWOoTtvzlJhrFb8Gil
43TSEYbjr/pc1a3lPocRqaRp0inf62jJSJiMjJpmTV+oWf2wf0vOO/FPgxr/
f3tP2tw2ruR3/gqW8uZN8iaS78zEs5k8n4lqc/jZTk1traZclEjZXEuiVpTi
+Lm8v327GwdBEuAh0bZskzWHRQINoAH0hUY3b0oM0hu55F1IoxzMcAtXzVW7
k8Bxe044lY3iXYmqW+n7k+GVM/Gak2Aw6Dq9yztrgN3p0C9BpwuTtt0dOKOo
/Qrl0M0ScqhszJ8OSp1jt9kscfdhu210vf44GzojKRMIYRKbs6LyeK+nTOsJ
107ZiUJe+7YbeGEsWRCDDdsWHb5FHM94ANVi4xpiorxzD5RSFPClG7MUGUNF
eUGI9J+YC7IQ8cnDuT31pJBdynsyoRMVdWbUXu/M6WNcF8nwwi7hh51CAj/0
ThRy3GqwlfABrxhXiV4WxlfKdlBiEIlWgUBJPAoHd/Oi1OQBzcdvyd6mTFo5
IV6lb/jc05M5tIoWcRbmeA9MmVYzVPo7wPUchlBGDduas5liqfqSdxDxmSf5
8HwTb0J7lbNvaoOThv/Y+7p/YB982T/5w/o/eqybbfsF4Hu0c9S+RcuWMMZh
wOwxYtPCmNNfWQkebBMvLHCrZaws8i149913WVamm5udMVR0/R/2Lt6paTf3
W7437TcdtIvgvwJCk0O4vW1hJ+heL7bn/eBSTWjfvMC30Ytb1rN+gAH1sPFY
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

-->

</rfc>

