<?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.4) -->


<!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 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 I-D.ietf-asdf-sdf SYSTEM "https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-asdf-sdf.xml">
<!ENTITY RFC9114 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9114.xml">
<!ENTITY RFC7159 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7159.xml">
<!ENTITY RFC8949 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8949.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 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 RFC8610 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8610.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">
]>


<rfc ipr="trust200902" docName="draft-ietf-asdf-nipc-11" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="NIPC">An Application Layer Interface for Non-IP device control (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="July" day="28"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 60?>

<t>This memo specifies RESTful application layer interface for gateways 
providing operations against non-IP devices, as well as a CBOR-based 
publish-subscribe interface for streaming data. The described interfaces are
extensible. The specification also defines a protocol mapping function to
to map this interface to commonly used non-IP protocols.</t>



    </abstract>



  </front>

  <middle>


<?line 68?>

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

<section anchor="scope"><name>Scope</name>

<t>Low-power sensors, actuators and other connected devices introduced in
environments and use cases such as building management, healthcare, workplaces,
manufacturing, logistics and hospitality are often battery-powered. With 
limited power budget, they may not be able to support the IP protocol on their
wired or wireless interfaces, hence they support protocols that require a lower
power budget. Promiment examples of such protocols are <xref target="BLE53"/> and
<xref target="Zigbee22"/>. These devices typically do require to communicate with devices
or applications that are connected to IP-based networking infrastructure. 
Therefore, applications on the IP network that need to communicate or receive
telemetry from these non-IP low-power devices must do so through a gateway 
function on the IP network. This gateway functions then translates the 
communication to the non-IP protocol that the low-power device supports.</t>

<figure title="Gateway for non-IP 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">Non-IP</text>
<text x="180" y="84">IP-based</text>
<text x="380" y="84">Non-IP</text>
<text x="476" y="84">Device</text>
<text x="184" y="100">Operation</text>
<text x="384" y="100">Operation</text>
</g>
</svg>
</artwork><artwork  type="ascii-art"><![CDATA[
                                                               
    +-------------+              +---------+              +--------+
    | Application |<------------>| Gateway |<------------>| Non-IP |                     
    |             |   IP-based   |         |    Non-IP    | Device |
    +-------------+   Operation  +---------+   Operation  +--------+                 

]]></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 non-IP devices, bespoke and
vendor-specific implementations have proliferated. This results in parallel
infrastructure of both gateways and non-IP networks being deployed on a case
by case basis, each connecting separately into the IP network, with a distinct
set of APIs. At the same time, wireless access points supporting both IP-based 
wireless connectivity as well as non-IP based wireless technologies are
deployed ubiquitiously. Many of these wireless access points are equipped with
radios that can transmit and receive different frame types, such as <xref target="BLE53"/>
and <xref target="Zigbee22"/>. This specification aims to define a Gateway API for these 
Non-IP protocols that can be leveraged by this wireless infrastructure in order
to connect Non-IP devices into IP networks. The specification aims to be
extensible, in order to support existing and future non-IP protocols.</t>

<t>A standardized Non-IP Gateway interface has following benefits:</t>

<t><list style="symbols">
  <t>Avoid the need for parallel Non-IP infrastructure.</t>
  <t>Avoid the need for applications to perform bespoke integrations for
different environments.</t>
  <t>Faster and more cost-effective adoption of Non-IP devices in IP network
environments.</t>
</list></t>

</section>
<section anchor="non-ip-gateway"><name>Non-IP Gateway</name>

<t>A non-IP gateway MUST provide at least following functions:</t>

<t><list style="symbols">
  <t>Authentication and authorization of application clients that
will leverage the gateway API to communicate with Non-IP devices.</t>
  <t>Access to a database of onboarded devices. Onboarding ensures that 
the Non-IP Gateway can identify a specific device and has sufficient context
about the device to service gateway API requests.</t>
  <t>The ability to consume an interaction model for a class of devices. This 
allows the gateway to understand how to interact with a device.</t>
  <t>An API that allows for bi-directional communication to non-IP devices.</t>
  <t>One or more channels to process requests, responses, and asymmetric
communications with the non-IP radio resources (Access Points)
at its disposal.</t>
  <t>The ability to stream telemetry received from non-IP devices in real-time
to applications on the IP network.</t>
</list></t>

<t>The definition of the onboarding function is out of scope of this document, but
can be provided by a provisioning interface such as <xref target="RFC7644"/> leveraging 
<xref target="I-D.ietf-scim-device-model"/>. NIPC performs operations on a device or group
object, hence it requires device onboarding to be performed prior to performing
a NIPC operation on a device. NIPC APIs will reference a device or group id 
generated at the time of onboarding as a unique identifier.</t>

<t>The Application gateway is a network function, so its goal is to proxy payloads 
between Non-IP and IP networks. It is not intended to be a middleware function
that interprets, decodes or modifies these 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"/> shows us applications, the NIPC application layer gateway (ALG),
an access point (AP), and a device (D). The applications, application layer
gateway and access point are deployed on an IP-Network. The AP supports a
Non-IP interface, which it uses to communicate with the device.
The Application is deployed in a different administrative domain than the
network elements (ALG &amp; AP).
The role of the application layer gateway is to provide a gateway function
to applications wishing to communicate with non-IP devices in the network
domain served by the gateway.
Applications implementing Non-IP Control can leverage RESTful interfaces
to communicate with Non-IP devices in the network domain and subscribe to
events levering a CBOR-based pub/sub interface.</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>
<section anchor="architecture"><name>Architecture</name>

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

<t>Non-IP protocols, such as BLE or Zigbee, typically define a number of basic
operations that are similar across protocols. Examples of this are read and 
write data. NIPC provides a unified API to support those operations.</t>

<t>To perform NIPC operations on a device, the gateways needs 2 things:
1) Information about the instance of the device or thing: The device must be
onboarded on the gateway (e.g. by means of SCIM). This allows the NIPC Gateway
to retrieve the device object, identified by an id referenced in the path of 
the NIPC API.
2) Information about the interaction model: The Gateway must be able to perform
protocol-neutral operations, and hence requires a mapping of protocol-neutral
operations to protocol specific operations. These are supplied to the gateway
by means of an SDF model, described in <xref target="I-D.ietf-asdf-sdf"/>.</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 these 2 prerequisites have been fulfilled, applications that are
authorized can perform NIPC operations on device ids. NIPC operations
are operations on properties, or constitute actions or events on devices,
as per the affordances defined in an SDF model.</t>

</section>
<section anchor="onboarding"><name>Onboarding</name>

<t>In order to perform a NIPC operation on a device, the device has to have its 
identity declared to the NIPC gateway. We refer to this as 'onboarding'. Apart
from the device identity, it is also necessary that the device object contains
all required information to bootstrap trust with the device, as well as
establish connectivity, as NIPC operations assume that connectivity is there. 
Allthough onboarding could theoretically be performed in other ways, it is
strongly recommended to leverage <xref target="RFC7644"/> with
<xref target="I-D.ietf-scim-device-model"/>, as the SCIM device schema has been developed
to contain all nessary attributes and extensions to support NIPC.</t>

</section>
<section anchor="registrations"><name>Registrations</name>

<t>NIPC registrations APIs allow applications to declare information that is not
related to a device instance. Registrations can be information about an
interaction model for a class of devices, or information about an application
that is required to interact with the gateway.</t>

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

<t>The SDF model for a class of devices determines how a gateway may interact with
these devices in a protocol-neutral way. In order to do that, the SDF model
must contain protocol mappings, mapping protocol-neutral SDF affordances
to protocol-specific ones. The SDF affordances supported by the device, as
well as its protcol-mappings, are provide to the gateway by means of an 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>An application authorized to perform NIPC operations on devices needs to be
able to define which applications can receive streaming event data from the
gateway. The data-app registrations API allows mapping of an event to a data 
app as well as a protocol.</t>

</section>
</section>
<section anchor="protocolmap"><name>Protocol mapping</name>

<t>An SDF model describes a thing, including all its SDF affordances. 
To leverage an SDF model to perform protocol specific operations on an
instance of that thing, a mapping of the SDF affordance to a protocol-specific
attribute is required. In NIPC, this is achieved through protocol mapping.</t>

<t>Protocol mapping is required to map a protocol agnostic affordance to a 
protocol-specific operation, as implementations of the same affordance will
differ between protocols. For example BLE will address a property as a service
characteristic, while a property in Zigbee is addressed as a property in a
cluster of an endpoint.</t>

<t>protocol mapping allows for integration of new protocols in NIPC, new mappings 
can be created without the need to update the base schema.</t>

<t>a protocol mapping object is a JSON object identified by the sdfProtocolMap keyword.</t>

<figure title="Property Mapping" anchor="protmap"><artset><artwork  type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="208" width="256" viewBox="0 0 256 208" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
<path d="M 24,48 L 24,128" fill="none" stroke="black"/>
<path d="M 96,80 L 96,96" fill="none" stroke="black"/>
<path d="M 96,144 L 96,160" fill="none" stroke="black"/>
<path d="M 24,64 L 72,64" fill="none" stroke="black"/>
<path d="M 96,96 L 120,96" fill="none" stroke="black"/>
<path d="M 24,128 L 72,128" fill="none" stroke="black"/>
<path d="M 96,160 L 120,160" fill="none" stroke="black"/>
<polygon class="arrowhead" points="128,160 116,154.4 116,165.6" fill="black" transform="rotate(0,120,160)"/>
<polygon class="arrowhead" points="128,96 116,90.4 116,101.6" fill="black" transform="rotate(0,120,96)"/>
<polygon class="arrowhead" points="80,128 68,122.4 68,133.6" fill="black" transform="rotate(0,72,128)"/>
<polygon class="arrowhead" points="80,64 68,58.4 68,69.6" fill="black" transform="rotate(0,72,64)"/>
<g class="text">
<text x="60" y="36">sdfProtocolMap</text>
<text x="96" y="68">ble</text>
<text x="144" y="100">BLE</text>
<text x="196" y="100">property</text>
<text x="108" y="132">zigbee</text>
<text x="156" y="164">Zigbee</text>
<text x="220" y="164">property</text>
</g>
</svg>
</artwork><artwork  type="ascii-art"><![CDATA[
  sdfProtocolMap
    |
    +-----> ble
    |        |
    |        +--> BLE property
    |
    +-----> zigbee
             |
             +--> Zigbee property

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

<t>As shown in <xref target="protmap"/>, protocol-specific properties must be embedded in an
sdfProtocolMap object, for example a "ble" or a "zigbee" object.</t>

<texttable title="Protocol objects" anchor="proobj">
      <ttcol align='left'>Attribute</ttcol>
      <ttcol align='left'>Req</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c>ble</c>
      <c>T</c>
      <c>object</c>
      <c>an object with BLE-specific attributes</c>
      <c>zigbee</c>
      <c>T</c>
      <c>object</c>
      <c>an object with Zigbee-specific attributes</c>
</texttable>

<t>where-</t>

<t><list style="symbols">
  <t>"ble" is an object containing properties that are specific to the BLE
protocol.</t>
  <t>"zigbee" is an object containing properties that are specific to the
Zigbee protocol.</t>
  <t>Other protocol mapping objects can be added by creating a new protocol
object</t>
</list></t>

<t>Example protocol mapping:</t>

<figure title="Example property mapping" anchor="exprotmap"><artwork><![CDATA[
"sdfObject": {
  "healthsensor": {
    "sdfProperty": {
      "heartrate": {
        "description": "The current measured heart rate",
        "type": "number",
        "unit": "beat/min",
        "observable": false,
        "writable": false,
        "sdfProtocolMap": {
          "ble": {
            "serviceID": "12345678-1234-5678-1234-56789abcdef4",
            "characteristicID": 
              "12345678-1234-5678-1234-56789abcdef4"
          }
        }
      }
    }
  }
}
]]></artwork></figure>

<t>A protocol map is provided as part of the SDF model, in the SDF affordance 
definition. Alternatively, it can be provided directly in a NIPC API.</t>

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

<t>NIPC operations are protocol-neutral operations on SDF affordances, more 
specifically properties, actions &amp; events. NIPC operations can happen against
affordances that were registered in an SDF model. If connection management is
required to execute a NIPC operation, it is assumed that the gateway implictly
establishes and tears down required connections.</t>

<section anchor="properties-apis"><name>Properties APIs</name>

<t>Property APIs allow applications perform operations on properties, such as to
read or write values to them.</t>

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

<t>Action APIs perform actions on devices, such as enabling or disabling a feature
on a device.</t>

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

<t>Event APIs allow apps to enable or disable event reporting on devices. Events
are reported over the events publish/subscribe interface.</t>

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

<t>For protocols that require connection management before executing an operation,
a NIPC gateway will perform implicit connection management. When executing a 
NIP operation, a NIPC Gateway can set up a connection with a device as well as
tear down the connection after the operation has completed. A NIPC Gateway
may support explicit connection management as well. Explicit connection
management can be used by an app that wants to perform multiple NIPC operations
in a single connection. Explicit connection management can be performed by 
calling the /devices/{id}/connections API. When after establishing an
explicit connection to a device, an application calls a NIPC Operation, the
Gateway will leverage the exissting connection and will also not tear the
connection down after the operation completes. The app will have to explicitly
close the connection.</t>

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

<t>NIPC is extendable as a NIPC gateway may want to provide a way to execute a
complex set of NIPC operations in a single API call, or may want to perform
an operation that can deliver an outcome more efficiently than a NIPC API. 
An example of an extension that uses compound operation is the bulk API.</t>

<t>Extensions must leverage the /extension path element. In order to assure
inter-operability, extensions should be IANA registered <xref target="iana-api-ext"/>.</t>

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

<t>Events are published on a publish/subscribe interface. Events can be of
different types:</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</t>
  <t>Connection events: Devices connecting &amp; disconnecting</t>
</list></t>

</section>
<section anchor="protocols"><name>Protocols</name>

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

<t>NIPC is a protocol that is based on RESTful HTTP <xref target="RFC9114"/>. Along with HTTP
headers and URIs, NIPC uses JSON <xref target="RFC7159"/> payloads to convey NIPC 
operations, such as registrations, actions, event and property operations. This
is the case for both request and response parameters, as well as errors.
NIPC uses the JSON media type "application/nipc+json" that is registered in
<xref target="iana-media-types"/>, except for the SDF model registrations APIs, 
where the media type reflects the content as an SDF 
model, and hence is media type "application/sdf+json".
The NIPC property APIs also support the use of other media types to 
describe the content of the property.</t>

</section>
<section anchor="nipc-publishsubscribe-events"><name>NIPC publish/subscribe events</name>

<t>NIPC publish/subscribe events are encoded in CBOR (<xref target="RFC8949"/>) and can be
delivered over either:</t>

<t><list style="symbols">
  <t>MQTT</t>
  <t>Webhook</t>
  <t>Websocket</t>
</list></t>

</section>
</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 can 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}/firmware",
    "/extensions/{id}/properties/blob",
    "/extensions/{id}/properties/file",
    "/extensions/{id}/properties/read/conditional",
    "/extensions/{id}/properties/write"
  ]
}
]]></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 will 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>property</t>
  <t>event</t>
  <t>action</t>
  <t>extension</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>In order to perform a NIPC operation on a device, an SDF interaction model 
needs to be declared that provides protcol mappings for the SDF affordances
the operations will be performed on.</t>

<t>The SDF model can be registered by means of a registrations API POST with 
the SDF model in the body of hte request. A registered SDF model can be 
fetched by a registrations API GET with an sdfReference.</t>

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

<t>NIPC operations require 2 key parameters:
1) A device ID identifying the device the operation should be executed on
2) an SDF reference for the SDF affordance the operations pertains to</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.</t>

<texttable title="Definition of a device our group of devices" anchor="devicedef">
      <ttcol align='left'>Attribute</ttcol>
      <ttcol align='left'>Req</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c>id</c>
      <c>T</c>
      <c>uuid</c>
      <c>12345678-1234-5678-1234-56789abcdef4</c>
</texttable>

<t>Id is the unique uuid of the device. This id is generated when registering
the device, for example against a SCIM server. As such, this id is a common
identifier, known both to the application as well as the NIPC Server.</t>

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

<t>NIPC operations happen against SDF affordances and are referenced with an
global sdfName, which is the full path including the namespace.</t>

<t>The operations are either Properties, Events or Actions and their references
are of type string</t>

<t>For example:</t>

<texttable title="Definition of a NIPC operation on a property" anchor="nipcopsdef">
      <ttcol align='left'>Attribute</ttcol>
      <ttcol align='left'>Req</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c>Property</c>
      <c>T</c>
      <c>string</c>
      <c>https://example.com/heartrate#/<br />sdfObject/thermostat/sdfProperty/temperature</c>
</texttable>

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

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

<t>The exception to the above are NIPC extensions, <xref target="apiextensions"/>. These contain 
compound statements, and thus require the gateway to execute multiple
NIPC operations. In this case the NIPC gateway will return HTTP status
code 202 after receiving the request and verifying it is able to execute it.
The client can then perform an HTTP GET of the extension API to get the
execution status for the request. If a callback URL was address was defined in
the request, the NIPC Gateway can optionally perform a callback with a
response to the compound request after the compound statement completes.</t>

<t>Actions also follow an asynchronous pattern, returning HTTP status code 202
when the action is accepted, along with a Location header pointing to the
action instance for status tracking.</t>

<t>A failure response will consist of a HTTP status code of 4xx or 5xx, and 
will follow the <xref target="RFC9457"/> Problem Details format with <spanx style="verb">application/problem+json</spanx>
media type. The response will contain a <spanx style="verb">type</spanx> field with a URI identifying
the error type, and a human-readable <spanx style="verb">detail</spanx> field. The <spanx style="verb">type</spanx> field
is a URI and is described in <xref target="errorhandling"/>.</t>

<t>Failure response:</t>

<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 12345678-1234-5678-1234-56789abcdef4 does not\
\ exist or is not a device"
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"type" is a URI identifying the specific error type</t>
  <t>"status" is the HTTP status code</t>
  <t>"title" is a brief, human-readable summary of the error type</t>
  <t>"detail" is a human-readable explanation specific to this occurrence</t>
</list></t>

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

<t>NIPC allows an application to register an SDF model for a class of devices,
as well as a data application that will receive streaming data from the 
gateway.</t>

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

<t>These 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>an SDF document in JSON format containing one of more sdfThings or sdfObjects, similar to the example in <xref target="thermometer-sdf"/>.</t>
</list></t>

<t>Response:</t>

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

<figure title="Example register SDF model response" anchor="exregresp"><artwork><![CDATA[
[
 {
  "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
 }
]
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"sdfName" is the reference to the top-level sdfThing or sdfObject 
 in the SDF model</t>
</list></t>

</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>Example of a response:</t>

<figure title="Example get all SDF models response" anchor="exgetallresp"><artwork><![CDATA[
[
 {
  "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
 }
]
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"sdfName" is the reference to the top-level sdfThing or sdfObject 
 in the SDF model</t>
</list></t>

</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 reference to the top-level sdfThing or sdfObject 
 in the SDF model.</t>
</list></t>

<t>Response:</t>

<t>The SDF model is returned in JSON format, similar to the example in 
<xref target="thermometer-sdf"/>.</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 reference to the top-level sdfThing or sdfObject 
 in the SDF model.</t>
</list></t>

<t>Response:</t>

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

<figure title="Example delete SDF model response" anchor="exdelresp"><artwork><![CDATA[
{
  "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"sdfName" is the reference to the top-level sdfThing or sdfObject 
 in the SDF model</t>
</list></t>

</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 reference to 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>Example of a response:</t>

<figure title="Example update SDF model response" anchor="exupresp"><artwork><![CDATA[
{
  "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"sdfName" is the reference to the top-level sdfThing or sdfObject 
 in the SDF model</t>
</list></t>

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

<t>These 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. The endpoint app is defined in 
<xref section="6" sectionFormat="of" target="I-D.ietf-scim-device-model"/>.</t>

<section anchor="register-a-data-application"><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 wants to receive
streaming data for.</t>
</list></t>

<t>The request body also contains one of the following:</t>

<t><list style="symbols">
  <t>mqttClient: a boolean that denotes that the data application
is an MQTT client that will receive streaming data over MQTT</t>
  <t>mqttBroker: an object that contains the MQTT broker information
where the broker will publish the streaming data.
  <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 CA certificate of the MQTT broker (optional)</t>
      <t>customTopic: the custom topic to publish the streaming data to
(optional)</t>
    </list></t>
  <t>webhook: an object that contains a webhook URL along with any 
 credentials that are required to authenticate the webhook. 
 The webhook URL is the endpoint where the streaming data will be sent.
  <list style="symbols">
      <t>URI: the webhook URL</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.</t>
      <t>serverCACert: the CA certificate of the webhook server (optional)</t>
    </list></t>
  <t>websocket: an object that 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 URL</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.</t>
      <t>serverCACert: the CA certificate of the websocket server (optional)</t>
    </list></t>
</list></t>

<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>If successful, the response will be identical to the request body.</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 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: Same as the request body for the register data application API.</t>

<t>Response:</t>

<t>If successful, the response will be identical to the request body.</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 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.</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>The response will be identical to the request body for the register data
application API.</t>

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

<t>The primary goal of the NIPC APIs is to  perform operations on SDF Affordances, such as properties, events &amp; actions.This allows a user of the NIPC API to get or update properties of devices, perform actions on devices, and consume events from devices.</t>

<t>The NIPC APIs consists of 3 main collections which reflect SDF Affordances as defined in <xref section="1.2" sectionFormat="of" target="I-D.ietf-asdf-sdf"/>:</t>

<t><list style="symbols">
  <t>NIPC Property APIs: These APIs allow applications to get and update device 
properties.</t>
  <t>NIPC Event APIs: These APIs allow applications to enable or disable event
reporting on devices.</t>
  <t>NIPC Action APIs: These APIs allow applications to perform actions on
devices.</t>
</list></t>

<t>One or more SDF models must be registered in order to use these NIPC
Property, Event and Action APIs. The SDF models can be a top-level sdfThing with
multiple sdfObjects or a top-level sdfObject. These APIs depend on the SDF 
affordances (i.e. sdfProperty, sdfEvent and sdfAction) defined in
the SDF model and a device ID that is defined in <xref target="I-D.ietf-scim-device-model"/>.
An SDF affordance can be referenced using the global name of the SDF affordance
as described in <xref section="4" sectionFormat="of" target="I-D.ietf-asdf-sdf"/>.</t>

<t>The SDF global name will be used against the registered SDF model to 
determine the protocol-specific protocolmap that the NIPC API will operate on.</t>

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

<t>These APIs allow applications to get and update device properties. 
These operations may require a connection to the device to be established. 
This connection can be established as part of the same API call implicitly.
If a connection is already active for this device, the existing connection willi
be leveraged without modifying it.</t>

<t>These APIs support multiple media types based on Content-Type and Accept
headers to accommodate different data formats.</t>

<t>When using <spanx style="verb">application/nipc+json</spanx>, the request and response bodies follow 
the format shown in the examples above, with binary data encoded as 
base64 in the "value" field. 
For other content types, the data is transmitted according to the 
specific format requirements of that media type.</t>

<section anchor="write-multiple-values"><name>Write 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: a single property to update. If this parameter is
provided, the request body can contain any conten type payload 
with the value to write to the property. If this parameter is not
provided, the request body MUST contain an application/nipc+json payload
with an array of properties to update, each containing 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
can contain any content type payload with the value to write to the property.
The value is the raw binary data to write to the property.</t>
</list></t>

<t>or</t>

<t><list style="symbols">
  <t>an array of properties to update, each containing a property and a value.
The value is the raw binary data, encoded in base64 with padding as per 
<xref section="5" sectionFormat="of" target="RFC4648"/>.</t>
</list></t>

<t>Example body 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>If the Accept header is set to <spanx style="verb">application/nipc+json</spanx>, the response will 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.</t>

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

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

<t>where-</t>

<t><list style="symbols">
  <t>"properties" is an array of properties that were updated, each containing
a property and a value</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="read-multiple-values"><name>Read 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>If the Accept header is set to <spanx style="verb">application/nipc+json</spanx>, the response will be
an array of properties, each containing a property and a value. The value is
the raw binary data read from the property, encoded in base64 with padding as per <xref section="5" sectionFormat="of" target="RFC4648"/>.</t>

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

<t>where-</t>

<t><list style="symbols">
  <t>"property" is the property that was read from</t>
  <t>"value" is the bytes that were read in base64 encoding</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 anchor="nipc-event-apis"><name>NIPC Event APIs</name>

<t>These APIs allow applications to enable or disable event reporting on devices.
These operations may require a connection to the device to be established. This
connection can be established as part of the same API call implicitly. If a
connection is already active for this device, the existing connection will be
leveraged without modifying it.</t>

<t>The event is a global name reference to an <spanx style="verb">sdfEvent</spanx>.</t>

<t>The ID in the path is the id of the device or group of devices.
An event can be enabled on a group of devices if it is supported by the
underlying protocol. For example, if the underlying protocol is BLE, 
the event can be enabled on a group of devices if the event is an 
advertisement event or connection status event.</t>

<t>If the data application registered for this event is an MQTT broker or 
client, the event is 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 <spanx style="verb">"12345678-1234-5678-1234-56789abcdef4"</spanx> 
and the event is 
<spanx style="verb">"https://example.com/thermometer#/sdfThing/thermometer/sdfEvent/isPresent"</spanx>,
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/12345678-1234-5678-1234-56789abcdef4/thermometer/sdfThing/\
thermometer/sdfEvent/isPresent
]]></artwork></figure>

<t>A data application can subscribe to this topic using the topic or it 
can 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 custom topic is provided for an MQTT broker, the custom topic is
used as the MQTT topic instead.</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 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>eventName: the event to enable</t>
</list></t>

<t>The eventName is a URL encoded string that is the absolute URI that is a global
name reference to an <spanx style="verb">sdfEvent</spanx>.</t>

<t>Response:</t>

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

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

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

HTTP/1.1 201 Created
Location: /devices/12345678-1234-5678-1234-56789abcdef4/events?insta\
nceId=87654321-4321-8765-4321-fedcba9876543
]]></artwork></figure>

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

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</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 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: 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>Returns HTTP status code 204 No Content on successful disable.</t>

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

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

</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:</t>

<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": "87654321-4321-8765-4321-fedcba9876543",
    "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
sdfEvent/fallDetected"
  }
]
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"instanceId" is the unique instance ID for each enabled event</t>
  <t>"event" is the event URI for each enabled event</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="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</t>
</list></t>

<t>The eventName is a URL encoded string that is the absolute URI that is a global
name reference to an <spanx style="verb">sdfEvent</spanx>.</t>

<t>Response:</t>

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

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

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

HTTP/1.1 201 Created
Location: /groups/12345678-1234-5678-1234-56789abcdef4/events?instan\
ceId=87654321-4321-8765-4321-fedcba9876543
]]></artwork></figure>

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

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

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

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

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

<t>Parameters:</t>

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

<t>Query Parameters:</t>

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

<t>Response:</t>

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

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

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

</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 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: a list of event instance IDs to filter by (optional)</t>
</list></t>

<t>Response:</t>

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

[
  {
    "instanceId": "87654321-4321-8765-4321-fedcba9876543",
    "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
sdfEvent/fallDetected"
  }
]
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"instanceId" is the unique instance ID for each enabled event</t>
  <t>"event" is the event URI for each enabled event</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 anchor="nipc-action-apis"><name>NIPC Action APIs</name>

<t>These APIs allow applications to perform actions on devices. These operations
may require a connection to the device to be established. This connection can
be established as part of the same API call implicitly. If a connection is
already active for this device, the existing connection will be leveraged
without modifying it.</t>

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

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

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

<t>Parameters:</t>

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

<t>Query Parameters:</t>

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

<t>Request Body:</t>

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

<t>Response:</t>

<t>Actions are performed asynchronously. A successful request returns HTTP status code 202 Accepted 
with a Location header pointing to the action instance for status checking.</t>

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

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

HTTP/1.1 202 Accepted
Location: /devices/12345678-1234-5678-1234-56789abcdef4/actions?inst\
anceId=87654321-4321-8765-4321-fedcba9876543
]]></artwork></figure>

<t>The Location header contains the URI for the action instance, which can be used to check the action status.</t>

</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:</t>

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

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

<t>where "status" indicates the current state of the action (e.g., "IN_PROGRESS" or "COMPLETED").</t>

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

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

<t>A lot of 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 connections 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 discover 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 operations 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": "12345678-1234-5678-1234-56789abcdef4"
        }
      ],
      "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 charateristics, 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
            - charactericID
            - flags
               |
               |> Descriptors
                   - descriptorID
]]></artwork></figure>

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

<figure title="Example connection response" anchor="exconnresp"><artwork><![CDATA[
{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "sdfProtocolMap": {
    "ble": [
      {
        "serviceID": "12345678-1234-5678-1234-56789abcdef4",
        "characteristics": [
          {
            "characteristicID": 
              "12345678-1234-5678-1234-56789abcdef4",
            "flags": [
              "read",
              "write"
            ],
            "descriptors": [
              {
                "descriptorID": 
                  "12345678-1234-5678-1234-56789abcdef4"
              }
            ]
          }
        ]
      }
    ]
  }
}
]]></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 discover 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": "12345678-1234-5678-1234-56789abcdef4"
        }
      ],
      "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 charateristics, 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": "12345678-1234-5678-1234-56789abcdef4",
  "sdfProtocolMap": {
    "ble": [
      {
        "serviceID": "12345678-1234-5678-1234-56789abcdef4",
        "characteristics": [
          {
            "characteristicID": 
              "12345678-1234-5678-1234-56789abcdef4",
            "flags": [
              "read",
              "write"
            ],
            "descriptors": [
              {
                "descriptorID": 
                  "12345678-1234-5678-1234-56789abcdef4"
              }
            ]
          }
        ]
      }
    ]
  }
}
]]></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": "12345678-1234-5678-1234-56789abcdef4"
}
]]></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": "12345678-1234-5678-1234-56789abcdef4",
  "sdfProtocolMap": {
    "ble": [
      {
        "serviceID": "12345678-1234-5678-1234-56789abcdef4",
        "characteristics": [
          {
            "characteristicID": 
              "12345678-1234-5678-1234-56789abcdef4",
            "flags": [
              "read",
              "write"
            ],
            "descriptors": [
              {
                "descriptorID": 
                  "12345678-1234-5678-1234-56789abcdef4"
              }
            ]
          }
        ]
      }
    ]
  }
}
]]></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 extensible in two ways:</t>

<t><list style="symbols">
  <t>Protocol mapping: New protocol mapping can extend NIPC with support
for new non-IP protocols</t>
  <t>API extensions: API extensions leverage compound statements of basic NIPC
action APIs to simplify common operations for applications.</t>
</list></t>

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

<t>As described in <xref target="protocolmap"/>, NIPC supports mapping protocol specific
properties to NIPC properties. BLE and Zigbee are used as examples, but protocol
mapping is extensible to other protocols, so now non-IP protocols can be 
supported by NIPC without a schema change.</t>

<t>The protocol objects need to be extended with the new
protocol as well. Protocol objects will be extended as follows:</t>

<texttable title="Adding Protocol mappings" anchor="newprotext">
      <ttcol align='left'>Attribute</ttcol>
      <ttcol align='left'>Req</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c>ble</c>
      <c>T</c>
      <c>object</c>
      <c>an object with BLE-specific properties</c>
      <c>zigbee</c>
      <c>T</c>
      <c>object</c>
      <c>an object with Zigbee-specific properties</c>
      <c>newProtocol</c>
      <c>T</c>
      <c>object</c>
      <c>an object with newProtocol-specific props</c>
</texttable>

<t>In the new protocol object, protocol specific properties can be added.</t>

<t>Protocol mappings need to be IANA registered, see <xref target="iana-prot-map"/>.</t>

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

<t>/extension</t>

<t>The extension APIs allow for extensibility of the APIs, either IANA 
registered extensions (<xref target="iana-api-ext"/>) or vendor-specific extensions.
Extension APIs must leverage the basic NIPC defined APIs and combine them in 
compound statements in order to streamline application operation against
devices, make operations more expediant and convenient in one API call.
In principle they do not add any basic functionality. In
the OpenAPI model <xref target="NIPCextensions"/> below, we have defined a few example 
extensions.</t>

<t>The extensions can contain long running operations, such as firmware updates,
or other bulk operations that can be performed on a device. For long 
running operations, the extension API will return a 202 Accepted status 
code and a location header with the URL to check the status of the operation.
The status of the operation can be checked by calling the status extension API
with the same device ID. The status extension API will return a 200 OK status code
when the operation is in progress. When the operation is complete, 
the status extension API will return a 303 See Other status code with a 
location header with the URL to check the status of the operation.
The GET operation on the extension API will return a 200 OK status code
with the actual response once the operation is complete.</t>

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

<t>The error types in the NIPC APIs 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>The specific 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>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-broadcast-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>The publish/subscribe interface, or data streaming interface, is an MQTT
publishing interface. Pub/sub topics can be created and managed by means
of the /registration/data-app API.</t>

<t>In this memo, we propose the data format to be CBOR <xref target="RFC8949"/>.</t>

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

<t>We have a CDDL <xref target="RFC8610"/> definition where we define the
DataSubscription struct that will be used by all the messages published 
to the MQTT broker.</t>

<t>The DataSubscription struct is a CBOR map that will contain the raw data
in bytes and a timestamp of the data. Optionally, the message will also
have a deviceID that corresponds to the SCIM ID of the device if the 
payload is associated to a known device.</t>

<t>Other fields in the CDDL such as apMacAddress and rssi can be optionally
included but these fields can expose the underlying network topology.</t>

<t>Each message also has a subscription choice group that will define the
type of data that is being published.</t>

<t>Each MQTT message can be a collection of DataSubscription structs. This
collection is represented as DataBatch in the CDDL.</t>

<figure><sourcecode type="CDDL"><![CDATA[
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 
depicted in CBOR diagnostic notation.</t>

<figure title="Onboarded BLE Device Advertisement"><artwork><![CDATA[
[
  {
    "data": h'02011A020A0C16FF4C001007721F41B0392078',
    "deviceID": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "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": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "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": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "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": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "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 /registration/model
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/12345678-1234-5678-1234-56789abcdef4/properties?prop\
ertyName=https://example.com/thermometer%23/sdfThing/thermometer/\
sdfProperty/device_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/12345678-1234-5678-1234-56789abcdef4/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"><name>Enabling an Event</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 /registration/data-app?dataAppId=23456789-1234-5678-1234-567\
89abcdef4
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>
  <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 /registration/data-app?dataAppId=23456789-1234-5678-1234-567\
89abcdef4
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/12345678-1234-5678-1234-56789abcdef4/events?eventNa\
me=https://example.com/thermometer%23/sdfThing/thermometer/sdfEve\
nt/isPresent
Host: localhost
Content-Length: 0

HTTP/1.1 201 Created
Location: /devices/12345678-1234-5678-1234-56789abcdef4/events?in\
stanceId=87654321-4321-8765-4321-fedcba9876543
]]></artwork></figure>
  </t>
  <t>Check the status of the event  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[
============== NOTE: '\' line wrapping per RFC 8792 ==============

GET /devices/12345678-1234-5678-1234-56789abcdef4/events?instance\
Id=87654321-4321-8765-4321-fedcba9876543
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>
<section anchor="security-considerations"><name>Security Considerations</name>

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

<t>In order to enable a network wishing to offer NIPC ALG functions, the network
administrator authorizes application(s) to perform operations on the Gateway.
This happens out of band and may be accomplished by means of exchanging tokens
or public keys.
Authorization can be role-based. The 3 primary roles are:</t>

<t><list style="numbers" type="1">
  <t>Onboarding: Authorize an onboarding application against a SCIM server
co-located with the gateway.</t>
  <t>Control: Authorize applications that may control devices.</t>
  <t>Data: Authorize applications that may receive telemetry.<br />
It is possible to further refine roles down to an API basis.</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:</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-prot-map"><name>Protocol mapping</name>

<t>IANA is requested to create a new registry called "NIPC protocol mapping".</t>

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

<t><list style="symbols">
  <t>Protocol map name</t>
  <t>Protocol name</t>
  <t>Description</t>
  <t>Reference of the specification describing the protocol mapping. This specification must be reviewed by an expert.</t>
</list></t>

<t>Following protocol mappings are described in this document:</t>

<texttable>
      <ttcol align='left'>Protocol map</ttcol>
      <ttcol align='left'>Protocol Name</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>ble</c>
      <c>Bluetooth Low Energy (BLE)</c>
      <c>Protocol mapping for BLE devices</c>
      <c>This document</c>
      <c>zigbee</c>
      <c>Zigbee</c>
      <c>Protocol mapping for Zigbee devices</c>
      <c>This document</c>
</texttable>

</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>/extension/{id}/bulk</c>
      <c>Bulk API</c>
      <c>Call multiple NIPC's in a single request</c>
      <c><xref target="NIPCextensions"/></c>
      <c>/extension/{id}/properties/file</c>
      <c>File write API</c>
      <c>Write a file with multiple property ops</c>
      <c><xref target="NIPCextensions"/></c>
      <c>/extension/{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}/firmware</c>
      <c>Firmware upgrade API</c>
      <c>Firmware upgrade API, leveraging mutiple opsed</c>
      <c><xref target="NIPCextensions"/></c>
      <c>/extensions/{id}/manage/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#property-not-readable</c>
      <c>Property not readable</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#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;
&RFC2119;
&RFC8174;
&I-D.ietf-asdf-sdf;
&RFC9114;
&RFC7159;
&RFC8949;
&RFC3986;
&RFC6570;
&RFC9457;
&RFC4648;
&RFC8610;
&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>


    </references>

</references>


<?line 2326?>

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

<t>The following non-normative model is provide 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.9.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-11"
    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: 12345678-1234-5678-1234-56789abcdef4
      - 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: 12345678-1234-5678-1234-56789abcdef4
      - 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: device id or group id
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - 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: device id or group id
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: instanceId
        in: query
        description: instance id of the event that needs to be disab\
\led
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      - 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: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      - 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: 12345678-1234-5678-1234-56789abcdef4
      - name: instanceId
        in: query
        description: instance id of the event that needs to be disab\
\led
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      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 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: 12345678-1234-5678-1234-56789abcdef4
      - name: instanceId
        in: query
        description: |-
          Instance IDs of the events that need to be filtered
        required: false
        schema:
          type: array
          items:
            type: string
            format: uuid
            example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success, events retrieved
          content:
            application/nipc+json:
              schema:
                $ref: '#/components/schemas/EventStatusResponseArray'
        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: 12345678-1234-5678-1234-56789abcdef4
      - 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: 12345678-1234-5678-1234-56789abcdef4
      - name: instanceId
        in: query
        description: |-
          instance id of the action that needs to be checked
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4

## 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: 12345678-1234-5678-1234-56789abcdef4
            
## 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: 12345678-1234-5678-1234-56789ab\
\cdef4
                          characteristicID: 12345678-1234-5678-1234-\
\56789abcdef4
                  sdfEvent:
                    fallDetected:
                      sdfOutputData:
                        sdfProtocolMap:
                          ble:
                            serviceID: 12345678-1234-5678-1234-56789\
\abcdef4
                            characteristicID: 12345678-1234-5678-123\
\4-56789abcdef4
                  sdfAction:
                    start:
                      sdfProtocolMap:
                        ble:
                          serviceID: 12345678-1234-5678-1234-56789ab\
\cdef4
                          characteristicID: 12345678-1234-5678-1234-\
\56789abcdef4

    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: 12345678-1234-5678-1234-56789abcdef4
                      characteristicID: 12345678-1234-5678-1234-5678\
\9abcdef4
              sdfEvent:
                fallDetected:
                  sdfOutputData:
                    sdfProtocolMap:
                      ble:
                        serviceID: 12345678-1234-5678-1234-56789abcd\
\ef4
                        characteristicID: 12345678-1234-5678-1234-56\
\789abcdef4
              sdfAction:
                start:
                  sdfProtocolMap:
                    ble:
                      serviceID: 12345678-1234-5678-1234-56789abcdef4
                      characteristicID: 12345678-1234-5678-1234-5678\
\9abcdef4

    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: 12345678-1234-5678-1234-56789abcdef4
                  characteristicID: 12345678-1234-5678-1234-56789abc\
\def4
          
    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: 12345678-1234-5678-1234-56789abcdef4
                    characteristicID: 12345678-1234-5678-1234-56789a\
\bcdef4
    
    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: 12345678-1234-5678-1234-56789abcdef4
                  characteristicID: 12345678-1234-5678-1234-56789abc\
\def4

# 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-not-writable
            - 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 12345678-1234-5678-1234-56789abcdef4 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'

<CODE ENDS>
]]></artwork></figure>

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

<t>NIPC requires that a protocol mapping be provided as part of the SDF
model for a device or have one provided using the NIPC action APIs with 
embedded protocol mapping. The protocol mapping is a JSON object that 
describes the underlying technology used to communicate with the device 
along with any additional information needed to communicate with the 
device.</t>

<t>The JSON format of the protocol mapping is provided as a non-normative
OpenAPI model for the convenience of the implementor.</t>

<section anchor="protocol-mapping-openapi-model"><name>Protocol mapping OpenAPI model</name>

<figure anchor="protocolmapmodel"><artwork><![CDATA[
<CODE BEGINS>
file "ProtocolMap.yaml"
=============== NOTE: '\' line wrapping per RFC 8792 ================

openapi: 3.0.3
info:
  title: Non IP Device Control (NIPC) Protocol Mapping
  description: |-
    Non IP Device Control (NIPC) Protocol Mapping. When adding a
    new protocol mapping pls add a reference to the protocol map
    for all the schemas in this file.
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.10.0
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/

components:
  schemas:
# Protocol Mapping
## Protocol Map for Service Discovery
    ProtocolMap-ServiceList:
      type: object
      properties:
        sdfProtocolMap:
          oneOf:
            - $ref: './ProtocolMap-BLE.yaml#/components/schemas/Prot\
ocolMap-BLE-ServiceList'

## Protocol Map for Service Discovery result
    ProtocolMap-ServiceMap:
      type: object
      properties:
        sdfProtocolMap:
          oneOf:
            - $ref: './ProtocolMap-BLE.yaml#/components/schemas/Prot\
ocolMap-BLE-ServiceMap'
            - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/P\
rotocolMap-Zigbee-ServiceMap'
        
## Protocol Map for Error Codes
    ProtocolMap-ErrorCodes:
      type: object
      properties:
        sdfProtocolMap:
          oneOf:  
            - $ref: './ProtocolMap-BLE.yaml#/components/schemas/Prot\
ocolMap-BLE-ErrorCodes'
            - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/P\
rotocolMap-Zigbee-ErrorCodes'

## Protocol Map for Broadcasts
    ProtocolMap-Broadcast:
      type: object
      properties:
        sdfProtocolMap:
          oneOf:  
            - $ref: './ProtocolMap-BLE.yaml#/components/schemas/Prot\
ocolMap-BLE-Broadcast'
            - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/P\
rotocolMap-Zigbee-Broadcast'

## Protocol Map for a property
    ProtocolMap-Property:
      type: object
      properties:
        sdfProtocolMap:
          oneOf:  
            - $ref: './ProtocolMap-BLE.yaml#/components/schemas/Prot\
ocolMap-BLE-Propmap'
            - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/P\
rotocolMap-Zigbee-Propmap'

## Protocol Map for an event
    ProtocolMap-Event:
      type: object
      properties:
        sdfProtocolMap:
          oneOf:  
            - $ref: './ProtocolMap-BLE.yaml#/components/schemas/Prot\
ocolMap-BLE-Event'
            - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/P\
rotocolMap-Zigbee-Event'
 
<CODE ENDS>
]]></artwork></figure>

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

<figure anchor="protocolmapble"><artwork><![CDATA[
<CODE BEGINS>
file "ProtocolMap-BLE.yaml"
=============== NOTE: '\' line wrapping per RFC 8792 ================

openapi: 3.0.3
info:
  title: Non IP Device Control (NIPC) BLE Protocol Mapping
  description: |-
    Non IP Device Control (NIPC) BLE Protocol Mapping. 
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.10.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/

components:
  schemas:
# BLE Protocol Mapping
## A Service is a device with optional service IDs
    ProtocolMap-BLE-ServiceList:
      type: object
      properties:
        ble:
          type: object
          properties:
            services:
              type: array
              items:
                type: object
                properties:
                  serviceID:
                    type: string
                    format: uuid
                    example: 12345678-1234-5678-1234-56789abcdef4
            cached:
              description: |-
                If we can cache information, then device doesn't need
                to be rediscovered before every connected.
              type: boolean
              default: false
            cacheIdlePurge:
              description: cache expiry period, when device allows
              type: integer
              example: 3600 # default 1 hour
            autoUpdate:
              description: |-
                autoupdate services if device supports it (default)
              type: boolean
              example: true
            bonding: #optional, by default defined in SCIM object 
              type: string
              example: default
              enum:
                - default 
                - none
                - justworks
                - passkey
                - oob

##  Protocol Mapping for BLE Service Map
    ProtocolMap-BLE-ServiceMap:
      required:
        - services
      type: object
      properties:
        ble:
          type: array
          items:
            $ref: '#/components/schemas/ProtocolMap-BLE-Service'

    ProtocolMap-BLE-Service:
      required:
        - serviceID
        - characteristics
      type: object
      properties:
        serviceID:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
        characteristics:
          type: array
          items:
            $ref: '#/components/schemas/ProtocolMap-BLE-Characterist\
ic'

    ProtocolMap-BLE-Characteristic:
      required:
        - characteristicID
        - flags
        - descriptors
      type: object
      properties:
        characteristicID:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
        flags:
          type: array
          example:
          - read
          - write
          items:
            type: string
            enum:
              - read
              - write
              - notify
        descriptors:
          type: array
          items:
            $ref: '#/components/schemas/ProtocolMap-BLE-Descriptor'

    ProtocolMap-BLE-Descriptor:
      required:
        - descriptorID
      type: object
      properties:
        descriptorID:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4

##  Protocol Mapping for BLE Broadcast
    ProtocolMap-BLE-Broadcast:
      required:
        - ble
      type: object
      properties:
        ble:
          type: object

## Protocol Mapping for BLE Property
    ProtocolMap-BLE-Propmap:
      required:
        - ble
      type: object
      properties:
        ble:
          required:
            - serviceID
            - characteristicID
          type: object
          properties:
            serviceID:
              type: string
              format: uuid
              example: 12345678-1234-5678-1234-56789abcdef4
            characteristicID:
              type: string
              format: uuid
              example: 12345678-1234-5678-1234-56789abcdef4
              
## Defines different types of BLE events
    ProtocolMap-BLE-Event:
      required:
        - ble
      type: object
      properties:
        ble:
          required:
            - type
          type: object
          properties:
            type:
              type: string
              example: gatt
              enum:
                - gatt
                - connection_events
                - advertisements
            serviceID:
              type: string
              example: 12345678-1234-5678-1234-56789abcdef0
            characteristicID:
              type: string
              example: 12345678-1234-5678-1234-56789abcdef1

## BLE Error codes
    ProtocolMap-BLE-ErrorCodes:
      type: object
      properties:
        nipcStatus:
          type: integer
          format: int32
          enum:
            - 1011 # BLE bonding failed
            - 1013 # BLE service discovery failed
<CODE ENDS>
]]></artwork></figure>

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

<figure anchor="protocolmapzigbee"><artwork><![CDATA[
<CODE BEGINS>
file "ProtocolMap-Zigbee.yaml"
openapi: 3.0.3
info:
  title: Non IP Device Control (NIPC) Zigbee Protocol Mapping
  description: |-
    Non IP Device Control (NIPC) Zigbee Protocol Mapping. 
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.10.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/

components:
  schemas:
# Zigbee Protocol Mapping
##  Protocol Mapping for Zigbee Service Map
    ProtocolMap-Zigbee-ServiceMap:
      required:
        - zigbee
      type: object
      properties:
        zigbee:
          type: array
          items:
            $ref: '#/components/schemas/ProtocolMap-Zigbee-Endpoint'

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

    ProtocolMap-Zigbee-Cluster:
      required:
        - clusterID
        - properties
      type: object
      properties:
        clusterID:
          type: integer
          format: int32
          example: 0
        properties:
          type: array
          items:
            $ref: '#/components/schemas/ProtocolMap-Zigbee-Property'

    ProtocolMap-Zigbee-Property:
      required:
        - propertyID
        - propertyType
      type: object
      properties:
        propertyID:
          type: integer
          format: int32
          example: 1
        propertyType:
          type: integer
          format: int32
          example: 32
          
## Protocol Mapping for Zigbee broadcast
    ProtocolMap-Zigbee-Broadcast:
      required:
        - zigbee
      type: object
      properties:
        zigbee:
          type: object

## Protocol mapping for Zigbee property
    ProtocolMap-Zigbee-Propmap:
      required:
        - zigbee
      type: object
      properties:
        zigbee:
          required:
            - endpointID
            - clusterID
            - propertyID
          type: object
          properties:
            endpointID:
              type: integer
              format: int32
              example: 1
            clusterID:
              type: integer
              format: int32
              example: 6
            propertyID:
              type: integer
              format: int32
              example: 16
            type:
              type: integer
              format: int32
              example: 1

    ProtocolMap-Zigbee-Event:
      allOf:  
        - $ref: '#/components/schemas/ProtocolMap-Zigbee-Propmap'

## Zigbee Error codes
    ProtocolMap-Zigbee-ErrorCodes:
      type: object
      properties:
        nipcStatus:
          type: integer
          format: int32
          enum:
            - 1021 # Zigbee join failed
<CODE ENDS>
]]></artwork></figure>

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

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

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

<figure><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.9.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-11"
    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: 12345678-1234-5678-1234-56789abcdef4
      - 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.9.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-11"
    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: 12345678-1234-5678-1234-56789abcdef4
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Extension-Bulk'
            examples:
              bulkRequest:
                $ref: '#/components/examples/bulkRequest'
        required: true
      responses:
        '202':
          description: Accepted
          headers:
            Location:
              schema:
                type: string
              description: URL to get the bulk status response
              example: /extensions/12345678-1234-5678-1234-56789abcd\
ef4/bulk/status?requestId=12345678-1234-5678-1234-56789abcdef4
        '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: 12345678-1234-5678-1234-56789abcdef4
      - name: requestId
        in: query
        description: Request ID of the bulk operation
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      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'
                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: 12345678-1234-5678-1234-56789abcdef4
      - name: requestId
        in: query
        description: Request ID of the bulk operation
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: OK
          headers:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: './Extension-ReadConditional.yaml#/compone\
nts/schemas/Extension-StatusResponse'
        '303':
          description: See Other
          headers:
            Location:
              schema:
                type: string
              description: URL to get the bulk response
              example: /extensions/12345678-1234-5678-1234-56789abcd\
ef4/bulk?requestId=12345678-1234-5678-1234-56789abcdef4
          content:
            application/json:
              schema:
                allOf:
                  - $ref: './Extension-ReadConditional.yaml#/compone\
nts/schemas/Extension-StatusResponse'
              examples:
                successExample:
                  summary: Success
                  value:
                    status: COMPLETED

components:
  schemas:
# Extensions
## Bulk schema Extension
    Extension-Bulk:
      allOf:
        - $ref: './Extension-ReadConditional.yaml#/components/schema\
s/Extension-Callback'
        - type: object
          properties:
            operations:
              type: array
              items:
                $ref: '#/components/schemas/Extension-BulkOperation'

## 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}
              example: /devices/12345678-1234-5678-1234-56789abcdef4\
/properties?propertyName=https://example.com/thermometer%23/sdfThing\
/thermometer/sdfProperty/temperature
            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}
              example: /devices/12345678-1234-5678-1234-56789abcdef4\
/properties?propertyName=https://example.com/thermometer%23/sdfThing\
/thermometer/sdfProperty/temperature
            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/12345678-1234-5678-1234-56789abcdef4/prop\
erties?propertyName=https://example.com/thermometer%23/sdfThing/ther\
mometer/sdfProperty/temperature
          - method: PUT
            path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\
erties?propertyName=https://example.com/thermometer%23/sdfThing/ther\
mometer/sdfProperty/temperature
            data:
              value: dGVzdA==
          - method: POST
            path: /extensions/12345678-1234-5678-1234-56789abcdef4/p\
roperties/read/conditional?propertyName=https://example.com/thermome\
ter%23/sdfThing/thermometer/sdfProperty/temperature
            data:
              value: dGVzdA==
              maxRepeat: 5
              retryTime: 1
    bulkResponse:
      summary: Bulk response example
      value:
        operations:
          - method: GET
            path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\
erties?propertyName=https://example.com/thermometer%23/sdfThing/ther\
mometer/sdfProperty/temperature
            response:
              value: dGVzdA==
          - method: PUT
            path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\
erties?propertyName=https://example.com/thermometer%23/sdfThing/ther\
mometer/sdfProperty/temperature
            response:
              status: 200
          - method: POST
            path: /extensions/12345678-1234-5678-1234-56789abcdef4/p\
roperties/read/conditional?propertyName=https://example.com/thermome\
ter%23/sdfThing/thermometer/sdfProperty/temperature
            response:
              value: dGVzdA==
    errorBulkResponse:
      summary: Error Bulk response example
      value:
        operations:
          - method: GET
            path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\
erties?propertyName=https://example.com/thermometer%23/sdfThing/ther\
mometer/sdfProperty/temperature
            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/12345678-1234-5678-1234-56789abcdef4/prop\
erties?propertyName=https://example.com/thermometer%23/sdfThing/ther\
mometer/sdfProperty/temperature
            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/12345678-1234-5678-1234-56789abcdef4/p\
roperties/read/conditional?propertyName=https://example.com/thermome\
ter%23/sdfThing/thermometer/sdfProperty/temperature
            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
<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.9.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-11"
    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: 12345678-1234-5678-1234-56789abcdef4
      - 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-File'
        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 File Extension
    Extension-File:
      required:
        - fileURL
      type: object
      properties:
        fileURL:
          type: string
          example: "https://domain.com/firmware.dat"
        chunksize:
          type: integer
<CODE ENDS>
]]></artwork></figure>

</section>
<section anchor="nipc-api-firmware-update-extension"><name>NIPC API firmware update extension</name>

<figure><artwork><![CDATA[
<CODE BEGINS>
file "Extension-Firmware.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 firmware upgrade extension
  description: |-
    Non IP Device Control (NIPC) API firmware upgrade extension, 
    requires the file extension
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.9.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-11"
    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}/firmware:
    put:
      tags:
        - NIPC API extensions
      summary: Upgrade the firmware of a device
      description: |-
        Update the firmware of a device. Will perform all operations
        required to upgrade the firmware. ID cannot be a group-id.
      operationId: upgradeFirmware
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      requestBody:
        content:
          application/json:
            schema:
              allOf:
                - $ref: './Extension-File.yaml#/components/schemas/E\
xtension-File'
                - $ref: '#/components/schemas/Extension-Firmware'
                - $ref: './Extension-ReadConditional.yaml#/component\
s/schemas/Extension-Callback'
        required: true
      responses:
        '202':
          description: Accepted
          headers:
            Location:
              schema:
                type: string
              description: Location of the resource
              example: /12345678-1234-5678-1234-56789abcdef4/extensi\
on/firmware/status?requestId=12345678-1234-5678-1234-56789abcdef4
        default:
          description: Error response
          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:
                      anyOf:
                        - $ref: '../NIPC.yaml#/components/schemas/Id'
                        - allOf:
                          - $ref: '../NIPC.yaml#/components/schemas/\
FailureResponse'
                          - $ref: '#/components/schemas/ExtensionErr\
orCodes'
              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 the status of a firmware upgrade of a device
      description: |-
        Get the status of a firmware upgrade of a device. 
        Returns success when ongoing or completed, with a reason. 
        Returns failure when upgrade has failed. 
        ID cannot be a group-id.
      operationId: upgradeFirmwareStatus
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: requestId
        in: query
        description: Request ID of the firmware upgrade operation
        required: true
        schema:
          type: string
          example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: OK
          headers:
            Location:
              schema:
                type: string
              description: Location of the resource
          content:
            application/json:
              schema:
                $ref: '../NIPC.yaml#/components/schemas/Id'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/FailureR\
esponse'
                  - $ref: '#/components/schemas/ExtensionErrorCodes'
  /extensions/{id}/firmware/status:
    get:
      tags:
        - NIPC API extensions
      summary: Get the status of a firmware upgrade of a device
      description: |-
        Get the status of a firmware upgrade of a device. 
        Returns success when ongoing or completed, with a reason. 
        Returns failure when upgrade has failed. 
        ID cannot be a group-id.
      operationId: upgradeFirmwareStatus
      parameters:
      - name: id
        in: path
        description: The ID of the device. Group ID is not allowed.
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: requestId
        in: query
        description: Request ID of the firmware upgrade operation
        required: true
        schema:
          type: string
          example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          headers:
          content:
            application/json:
              schema:
                allOf: 
                  - $ref: '../NIPC.yaml#/components/schemas/Id'
                  - $ref: './Extension-ReadConditional.yaml#/compone\
nts/schemas/Extension-StatusResponse'
        '303':
          description: See Other
          headers:
            Location:
              schema:
                type: string
              description: URL to get the firmware response
              example: /12345678-1234-5678-1234-56789abcdef4/extensi\
on/firmware?requestId=12345678-1234-5678-1234-56789abcdef4
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/Id'
                  - $ref: './Extension-ReadConditional.yaml#/compone\
nts/schemas/Extension-StatusResponse'
              examples:
                successExample:
                  summary: Completed
                  value:
                    id: 12345678-1234-5678-1234-56789abcdef4
                    status: COMPLETED

components:
  schemas:
# Extensions
## a Firmware Extension
    Extension-Firmware:
      type: object
      properties:
        firmware:
          type: string
          enum:
            - nordic
            - silabs

    ExtensionErrorCodes:
      type: object
      properties:
        nipcStatus:
          type: integer
          format: int32
          enum:
            - 1600 # Firmware rollback
            - 1601 # Firmware update failed
<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.9.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-11"
    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: 12345678-1234-5678-1234-56789abcdef4
      - 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
              description: |-
                URL to get the conditional read status
              example: /12345678-1234-5678-1234-56789abcdef4/extensi\
on/property/temperature/read/conditional/status?requestId=12345678-1\
234-5678-1234-56789abcdef4
            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: 12345678-1234-5678-1234-56789abcdef4
                          property: https://example.com/heartrate#/s\
dfObject/thermostat/sdfProperty/temperature
                          value: dGVzdA==
                      failedResponse:
                        summary: Failed
                        value:
                          id: 12345678-1234-5678-1234-56789abcdef4
                          status: 400
                          nipcStatus: 1000
                          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: 12345678-1234-5678-1234-56789abcdef4
      - 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: requestId
        in: query
        description: |-
          Request ID of the conditional read operation
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      - 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: requestId
        in: query
        description: Request ID of the conditional read operation
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: OK
          headers:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Extension-StatusResp\
onse'
        '303':
          description: See Other
          headers:
            Location:
              schema:
                type: string
              description: URL to get the conditional read response
              example: /12345678-1234-5678-1234-56789abcdef4/extensi\
on/property/temperature/read/conditional?requestId=12345678-1234-567\
8-1234-56789abcdef4
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Extension-StatusResp\
onse'
              examples:
                successExample:
                  summary: Completed
                  value:
                    id: 12345678-1234-5678-1234-56789abcdef4
                    status: COMPLETED

components:
  schemas:
# Extensions
    Extension-Callback:
      type: object
      properties:
        callback:
          type: object
          properties:
            url:
              description: |-
                URL to send the callback to
                (default is the same as the request URL)
              type: string
              example: "http://localhost:8080/callback"
            headers:
              description: |-
                Headers to include in the callback
                (default is empty)
              type: object
              example:
                x-api-key: "1234567890"
              additionalProperties:
                type: string

    Extension-StatusResponse:
      type: object
      properties:
        status:
          description: |-
            Status of the callback
          type: string
          enum:
            - IN_PROGRESS
            - COMPLETED

    Extension-ConditionalRead:
      allOf:
        - $ref: '../NIPC.yaml#/components/schemas/Value'
        - $ref: '#/components/schemas/Extension-Callback'
        - type: object
          properties:
            maxRepeat:
              description: |-
                maximum time the conditional read should repeat
                (default 5, max 10)
              type: integer
              example: 5
            retryTime:
              description: |-
                time between reads in seconds (default 1, max 10)
              type: integer
              example: 1
<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.9.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-11"
    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}/manage/transmit:
    post:
      tags:
        - NIPC API extensions
      summary: Broadcast to a device
      description: |-
        Broadcast a payload to a device. The broadcast is performed \
on the AP where the device was last seen
      operationId: ActionBroadcast
      parameters:
        - name: id
          in: path
          description: The ID of the device. Group ID is not allowed.
          required: true
          schema:
            type: string
            format: uuid
            example: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      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: 12345678-1234-5678-1234-56789abcdef4
      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="thermometer-sdf"><name>Example SDF model with protocol mappings for BLE</name>

<figure title="Example SDF model with protocol mappings for BLE"><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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
ZSbBDSO9cYIBFXfK47IHAWbwE1pGdw6IDSbvpXXvbvlDyeT4Jl4EIhVHINHA
nqsjNx01VS6UPOgpUI6iy3HSXLbLXOm73gg6E2pm56WPnGy+mC3eEXB5tVk9
u94S94aYsoy2krMbkp+SSMjJT/9Aodus6comUMF14uLvg+imbaAlkDYK3Nb3
DHVVopXeOm8arUj6ODfItrt6RCOq3PzRbiHcygwWi7T3l066pFz11nbfvj5E
jWDPl0dJoEcf+9i6sw9VHm6lNp0OKReAVLKT2uWUDLm82Lh30uuEawdvfjt8
9/blu/2jozUUGq2J3v9DVC6V2btSlTW3C8Iy/94Jx2khPlBSInjIhVQbiwR3
Qkr/TKclN1FLHNOhBAJaLyWvBZngXAoZSu7qvGXNYBpkqfLF91Rk5/NX+/dp
nglWmk6mAxLpiCP4Ajm1+6Uq/qomWFPL+ACwCSukYtLyPDxNz5DFd1SY6CQ5
OS102dUPcVyqYAxCz7RjZxhnpMIYVGBlKtWH5H6nQpM6ubcUyhEs1NFFAhps
UMqoniifAqT31sIWVDXOVa5wgz5ZPCF6aYtVViJ1vPJFFoexgKpieIs4Tl1k
V0ZXYp5deVyS2UtMUiLLy0tilgYG+YWoOFjClrxmH5162qFVtrhZ+LLmViHS
vr6WoMKeqBOrCmtGacpM4Rd6v2OcYjBMMJWwzgMpgx1xdUwCSjJCR2/ncyy2
QXUp4iErZJj1BDdAVaAj0czIOHZtOpSdjVeP5fiGpguOdTFlYi2I9MK3OnF9
xzOgVDQcJ5OkoCFVxJDq3woWxTWuoX+0WZbOz88Co/SvctJQX2qseKidZIfi
l6l8Q3smhlIvWL7tzyk4j2OPokGW5jaC5R11epCy2NVK8UgOKEzXbGEvLEWv
pCUFROkMhrdrODneqy7nRExBT+7t8EFH/X3+WlTbncO8PqULDl1moGY6ZcVX
jSNbwoxTClPC9OQ1wlXXd7Cc9zTZpVRuKJciULue6Tril9VbFotrVTIdZRG7
PjG7xcJO0KtW5yOSelmAJhNpFg2TVLgK9p6Rnm0OI+mC4l68hsBaY892E5pp
d6mQliaIfEuW3qM6W3rxTkoR0jvGyYfYOVV28K+VTEBX4Qoi5wSTPO4gsaSr
4/04kxpcqidd9SkwZ6AcQEWjAcEoo+HN4GBH0muqmtGvo5nJf9OnuAydiEed
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
vVa7/j+6vCSKiJ0czUej5BMeXpbudrV0h5GbjvCyZxiWWb1LynwEpg2Vojwx
oIBpmKJgWYZzSZ3477/duzOLitO8ywmrxvcR7MjZSnDSwm7CEfJhuN4zn5BO
qmRYDOcHEk/h/CUh2Qi0Tsz/MmyZVSBmymowVE7XrC9YHzd7/su7V9u4VGVY
Ozs76+FEeml2sh6RdYDyp9Ay9OxIMb9PVUKN7p6Hr385Oha9isKLceehb221
a9nxnbX7WjclxQagXJIqGGMEJKWBi3gyQ5OEm1HhSPTQh70tlLcBU589fPSE
zBHLnBE6aOpkeCAdKFArgVm/ayMWLPwtHalflquvIB20+a1A4MAzegUsvFOX
BeDqIf8+af06MytnCVg+JcCqZrQwicAKUgesaq6NaQeWTzSw+mm5qQmWz0Ow
qhnVZS5YPk3BjczIylWwfBaDlSF+Td6D5ZMcrHZG1bQIy+dAWP2M3JO0fIqE
FeLRgqQKy+dSuKm5udkXlk+4cFPz8oTWL5+a4aYmV0rmsHwChy8ANWduy2R6
uKm51eaGWD4zxE1NcaW5JG5wrvXpJ5bPPHGD81tVrorVTnRhhosr5LVY+dSq
mTCWT31xg7Nyk2UsnyLDY+mnuPeK4kkJIeVOD9kQyqeR3KBTDBc6DffpHrBi
qDBFbiIrMTQozqC1hQg/9EZQWUqHVm6IY0d1npKyQXeMH2MlKefKSYFmpXOo
0qUYJaXEjNbkC5dmqlzk/wZ/2X27tx8+33958OborwFZYNdSvhDonU/Ga8GP
NY5Uy3hS/YjLOo8m4+44mp7MoxMmvXgv+U+cIVo7vuGleZefESIMs2hUrG9t
bG10N98H77fW+V0gc9wOH/Q2eg8CvHPdDkIOlNsGkWEaHhwqiUYsZeE9tDLc
p9yhoa44Sfffn7tkbSIcsO68YZ/e7R8dY/ULWywbR+e0vcp7HOBNzUUhVhvh
ZmDVfjWSR1u5vqD7DrW2L0VUz05ybkk5aerZc/EGaqzD9bx3bXZm8Jyz5nIl
CExtPj6X4Wfj9ByREaAYZ5P87UiK7m3TEYW9yc+ik5M46yXpOn2BuQLkAnyb
w4fwenw77PcxQ++Hyb8OkHGiZxm8BejFVMwBP2RHjuPnXFAUNHr1B6wipx3Z
6D3rbVCm3WwajffSAeaVdzeNbEZkfiQkCaQjhUlIIIFaDjCHSRIXI0andMAo
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
q95slUgdYlOq5QIA02/RCJW7AgA=

-->

</rfc>

