Internet-Draft NIPC April 2025
Brinckman, et al. Expires 9 October 2025 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-ietf-asdf-nipc-04
Published:
Intended Status:
Standards Track
Expires:
Authors:
B. Brinckman
Cisco Systems
R. Mohan
Cisco Systems
B. Sanford
Philips

An Application Layer Interface for Non-IP device control (NIPC)

Abstract

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.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 9 October 2025.

Table of Contents

1. Introduction

1.1. Scope

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 [BLE53] and [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.


    +-------------+              +---------+              +--------+
    | Application |<------------>| Gateway |<------------>| Non-IP |
    |    app      |   IP-based   |         |    Non-IP    | Device |
    +-------------+   Operation  +---------+   Operation  +--------+

Figure 1: Gateway for non-IP Devices

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 ([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 [BLE53] and [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.

A standardized Non-IP Gateway interface has following benefits:

  • Avoid the need for parallel Non-IP infrastructure.

  • Avoid the need for applications to perform bespoke integrations for different environments.

  • Faster and more cost-effective adoption of Non-IP devices in IP network environments.

1.2. Non-IP Gateway

A non-IP gateway MUST provide at least following functions:

  • Authentication and authorization of application clients that will leverage the gateway API to communicate with Non-IP devices.

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

  • The ability to consume an interaction model for a class of devices. This allows the gateway to understand how to interact with a device.

  • An API that allows for bi-directional communication to non-IP devices.

  • One or more channels to process requests, responses, and asymmetric communications with the non-IP radio resources (Access Points) at its disposal.

  • The ability to stream telemetry received from non-IP devices in real-time to applications on the IP network.

The definition of the onboarding function is out of scope of this document, but can be provided by a provisioning interface such as [RFC7644] leveraging [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.

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.

                             +-----------------------------------+
                             |                                   |
    +-----------+   Request  |  +---------+                      |
    | onboarding|-------------->|  SCIM   |                      |
    |    app    |<--------------| Server  |                      |
    +-----------+  Ctrl Endpt|  +---------+                      |
                             |                                   |
    +-----------+            |  +------------+  +-------+  +--+  |
    |  Control  |>...REST....|.>|    NIPC    |..|  AP   |..|D |  |
    |     &     |            |  |   Gateway  |  +-------+  +--+  |
    | Telemetry |<..pub/sub..|.<|            |                   |
    |    Apps   |            |  +------------+                   |
    +-----------+            |                                   |
                             |       Network Deployment          |
                             +-----------------------------------+

Figure 2: Basic Architecture

Figure 2 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 & AP). The role of the application layer gateway is to provide a gateway functioni 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.

1.3. Terminology

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 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

2. Architecture

2.1. Overview

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.

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 [I-D.ietf-asdf-sdf].

    +------------+
    |    SCIM    |
    |   object   |           +----------------+
    |    {id}    |---------->|                |
    +------------+           | NIPC Operation |
                             |    - Property  |
                             |    - Action    |
    +------------+           |    - Event     |
    |     SDF    |---------->|                |
    |    model   |           +----------------+
    |            |
    +------------+

Figure 3: NIPC prerequisites

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.

2.2. Onboarding

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 [RFC7644] with [I-D.ietf-scim-device-model], as the SCIM device schema has been developed to contain all nessary attributes and extensions to support NIPC.

2.3. Registrations

NIPC registration 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.

2.3.1. SDF model registrations

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 [I-D.ietf-asdf-sdf].

2.3.2. Data application registration

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 registration API allows mapping of an event to a data app as well as a protocol.

2.4. Protocol mapping

An SDF model can fully describe 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.

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.

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

     - protocolmap
        |
        |> ble
        |     - BLE property
        |
        |> zigbee
              - Zigbee property

Figure 4: Property Mapping

As shown in Figure 4, protocol-specific properties must be embedded in a protocolmap object, for example a "ble" or a "zigbee" object.

Table 1: Protocol objects
Attribute Req Type Example
ble T object an object with BLE-specific attributes
zigbee T object an object with Zigbee-specific attributes

where-

  • "ble" is an object containing properties that are specific to the BLE protocol.

  • "zigbee" is an object containing properties that are specific to the Zigbee protocol.

  • Other protocol mapping objects can be added by creating a new protocol object

Example property mapping:

"sdfObject": {
  "healthsensor": {
    "sdfProperty": {
      "heartrate": {
        "description": "The current measured heart rate",
        "type": "number",
        "unit": "beat/min",
        "observable": false,
        "writable": false,
        "protocolMap": {
          "ble": {
            "serviceID": "12345678-1234-5678-1234-56789abcdef4",
            "characteristicID": "12345678-1234-5678-1234-56789abcdef4"
          }
        }
      }
    }
  }
}
Figure 5: Example property mapping

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.

2.5. NIPC Operations

NIPC operations are protocol-neutral operations on SDF affordances, more specifically properties, actions & 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.

2.5.1. Properties APIs

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

2.5.2. Actions

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

2.5.3. Events

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

2.5.4. Connection management for NIPC Operations

For protocols that require connection management before executing an operation, a NIPC gateway can 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 should 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 /{id}/action/connection action 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.

2.5.5. Action APIs with embedded protocol mapping

Action APIs with embedded protocol mapping are APIs that perform actions on devices, but do not use registered affordances. These APIs have embedded protocol mappings. They require explicit connection management.

2.5.6. Extensions

Extensions are not part of the core NIPC API specification, but extensions to it. Extensions are compound APIs. They leverage basic NIPC operations but combine multiple operations in to one API call for efficiency. An example of this is the the bulk operation, allowing to send multiple operations in one operation. Extensions can be generic, IANA registered extentions, or vendor specific extensions.

2.6. Events publish subscribe interface

Events are published on a publish/subscribe interface. Events can be of different types:

  • Streaming data from devices: Streaming data is activated/deactivated with the NIPC events API

  • Broadcasts from devices

  • Connection events: Devices connecting & disconnecting

2.7. Protocols

2.7.1. NIPC APIs

NIPC is a protocol that is based on RESTful HTTP [RFC9114]. Along with HTTP headers and URIs, NIPC uses JSON [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 standard JSON media type "application/json", except for the SDF model registration APIs, where the media type reflects the content as an SDF model, and hence is media type "application/sdf+json".

2.7.2. NIPC publish/subscribe events

NIPC publish/subscribe events are encoded in CBOR ([RFC8949]) and can be delivered over either:

  • MQTT

  • Webhook

  • Websocket

2.8. Paths

2.8.1. General

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 [RFC3986]. That initial path for NIPC is recommended to be /nipc. For example:

  "https://example.com/nipc/"

Based on this a well_known URI [RFC8615] of nipc can be defined.

Additionally a version number may be added, for example:

  "https://example.com/nipc/v1/"

2.8.2. NIPC Registrations

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

paths:

  • /registration/model

  • /registration/data-app

2.8.3. NIPC Operations

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:

  "https://example.com/nipc/v1/{id}"

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

  • property

  • event

  • action

  • extension

These are described in Section 2.5.

Every NIPC API response has a X-Request-ID header, which is a unique identifier for the request. Each successful response will have a HTTP status code of 200 OK.

A failure response will consist of a HTTP status code of 4xx or 5xx, and will contain an error code and reason field. The error codes and the appropriate error codes are described in Section 6.

Failure response:

Example of a failure response:

{
  "errorCode": 2000,
  "reason": "Generic error message"
}
Figure 6: Example failure response

where-

  • "errorCode" is error code that indicates the type of error, as described in Table 3

  • "reason" is a human-readable error message

3. NIPC Registrations

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.

3.1. SDF model registration APIs

These APIs allow applications to register an SDF model for a class of devices. These APIs use the application/sdf+json media type, as described in Section 7.1 of [I-D.ietf-asdf-sdf].

3.1.1. Register an sdf model

Method: POST /registration/model

Description: Registers an SDF model for a class of devices

Request Body:

  • an SDF model in JSON format, similar to the example in Appendix D.

Response:

Example of a response:

{
  "sdfRef": "https://example.com/heartrate#/sdfObject/healthsensor"
}
Figure 7: Example register sdf model response

where-

  • "sdfRef" is the reference to the top-level sdfThing or sdfObject in the SDF model

  • "id" is the id of the sdf model

3.1.2. Get all sdf models

Method: GET /registration/model

Description: Gets all sdf models registered with the gateway

Response:

Example of a response:

[
  {
    "sdfRef": "https://example.com/heartrate#/sdfObject/healthsensor"
  }
]
Figure 8: Example get all sdf models response

where-

  • "sdfRef" is the reference to the top-level sdfThing or sdfObject in the SDF model

  • "id" is the id of the sdf model

3.1.3. Get an sdf model

Method: GET /registration/model/{sdfRef}

Description: Gets an sdf model registered with the gateway

Parameters:

  • sdfRef: the reference to the top-level sdfThing or sdfObject in the SDF model. This is a percent-encoded URL string.

Response:

The sdf model is returned in JSON format, similar to the example in Appendix D.

3.1.4. Delete an sdf model

Method: DELETE /registration/model/{sdfRef}

Description: Deletes an sdf model registered with the gateway

Parameters:

  • sdfRef: the reference to the top-level sdfThing or sdfObject in the SDF model. This is a percent-encoded URL string.

Response:

Example of a response:

{
  "sdfRef": "https://example.com/heartrate#/sdfObject/healthsensor"
}
Figure 9: Example delete sdf model response

where-

  • "sdfRef" is the reference to the top-level sdfThing or sdfObject in the SDF model

  • "id" is the id of the sdf model

3.1.5. Update an sdf model

Method: PUT /registration/model/{sdfRef}

Description: Updates an sdf model registered with the gateway

Parameters:

  • sdfRef: the reference to the top-level sdfThing or sdfObject in the SDF model. This is a percent-encoded URL string.

Request Body:

  • an SDF model in JSON format, similar to the example in Appendix D.

Response:

Example of a response:

{
  "sdfRef": "https://example.com/heartrate#/sdfObject/healthsensor"
}
Figure 10: Example update sdf model response

where-

  • "sdfRef" is the reference to the top-level sdfThing or sdfObject in the SDF model

  • "id" is the id of the sdf model

3.2. Data application registration APIs

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 Section 6 of [I-D.ietf-scim-device-model].

3.2.1. Register a data application

Method: POST /registration/data-app/{data-app-id}

Description: Registers a data application with the gateway

Parameters:

  • data-app-id: the id of the data application

Request Body:

  • events: a list of events that the data application wants to receive streaming data for.

The request body also contains one of the following:

  • mqttClient: an empty object that denotes that the data application is an MQTT client that will receive streaming data over MQTT

  • mqttBroker: an object that contains the MQTT broker information where the broker will publish the streaming data.

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

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

Example of a request body:

{
  "events": [
    "https://example.com/heartrate#/sdfObject/healthsensor/sdfEvent/fallDetected"
  ],
  "mqttClient": {}
}
Figure 11: Example with mqttClient

Example of a request body for a data application that is an MQTT broker:

{
  "events": [
    "https://example.com/heartrate#/sdfObject/healthsensor/sdfEvent/fallDetected"
  ],
  "mqttBroker": {
    "URI": "mqtt.example.com:1883",
    "username": "user",
    "password": "password"
  }
}
Figure 12: Example with mqttBroker

Response:

If successful, the response will be identical to the request body.

3.2.2. Update a data application

Method: PUT /registration/data-app/{data-app-id}

Description: Updates a data application with the gateway

Parameters:

  • data-app-id: the id of the data application

Request Body: Same as the request body for the register data application API.

Response:

If successful, the response will be identical to the request body.

3.2.3. Get a data application

Method: GET /registration/data-app/{data-app-id}

Description: Gets a data application registered with the gateway

Parameters:

  • data-app-id: the id of the data application

Response:

The response will be identical to the request body for the register data application API.

3.2.4. Delete a data application

Method: DELETE /registration/data-app/{data-app-id}

Description: Deletes a data application registered with the gateway

Parameters:

  • data-app-id: the id of the data application

Response:

The response will be identical to the request body for the register data application API.

4. NIPC APIs

The primary goal of the NIPC APIs is to exchange data with a Non-IP device, by means of reading, writing or streaming NIPC properties to applications.

The NIPC APIs are divided into 3 categories:

An SDF model must be registered for the device in order to use these NIPC Property, Event and Action APIs. The SDF model can be a top-level sdfThing with multiple sdfObjects or a top-level sdfObject. These APIs depend on the SDF affordance (i.e. sdfProperty, sdfEvent and sdfAction) objects defined in the SDF model and a device ID that is defined in [I-D.ietf-scim-device-model]. The SDF affordance can be referenced using the global name of the SDF affordance as described in Section 4 of [I-D.ietf-asdf-sdf].

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. The global name must be percent-encoded to be used in the URL as per [RFC3986].

4.1. NIPC Property APIs

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 will be leveraged without modifying it.

4.1.1. Write a value

Method: POST /{id}/property/{property}

Description: Writes a value to a property on a device

Parameters:

  • id: the id of the device

  • property: the property to write to

Request Body:

  • value: the bytes to be written in base64 encoding

Response:

Example of a write property response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "property": "https://example.com/heartrate#/sdfObject/thermostat/sdfProperty/temperature",
  "value": "dGVzdA=="
}
Figure 13: Example write property response

where-

  • "id" is the id of the device

  • "property" is the property that was written to

  • "value" is the bytes that were written in base64 encoding

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.1.2. Read a value

Method: GET /{id}/property/{property}

Description: Reads a value from a property on a device

Parameters:

  • id: the id of the device

  • property: the property to read from

Response:

Example of a read property response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "property": "https://example.com/heartrate#/sdfObject/thermostat/sdfProperty/temperature",
  "value": "dGVzdA=="
}
Figure 14: Example read property response

where-

  • "id" is the id of the device

  • "property" is the property that was read from

  • "value" is the bytes that were read in base64 encoding

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.1.3. Write multiple values

Method: PUT /{id}/property

Description: Write values to one or more properties on a device

Parameters:

  • id: the id of the device

Request Body:

  • an array of properties to update, each containing a property and a value

Example body updating multiple properties:

{
  "properties": [
    {
      "property": "https://example.com/heartrate#/sdfObject/thermostat/sdfProperty/temperature",
      "value": "dGVzdA=="
    },
    {
      "property": "https://example.com/heartrate#/sdfObject/thermostat/sdfProperty/humidity",
      "value": "eGVzdB=="
    }
  ]
}
Figure 15: Example updating multiple properties

Response:

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "properties": [
    {
      "property": "https://example.com/heartrate#/sdfObject/thermostat/sdfProperty/temperature",
      "value": "dGVzdA=="
    },
    {
      "property": "https://example.com/heartrate#/sdfObject/thermostat/sdfProperty/humidity",
      "value": "eGVzdB=="
    }
  ]
}
Figure 16: Example update multiple properties response

where-

  • "id" is the id of the device

  • "properties" is an array of properties that were updated, each containing a property and a value

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.1.4. Read multiple values

Method: GET /{id}/property

Description: Read values from one or more properties on a device

Parameters:

  • id: the id of the device

Query Parameters:

  • property: a comma separated list of properties to read

Response:

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "properties": [
    {
      "property": "https://example.com/heartrate#/sdfObject/thermostat/sdfProperty/temperature",
      "value": "dGVzdA=="
    },
    {
      "property": "https://example.com/heartrate#/sdfObject/thermostat/sdfProperty/humidity",
      "value": "eGVzdB=="
    }
  ]
}
Figure 17: Example read multiple properties response

where-

  • "id" is the id of the device

  • "properties" is an array of properties that were read, each containing a property and a value

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.2. NIPC Event APIs

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.

The event is a global name reference to an sdfEvent. If the data application registered for this event is an MQTT broker or client, the event will be used as the MQTT topic as well. When used as a topic, the event will be percent-encoded as per [RFC3986] since '/' and '#' have special meaning in MQTT.

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.

4.2.1. Enable event reporting

Method: POST /{id}/event/{event}

Description: Enables an event on a specific device

Parameters:

  • id: the id of the device or group of devices

  • event: the event to enable

The event is a URL encoded string that is the absolute URI that is a global name reference to an sdfEvent.

Response:

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "event": "https://example.com/heartrate#/sdfObject/healthsensor/sdfEvent/fallDetected"
}
Figure 18: Example enable event response

where-

  • id: the id of the device or group of devices

  • "event" is the event that was enabled

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.2.2. Disable event reporting

Method: DELETE /{id}/event/{event}

Description: Disables an event on a specific device

Parameters:

  • id: the id of the device or group of devices

  • event: the event to disable

The event is a URL encoded string that is the absolute URI that is a global name reference to an sdfEvent.

Response:

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "event": "https://example.com/heartrate#/sdfObject/healthsensor/sdfEvent/fallDetected"
}
Figure 19: Example disable event response

where-

  • id: the id of the device or group of devices

  • "event" is the event that was disabled

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.2.3. Get event status

Method: GET /{id}/event/{event}

Description: Get the status of an event on a specific device

Parameters:

  • id: the id of the device or group of devices

  • event: the event to get the status of

The event is a URL encoded string that is the absolute URI that is a global name reference to an sdfEvent.

Response:

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "event": "https://example.com/heartrate#/sdfObject/healthsensor/sdfEvent/fallDetected"
}
Figure 20: Example get event status response

where-

  • id: the id of the device or group of devices

  • "event" is the event that was queried

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.2.4. Get status of multiple events

Method: GET /{id}/event

Description: Get the status of one or more events on a specific device

Parameters:

  • id: the id of the device or group of devices

Query Parameters:

  • event: a comma separated list of events to get the status of

Response:

Example of a response:

{
  "events": [
    {
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "event": "https://example.com/heartrate#/sdfObject/healthsensor/sdfEvent/fallDetected"
    }
  ]
}
Figure 21: Example get multiple events status response

where-

  • "id" is the id of the device or group of devices

  • "events" is an array of events that were queried

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.3. NIPC Action APIs

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.

4.3.1. Perform an action

Method: PUT /{id}/action/{action}

Description: Perform an action on a specific device

Parameters:

  • id: the id of the device

  • action: the action to perform

Request Body:

  • value: the bytes to be written in base64 encoding.

The request body is optional and can be empty if the underlying protocol allows an action without a value.

Example body of an action:

{
  "value": "dGVzdA=="
}
Figure 22: Example action

Response:

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "action": "https://example.com/heartrate#/sdfObject/healthsensor/sdfAction/start"
}
Figure 23: Example action response

where-

  • "id" is the id of the device

  • "action" is the action that was performed

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.4. NIPC Action APIs with embedded protocol mapping

These APIs allow applications to perform actions on devices, but do not use registered properties, events or actions. These APIs do not perform an implicit connection, so a connection must be established before calling these APIs.

4.4.1. Connect to a device

Method: POST /{id}/action/connection

Description: Connect to a device

Parameters:

  • id: the id of the device

Request Body:

  • Connection retry parameters

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

Example body of a connection without specific discovery of properties:

{
  "retries": 3,
  "retryMultipleAPs": true
}
Figure 24: Example connection

where-

  • "retries" defines the number of retries in case the operations does not succeed

  • "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.

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.

Example body of a BLE connection with specific discovery of properties:

{
  "retries": 3,
  "retryMultipleAPs": true,
  "protocolMap": {
    "ble": {
      "services": [
        {
          "serviceID": "12345678-1234-5678-1234-56789abcdef4"
        }
      ],
      "cached": false,
      "cacheIdlePurge": 3600,
      "autoUpdate": true,
      "bonding": "default"
    }
  }
}
Figure 25: Example connection with explicit discovery of connections

where in the BLE protocol object:

  • "services" is an array of services defined by their serviceIDs.

  • "cached" refers to whether the services need to be cached for subsequent connects, in order not to perform service discovery on each request.

  • "cacheIdlepurge" defines how long the cache should be maintained before purging

  • some devices support notifications on changes in services, "autoUpdate" allows the network to update services based on notification (on by default)

  • "bonding" allows you to override the bonding method configured when onboarding the device

Response:

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 Figure 26.

    services
     - serviceID
        |
        |> characteristics
            - charactericID
            - flags
               |
               |> Descriptors
                   - descriptorID
Figure 26: BLE Services

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "protocolMap": {
    "ble": [
      {
        "serviceID": "12345678-1234-5678-1234-56789abcdef4",
        "characteristics": [
          {
            "characteristicID": "12345678-1234-5678-1234-56789abcdef4",
            "flags": [
              "read",
              "write"
            ],
            "descriptors": [
              {
                "descriptorID": "12345678-1234-5678-1234-56789abcdef4"
              }
            ]
          }
        ]
      }
    ]
  }
}
Figure 27: Example connection response

where-

  • "id" is the id of the device

  • "protocolMap" contains an Array of BLE services as shown in Figure 26

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.4.2. Update a connection

Method: PUT /{id}/action/connection

Description: Update cached ServiceMap for a device. Full service discovery will be performed, unless specific services are described in the API body.

Parameters:

  • id: the id of the device

Request Body:

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

Example body of an update connection:

{
  "protocolMap": {
    "ble": {
      "services": [
        {
          "serviceID": "12345678-1234-5678-1234-56789abcdef4"
        }
      ],
      "cached": false,
      "cacheIdlePurge": 3600,
      "autoUpdate": true
    }
  }
}
Figure 28: Example service discovery response

where in the BLE protocol object:

  • "services" is an array of services defined by their serviceIDs.

  • "cached" refers to whether the services need to be cached for subsequent connects, in order not to perform service discovery on each request.

  • "cacheIdlepurge" defines how long the cache should be maintained before purging

  • some devices support notifications on changes in services, "autoUpdate" allows the network to update services based on notification (on by default)

Response:

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 Figure 26.

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "protocolMap": {
    "ble": [
      {
        "serviceID": "12345678-1234-5678-1234-56789abcdef4",
        "characteristics": [
          {
            "characteristicID": "12345678-1234-5678-1234-56789abcdef4",
            "flags": [
              "read",
              "write"
            ],
            "descriptors": [
              {
                "descriptorID": "12345678-1234-5678-1234-56789abcdef4"
              }
            ]
          }
        ]
      }
    ]
  }
}
Figure 29: Example connection response

where-

  • "id" is the id of the device

  • "protocolMap" contains an Array of BLE services as shown in Figure 26

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.4.3. Disconnect from a device

Method: DELETE /{id}/action/connection

Description: Disconnect from a device

Parameters:

  • id: the id of the device

Response:

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4"
}
Figure 30: Example disconnect response

where-

  • "id" is the id of the device

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.4.4. Get connection status

Method: GET /{id}/action/connection

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

Parameters:

  • id: the id of the device

Response:

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "protocolMap": {
    "ble": [
      {
        "serviceID": "12345678-1234-5678-1234-56789abcdef4",
        "characteristics": [
          {
            "characteristicID": "12345678-1234-5678-1234-56789abcdef4",
            "flags": [
              "read",
              "write"
            ],
            "descriptors": [
              {
                "descriptorID": "12345678-1234-5678-1234-56789abcdef4"
              }
            ]
          }
        ]
      }
    ]
  }
}
Figure 31: Example connection status response

where-

  • "id" is the id of the device

  • "protocolMap" contains an Array of BLE services as shown in Figure 26

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.4.5. Write a value using protocol mapping

Method: POST /{id}/action/property/write

Description: Writes a value to a property on a device using protocol mapping

Parameters:

  • id: the id of the device

Request Body:

  • value: the bytes to be written in base64 encoding

  • protocolMap: the protocol mapping for the property

Example body of a write property:

{
  "value": "dGVzdA==",
  "protocolMap": {
    "ble": {
      "serviceID": "12345678-1234-5678-1234-56789abcdef4",
      "characteristicID": "12345678-1234-5678-1234-56789abcdef4"
    }
  }
}
Figure 32: Example write property

Response:

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "value": "dGVzdA==",
  "protocolMap": {
    "ble": {
      "serviceID": "12345678-1234-5678-1234-56789abcdef4",
      "characteristicID": "12345678-1234-5678-1234-56789abcdef4"
    }
  }
}
Figure 33: Example write property response

where-

  • "id" is the id of the device

  • "value" is the bytes that were written in base64 encoding

  • "protocolMap" is the protocol mapping for the property

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.4.6. Read a value using protocol mapping

Method: POST /{id}/action/property/read

Description: Reads a value from a property on a device using protocol mapping

Parameters:

  • id: the id of the device

Request Body:

  • protocolMap: the protocol mapping for the property

Example body of a read property:

{
  "protocolMap": {
    "ble": {
      "serviceID": "12345678-1234-5678-1234-56789abcdef4",
      "characteristicID": "12345678-1234-5678-1234-56789abcdef4"
    }
  }
}
Figure 34: Example read property

Response:

Example of a response:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "value": "dGVzdA==",
  "protocolMap": {
    "ble": {
      "serviceID": "12345678-1234-5678-1234-56789abcdef4",
      "characteristicID": "12345678-1234-5678-1234-56789abcdef4"
    }
  }
}
Figure 35: Example read property response

where-

  • "id" is the id of the device

  • "value" is the bytes that were read in base64 encoding

  • "protocolMap" is the protocol mapping for the property

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

4.4.7. Broadcast to a device

Method: POST /{id}/action/broadcast

Description: Broadcast a payload to a device. The broadcast is performed on the AP where the device was last seen

Parameters:

  • id: the id of the device

Request Body:

An example body of a broadcast:

{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "protocolMap": {
    "ble": {}
  },
  "cycle": "single",
  "broadcastTime": 3000,
  "broadcastInterval": 500,
  "payload": "AgEaAgoMFv9MABAHch9BsDkgeA=="
}
Figure 36: Example broadcast

where-

  • "id" is the id of the device

  • "protocolMap" is the protocol mapping for the property to identify the protocol to be used

  • "cycle" is the broadcast cycle, either "single" or "repeat"

  • "broadcastTime" is the time in milliseconds for the broadcast to run

  • "broadcastInterval" is the time in milliseconds between each broadcast

  • "payload" is the bytes to be broadcast in base64 encoding

Response:

This API responds with a HTTP 200 OK status code and an empty body when successful.

A failure will generate a standard failed response. Please refer to Figure 6 definition of failed response.

5. NIPC Extensibility

NIPC is extensible in two ways:

5.1. Protocol extensions

As described in Section 2.4 NIPC supports mapping protocol specific mapping 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.

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

Table 2: Adding Protocol mappings
Attribute Req Type Example
ble T object an object with BLE-specific properties
zigbee T object an object with Zigbee-specific properties
newProtocol T object an object with newProtocol-specific props

In the new protocol object, protocol specific properties can be added.

Protocol mappings need to be IANA registered.

5.2. API extensions

/extension

The extension APIs allow for extensibility of the APIs, either IANA registered extensions 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 Appendix C below, we have defined a few example extensions.

6. NIPC Error Handling

The error codes in the NIPC APIs can be generic or specific to the API. The generic error codes reuse the HTTP status codes defined in [RFC9110]. The error codes for the action APIs are divided into the following categories:

The specific error codes are defined in the table below:

Table 3: Error Codes
Error Code Description Category
1000 Generic catch-all error code for any API Generic
1001 Application not authorized to access the device Generic
1002 Invalid device ID or gateway doesn't recognize the ID Generic
1003 Invalid SDF URL or SDF affordance not found Generic
1004 Operation was not executed since the previous operation failed Generic
1100 Property not readable Property APIs
1101 Property not writable Property APIs
1200 Event already enabled Event APIs
1201 Event not enabled Event APIs
1202 Event not registered for any data application Event APIs
1300 Device already connected BLE-Specific
1301 No connection found for device BLE-Specific
1302 BLE connection timeout BLE-Specific
1303 BLE bonding failed BLE-Specific
1304 BLE connection failed BLE-Specific
1305 BLE service discovery failed BLE-Specific
1306 Invalid BLE service or characteristic ID BLE-Specific
1400 Zigbee connection timeout Zigbee-Specific
1401 Invalid Zigbee endpoint or cluster ID Zigbee-Specific
1500 Invalid broadcast data Broadcast APIs

The appropriate HTTP status code is returned in the response.

7. Publish/Subscribe Interface

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.

In this memo, we propose the data format to be CBOR [RFC8949].

7.1. CDDL Definition

We have a CDDL [RFC8610] definition where we define the DataSubscription struct that will be used by all the messages published to the MQTT broker.

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.

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

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

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

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
}

7.2. CBOR Examples

This section contains a few examples of the DataSubscription struct depicted in CBOR diagnostic notation.

[
  {
    "data": h'02011A020A0C16FF4C001007721F41B0392078',
    "deviceID": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "timestamp": 1727484393,
    "bleAdvertisement": {
        "macAddress": "C1:5C:00:00:00:01",
        "rssi": -25
    }
  }
]
Figure 37: Onboarded BLE Device Advertisement
[
  {
    "data": h'02011A020A0C16FF4C001007721F41B0392078',
    "timestamp": 1727484393,
    "bleAdvertisement": {
        "macAddress": "C1:5C:00:00:00:01",
        "rssi": -25
    }
  }
]
Figure 38: Non-onboarded BLE Device Advertisement
[
  {
    "data": h'434630374346303739453036',
    "deviceID": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "timestamp": 1727484393,
    "bleSubscription": {
        "serviceID": "a4e649f4-4be5-11e5-885d-feff819cdc9f",
        "characteristicID": "c4c1f6e2-4be5-11e5-885d-feff819cdc9f"
    }
  }
]
Figure 39: BLE GATT Notification
[
  {
    "deviceID": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "timestamp": 1727484393,
    "bleConnectionStatus": {
        "macAddress": "C1:5C:00:00:00:01",
        "connected": true
    }
  }
]
Figure 40: BLE Connection status event
[
  {
    "data": h'434630374346303739453036',
    "deviceID": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "timestamp": 1727484393,
    "zigbeeSubscription": {
        "endpointID": 1,
        "clusterID": 6,
        "attributeID": 12,
        "type": 1
    }
  }
]
Figure 41: Zigbee Attribute Notification

8. Examples

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

8.1. Property Read/Write

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

The sequence of operations for this are:

  • Onboard a device using the SCIM Interface (out of scope of this memo)

  • Register an SDF model for the device

    POST /registration/model
    Content-Type: application/sdf+json
    Accept: application/json
    Host: localhost
    
    { ... }
    
    HTTP/1.1 200 OK
    content-type: application/json
    x-request-id: 1f1c5a37-e21c-4edc-aeb0-65b9d747fe07
    
    {
      "sdfRef": "https://example.com/thermometer#/sdfThing/thermometer"
    }
    

    Request Body: JSON object with the SDF model, from Appendix D

  • Read a property from the BLE device

    GET /12345678-1234-5678-1234-56789abcdef4/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Fdevice_name
    Accept: application/json
    Host: localhost
    
    HTTP/1.1 200 OK
    content-type: application/json
    x-request-id: 7b821223-2ef4-4b7e-8802-efab7e1801ea
    
    {
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "value": "dGVzdA==",
      "sdfRef": "https://example.com/thermometer#/sdfThing/thermometer/sdfProperty/device_name"
    }
    
  • Write to a property on the BLE device

    PUT /12345678-1234-5678-1234-56789abcdef4/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Fdevice_name
    Content-Type: application/json
    Accept: application/json
    Host: localhost
    
    {
      "value": "dGVzdA=="
    }
    
    HTTP/1.1 200 OK
    content-type: application/json
    x-request-id: 7b821223-2ef4-4b7e-8802-efab7e1801ea
    
    {
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "value": "dGVzdA==",
      "sdfRef": "https://example.com/thermometer#/sdfThing/thermometer/sdfProperty/device_name"
    }
    

8.2. Enabling an Event

In this example, we will onboard a device, and setup an advertisement subscription event for that device.

The sequence of operations for this are:

  • Onboard a device and endpoint app using the SCIM Interface (out of scope of this memo)

  • Register an SDF model for the device

    POST /registration/model
    Content-Type: application/sdf+json
    Accept: application/json
    Host: localhost
    
    { ... }
    
    HTTP/1.1 200 OK
    content-type: application/json
    x-request-id: 1f1c5a37-e21c-4edc-aeb0-65b9d747fe07
    
    {
      "sdfRef": "https://example.com/thermometer#/sdfThing/thermometer"
    }
    

    Request Body: JSON object with the SDF model, from Appendix D

  • Register the data app with the event

    POST /registration/data-app/23456789-1234-5678-1234-56789abcdef4
    Content-Type: application/json
    Accept: application/json
    Host: localhost
    
    {
      "events": [
        "https://example.com/thermometer#/sdfThing/thermometer/sdfEvent/isPresent"
      ],
      "mqttClient": {}
    }
    
    HTTP/1.1 200 OK
    content-type: application/json
    x-request-id: 3a7d9ad6-562e-44ac-b119-cfe1d0e7b74e
    
    {
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "events": [
        "https://example.com/thermometer#/sdfThing/thermometer/sdfEvent/isPresent"
      ]
    }
    
  • Enable the advertisement event

    POST /12345678-1234-5678-1234-56789abcdef4/event/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfEvent%2FisPresent
    Content-Type: application/json
    Accept: application/json
    Host: localhost
    Content-Length: 0
    
    HTTP/1.1 200 OK
    content-type: application/json
    x-request-id: 1f1c5a37-e21c-4edc-aeb0-65b9d747fe07
    
    {
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "event": "https://example.com/thermometer#/sdfThing/thermometer/sdfEvent/isPresent"
    }
    

8.3. Property read/write with explicit connection

In this example, we will connect to a device explicitly and read and write from a property. The sequence of operations for this are:

  • Onboard a device using the SCIM Interface (out of scope of this memo)

  • Connect to the device

    POST /12345678-1234-5678-1234-56789abcdef4/action/connection
    Content-Type: application/json
    Accept: application/json
    Host: localhost
    
    {
      "retries": 3,
      "retryMultipleAPs": true,
      "protocolMap": {
        "ble": {
          "services": [
            {
              "serviceID": "1800"
            },
            {
              "serviceID": "1801"
            }
          ],
          "cached": false,
          "cacheIdlePurge": 3600,
          "autoUpdate": true,
          "bonding": "default"
        }
      }
    }
    
    HTTP/1.1 200 OK
    content-type: application/json
    x-request-id: 7b821223-2ef4-4b7e-8802-efab7e1801ea
    
    {
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "protocolMap": {
        "ble": [
          {
            "serviceID": "1800",
            "characteristics": [
              {
                "characteristicID": "2A00",
                "flags": [
                  "read",
                  "write"
                ],
                "descriptors": [
                  {
                    "descriptorID": "2901"
                  }
                ]
              }
            ]
          }
        ]
      }
    }
    
  • Read a property from the BLE device

    POST /12345678-1234-5678-1234-56789abcdef4/action/property/read
    Content-Type: application/json
    Accept: application/json
    Host: localhost
    
    {
      "protocolMap": {
        "ble": {
          "serviceID": "1800",
          "characteristicID": "2A00"
        }
      }
    }
    
    HTTP/1.1 200 OK
    content-type: application/json
    x-request-id: 7b821223-2ef4-4b7e-8802-efab7e1801ea
    
    {
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "value": "dGVzdA==",
      "protocolMap": {
        "ble": {
          "serviceID": "1800",
          "characteristicID": "2A00"
        }
      }
    }
    
  • Write to a property on the BLE device

    POST /12345678-1234-5678-1234-56789abcdef4/action/property/write
    Content-Type: application/json
    Accept: application/json
    Host: localhost
    
    {
      "value": "dGVzdA==",
      "protocolMap": {
        "ble": {
          "serviceID": "1800",
          "characteristicID": "2A00"
        }
      }
    }
    
    HTTP/1.1 200 OK
    content-type: application/json
    x-request-id: 7b821223-2ef4-4b7e-8802-efab7e1801ea
    
    {
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "value": "dGVzdA==",
      "protocolMap": {
        "ble": {
          "serviceID": "1800",
          "characteristicID": "2A00"
        }
      }
    }
    
  • Disconnect from the device

    DELETE /12345678-1234-5678-1234-56789abcdef4/action/connection
    Accept: application/json
    Host: localhost
    
    HTTP/1.1 200 OK
    content-type: application/json
    x-request-id: 7b821223-2ef4-4b7e-8802-efab7e1801ea
    
    {
      "id": "12345678-1234-5678-1234-56789abcdef4"
    }
    

9. Security Considerations

9.1. API authorization

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:

  1. Onboarding: Authorize an onboarding application against a SCIM server co-located with the gateway.

  2. Control: Authorize applications that may control devices.

  3. Data: Authorize applications that may receive telemetry.
    It is possible to further refine roles down to an API basis.

10. IANA Considerations

This section provides guidance to the Internet Assigned Numbers Authority (IANA) regarding registration of values related to NIPC, in accordance with [RFC8126].

11. References

11.1. Normative References

[I-D.ietf-asdf-sdf]
Koster, M., Bormann, C., and A. Keränen, "Semantic Definition Format (SDF) for Data and Interactions of Things", Work in Progress, Internet-Draft, draft-ietf-asdf-sdf-23, , <https://datatracker.ietf.org/doc/html/draft-ietf-asdf-sdf-23>.
[I-D.ietf-scim-device-model]
Shahzad, M., Iqbal, H., and E. Lear, "Device Schema Extensions to the SCIM model", Work in Progress, Internet-Draft, draft-ietf-scim-device-model-11, , <https://datatracker.ietf.org/doc/html/draft-ietf-scim-device-model-11>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC7159]
Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", RFC 7159, DOI 10.17487/RFC7159, , <https://www.rfc-editor.org/info/rfc7159>.
[RFC7644]
Hunt, P., Ed., Grizzle, K., Ansari, M., Wahlstroem, E., and C. Mortimore, "System for Cross-domain Identity Management: Protocol", RFC 7644, DOI 10.17487/RFC7644, , <https://www.rfc-editor.org/info/rfc7644>.
[RFC8126]
Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, , <https://www.rfc-editor.org/info/rfc8126>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8610]
Birkholz, H., Vigano, C., and C. Bormann, "Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, , <https://www.rfc-editor.org/info/rfc8610>.
[RFC8615]
Nottingham, M., "Well-Known Uniform Resource Identifiers (URIs)", RFC 8615, DOI 10.17487/RFC8615, , <https://www.rfc-editor.org/info/rfc8615>.
[RFC8949]
Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, , <https://www.rfc-editor.org/info/rfc8949>.
[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/info/rfc9110>.
[RFC9114]
Bishop, M., Ed., "HTTP/3", RFC 9114, DOI 10.17487/RFC9114, , <https://www.rfc-editor.org/info/rfc9114>.

11.2. Informative References

[BLE53]
Bluetooth SIG, "Bluetooth Core Specification, Version 5.3", .
[Gatt-REST-API]
Bluetooth SIG, "A RESTful API used to access data in devices using the functionality defined in the Bluetooth GATT profile", , <https://www.bluetooth.com/bluetooth-resources/gatt-rest-api/>.
[Zigbee22]
Connectivity Standards Alliance, "zigbee Specification, Version 22 1.0", .

Appendix A. OpenAPI definition

The following non-normative model is provide for convenience of the implementor.

<CODE BEGINS> file "openapi.yml"

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: [email protected]
  license:
    name: TBD
    url: TBD
  version: 0.5.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-04"
    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 action APIs with embedded protocol mapping
    description: |-
      APIs that perform actions on devices, but do not use registered properties, events or actions. These APIs have embedded protocol mappings
  - name: NIPC registration APIs
    description: |-
      APIs that register sdf models or data applications

paths:
### NIPC Property APIs
  /{id}/property/{property}:
    put:
      tags:
        - NIPC property APIs
      summary: Write a value to a property on a device
      description: |-
        Write a value to a property 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. Id cannot be a group-id.
      operationId: UpdateProperty
      parameters:
      - name: id
        in: path
        description: device id that need to be filtered, group id is not allowed
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: property
        in: path
        description: property that needs to be filtered
        required: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/thermostat/sdfProperty/temperature"
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Value'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/PropertyValue'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/PropertyErrorCodes'

    get:
      tags:
        - NIPC property APIs
      summary: Read a value from a property on a device
      description: |-
        Read a value to a property 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. Id cannot be a group-id.
      operationId: GetProperty
      parameters:
      - name: id
        in: path
        description: device id that need to be filtered, group id is not allowed
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: property
        in: path
        description: property that needs to be filtered
        required: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/thermostat/sdfProperty/temperature"
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/PropertyValue'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/PropertyErrorCodes'

  /{id}/property:
    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: device id that need to be filtered, 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/PropertyValueArray'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/PropertyValueResponseArray'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/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: device id that need to be filtered, group id is not allowed
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: property
        in: query
        description: properties that needs to be filtered, multiple values are comma-separated
        required: true
        explode: false
        schema:
          type: array
          items:
            type: string
            example: "https://example.com/heartrate#/sdfObject/thermostat/sdfProperty/temperature"
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/PropertyValueResponseArray'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/PropertyErrorCodes'

 ### NIPC Event APIs
  /{id}/event/{event}:
    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: event
        in: path
        description: event that needs to be enabled
        required: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/healthsensor/sdfEvent/fallDetected"
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/Event'

        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/EventErrorCodes'

    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: event
        in: path
        description: event that needs to be disabled
        required: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/healthsensor/sdfEvent/fallDetected"
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/Event'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/EventErrorCodes'

    get:
      tags:
        - NIPC event APIs
      summary: Get status of an event on a specific device
      description: |-
        Get status of an event on a specific device or a groupd of devices. Success is event is active, failure if event not active.
      operationId: GetEvent
      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: event
        in: path
        description: event that needs to be filtered
        required: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/healthsensor/sdfEvent/fallDetected"
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/Event'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/EventErrorCodes'

  /{id}/event:
    get:
      tags:
        - NIPC event APIs
      summary: Get status of events on a device or group of devices
      description: |-
        Get status of an event or multiple events on a specific device or group of devices.
      operationId: GetEvents
      parameters:
      - name: id
        in: path
        description: device or group id that needs to be filtered
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: event
        in: query
        description: events that needs to be filtered, multiple values are comma-separated
        explode: false
        required: true
        schema:
          type: array
          items:
            type: string
            example: "https://example.com/heartrate#/sdfObject/healthsensor/sdfEvent/fallDetected"
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventStatusResponseArray'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/EventErrorCodes'

### NIPC action APIs
  /{id}/action/{action}:
    put:
      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. Id cannot be a group-id.
      operationId: ActionProperty
      parameters:
      - name: id
        in: path
        description: device id that need to be filtered, group id is not allowed
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: action
        in: path
        description: action that needs to be performed
        required: true
        schema:
          type: string
          example: "https://example.com/heartrate#/sdfObject/healthsensor/sdfAction/start"
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Value'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/ActionValue'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/PropertyErrorCodes'

  /{id}/action/broadcast:
    post:
      tags:
        - NIPC action APIs with embedded protocol mapping
      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: device id that need to be filtered, group id not allowed
          required: true
          schema:
            type: string
            format: uuid
            example: 12345678-1234-5678-1234-56789abcdef4
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Broadcast'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/BroadcastErrorCodes'

  /{id}/action/connection:
    post:
      tags:
        - NIPC action APIs with embedded protocol mapping
      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: device id that need to be filtered, group id not allowed
          required: true
          schema:
            type: string
            format: uuid
            example: 12345678-1234-5678-1234-56789abcdef4
      requestBody:
        content:
          application/json:
            schema:
              anyOf:
                - $ref: '#/components/schemas/Connection'
                - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-ServiceList'
        required: false
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-ServiceMap'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/ConnectionErrorCodes'
                  - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-ErrorCodes'

    put:
      tags:
        - NIPC action APIs with embedded protocol mapping
      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: device id that need to be filtered, group id 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/schemas/ProtocolMap-ServiceList'
        required: false
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-ServiceMap'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/ConnectionErrorCodes'
                  - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-ErrorCodes'

    delete:
      tags:
        - NIPC action APIs with embedded protocol mapping
      summary: Disconnect a device
      description: |-
        Disconnect a device.
      operationId: ActionDeleteConnection
      parameters:
        - name: id
          in: path
          description: device id that need to be filtered, group id not allowed
          required: true
          schema:
            type: string
            format: uuid
            example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/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: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/ConnectionErrorCodes'

    get:
      tags:
        - NIPC action APIs with embedded protocol mapping
      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: device id that need to be filtered, group id not allowed
          required: true
          schema:
            type: string
            format: uuid
            example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-ServiceMap'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/ConnectionErrorCodes'
                  - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-ErrorCodes'

  /{id}/action/property/write:
    post:
      tags:
        - NIPC action APIs with embedded protocol mapping
      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: device id that need to be filtered, group id not allowed
          required: true
          schema:
            type: string
            format: uuid
            example: 12345678-1234-5678-1234-56789abcdef4
      requestBody:
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/Value'
                - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-Property'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/Value'
                  - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-Property'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/PropertyErrorCodes'

  /{id}/action/property/read:
    post:
      tags:
        - NIPC action APIs with embedded protocol mapping
      summary: Write 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: device id that need to be filtered, group id 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/schemas/ProtocolMap-Property'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Id'
                  - $ref: '#/components/schemas/Value'
                  - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-Property'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'
                  - $ref: '#/components/schemas/PropertyErrorCodes'


### Registrations
  /registration/model:
    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
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SdfReference'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - NIPC registration APIs
      summary: Get all registered sdfRefs
      description: |-
        Get all registered sdfRefs for a device or group
      operationId: getSdfRefs
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                type: array
                items:
                  allOf:
                    - $ref: '#/components/schemas/SdfReference'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'


  /registration/model/{sdfRef}:
    put:
      tags:
        - NIPC registration APIs
      summary: Update an SDF model
      description: |-
        Update an SDF model, including Properties, Events and actions
      operationId: updateSdf
      parameters:
        - name: sdfRef
          in: path
          description: sdfRef can be a reference to an sdfThing or sdfObject
          required: true
          schema:
            type: string
            example: "https://example.com/heartrate#/sdfObject/healthsensor"
      requestBody:
        content:
          application/sdf+json:
            schema:
              $ref: '#/components/schemas/SdfModel'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SdfReference'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/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: sdfRef
          in: path
          description: sdfObject name
          required: true
          schema:
            type: string
            example: "https://example.com/heartrate#/sdfObject/healthsensor"
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SdfReference'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - NIPC registration APIs
      summary: get a registered sdfObject
      description: |-
        Get an sdfObject, including Properties, Events and actions
      operationId: getSdfObject
      parameters:
        - name: sdfRef
          in: path
          description: sdfObject name
          required: true
          schema:
            type: string
            example: "https://example.com/heartrate#/sdfObject/healthsensor"
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SdfModel'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'

  /registration/data-app/{data-app}:
    post:
      tags:
        - NIPC registration APIs
      summary: Register a dataApp
      description: |-
        Register a dataApp that is able to receive device data.
      operationId: registerDataApp
      parameters:
        - name: data-app
          in: path
          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/json:
            schema:
              $ref: '#/components/schemas/DataApp'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/DataApp'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/FailureResponse'

    put:
      tags:
        - NIPC registration APIs
      summary: Update registration of a dataApp
      description: |-
        Update registration of a dataApp that is able to receive device data.
      operationId: UpdateDataApp
      parameters:
        - name: data-app
          in: path
          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/json:
            schema:
              $ref: '#/components/schemas/DataApp'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/DataApp'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/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: data-app
          in: path
          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
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/DataApp'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/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: data-app
          in: path
          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
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/DataApp'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/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/thermostat/sdfProperty/temperature"

    Action:
      required:
        - action
      type: object
      properties:
        action:
          type: string
          example: "https://example.com/heartrate#/sdfObject/thermostat/sdfAction/start"

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

    ActionValue:
      allOf:
        - $ref: '#/components/schemas/Action'
        - $ref: '#/components/schemas/Value'

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

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

## A Connection
    Connection:
      type: object
      properties:
        retries:
          type: integer
          format: int32
          example: 3
        retryMultipleAPs:
          type: boolean
          example: true

## A broadcast
    Broadcast:
      allOf:
        - $ref: '#/components/schemas/Id'
        - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-Broadcast'
      required:
        - cycle
      type: object
      properties:
        cycle:
          type: string
          example: single
          enum:
            - single
            - repeat
        # broadcast time in ms
        broadcastTime:
          type: integer
          example: 3000
        # interval between broadcasts in ms
        broadcastInterval:
          type: integer
          example: 500
        payload:
          type: string
          format: byte
          example: AgEaAgoMFv9MABAHch9BsDkgeA==

 ## 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: object

    DataAppMqttBroker:
      type: object
      properties:
        mqttBroker:
          type: object
          properties:
            URI:
              type: string
              example: mqtt.broker.com:8883
            username:
              type: string
              example: user1
            password:
              type: string
              example: password1
            brokerCACert:
              type: string

    DataAppWebhook:
      type: object
      properties:
        webhook:
          type: object
          properties:
            URI:
              type: string
              example: webhook.com:443
            apiKey:
              type: string
              example: fjelk-3dl33f-2wdsd
            serverCACert:
              type: string

    DataAppWebsocket:
      type: object
      properties:
        websocket:
          type: object
          properties:
            URI:
              type: string
              example: websocket.com:443
            apiKey:
              type: string
              example: fjelk-3dl33f-2wdsd
            serverCACert:
              type: string

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

    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:
                    protocolMap:
                      ble:
                        type: advertisement
              sdfObject:
                healthsensor:
                  sdfProperty:
                    heartrate:
                      protocolMap:
                        ble:
                          serviceID: 12345678-1234-5678-1234-56789abcdef4
                          characteristicID: 12345678-1234-5678-1234-56789abcdef4
                  sdfEvent:
                    fallDetected:
                      sdfOutputData:
                        protocolMap:
                          ble:
                            serviceID: 12345678-1234-5678-1234-56789abcdef4
                            characteristicID: 12345678-1234-5678-1234-56789abcdef4
                  sdfAction:
                    start:
                      protocolMap:
                        ble:
                          serviceID: 12345678-1234-5678-1234-56789abcdef4
                          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:
                  protocolMap:
                    ble:
                      serviceID: 12345678-1234-5678-1234-56789abcdef4
                      characteristicID: 12345678-1234-5678-1234-56789abcdef4
              sdfEvent:
                fallDetected:
                  sdfOutputData:
                    protocolMap:
                      ble:
                        serviceID: 12345678-1234-5678-1234-56789abcdef4
                        characteristicID: 12345678-1234-5678-1234-56789abcdef4
              sdfAction:
                start:
                  protocolMap:
                    ble:
                      serviceID: 12345678-1234-5678-1234-56789abcdef4
                      characteristicID: 12345678-1234-5678-1234-56789abcdef4

    SdfProperty:
      type: object
      description: Sample SDF property
      properties:
        sdfProperty:
          additionalProperties:
            allOf:
              - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-Property'
          example:
            heartrate:
              protocolMap:
                ble:
                  serviceID: 12345678-1234-5678-1234-56789abcdef4
                  characteristicID: 12345678-1234-5678-1234-56789abcdef4

    SdfEvent:
      type: object
      description: Sample SDF property
      properties:
        sdfEvent:
          additionalProperties: #example, this will be the registered event
            type: object
            properties:
              sdfOutputData:
                allOf:
                  - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-Event'
          example:
            fallDetected:
              sdfOutputData:
                protocolMap:
                  ble:
                    serviceID: 12345678-1234-5678-1234-56789abcdef4
                    characteristicID: 12345678-1234-5678-1234-56789abcdef4

    SdfAction:
      type: object
      description: Sample SDF property
      properties:
        sdfAction:
          additionalProperties:
            allOf:
              - $ref: './protocolmaps/ProtocolMap.yaml#/components/schemas/ProtocolMap-Property'
          example:
            start:
              protocolMap:
                ble:
                  serviceID: 12345678-1234-5678-1234-56789abcdef4
                  characteristicID: 12345678-1234-5678-1234-56789abcdef4

# responses

## Error 500 application Failure response
    FailureResponse:
      type: object
      properties:
        reason:
          type: string
          example: Bad request
        errorCode:
          type: integer
          format: int32
          enum:
            - 1000 # Generic catch-all error code for any API
            - 1001 # Application not authorized to access the device
            - 1002 # Invalid device ID or gateway doesn't recognize the ID
            - 1003 # Invalid SDF URL or SDF affordance not found
            - 1004 # Operation was not executed since the previous operation failed

    PropertyErrorCodes:
      type: integer
      format: int32
      enum:
        - 1100 # Property not readable
        - 1101 # Property not writable

    EventErrorCodes:
      type: integer
      format: int32
      enum:
        - 1200 # Event already enabled
        - 1201 # Event not enabled
        - 1202 # Event not registered for any data application

    ConnectionErrorCodes:
      type: integer
      format: int32
      enum:
        - 1300 # Device already connected
        - 1301 # No connection found for device
        - 1302 # BLE connection timeout
        - 1303 # BLE bonding failed
        - 1304 # BLE connection failed
        - 1305 # BLE service discovery failed
        - 1306 # Invalid BLE service or characteristic ID
        - 1400 # Zigbee connection timeout
        - 1401 # Invalid Zigbee endpoint or cluster ID

    BroadcastErrorCodes:
      type: integer
      format: int32
      enum:
        - 1500 # Invalid broadcast data

## Property operations responses

    PropertyValueResponseArrayItem:
      oneOf:
        - $ref: '#/components/schemas/PropertyValue'
        - $ref: '#/components/schemas/FailureResponse'

    PropertyValueResponseArray:
      type: object
      properties:
        properties:
          type: array
          items:
              $ref: '#/components/schemas/PropertyValueResponseArrayItem'

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

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


<CODE ENDS>
Figure 42

Appendix B. Protocol mapping

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.

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

B.1. Protocol mapping OpenAPI model

<CODE BEGINS> file "ProtocolMap.yaml"

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: [email protected]
  license:
    name: TBD
    url: TBD
  version: 0.5.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/

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

## Protocol Map for Service Discovery result
    ProtocolMap-ServiceMap:
      type: object
      properties:
        protocolMap:
          oneOf:
            - $ref: './ProtocolMap-BLE.yaml#/components/schemas/ProtocolMap-BLE-ServiceMap'
            - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/ProtocolMap-Zigbee-ServiceMap'

## Protocol Map for Error Codes
    ProtocolMap-ErrorCodes:
      type: object
      properties:
        protocolMap:
          oneOf:
            - $ref: './ProtocolMap-BLE.yaml#/components/schemas/ProtocolMap-BLE-ErrorCodes'
            - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/ProtocolMap-Zigbee-ErrorCodes'

## Protocol Map for Broadcasts
    ProtocolMap-Broadcast:
      type: object
      properties:
        protocolMap:
          oneOf:
            - $ref: './ProtocolMap-BLE.yaml#/components/schemas/ProtocolMap-BLE-Broadcast'
            - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/ProtocolMap-Zigbee-Broadcast'

## Protocol Map for a property
    ProtocolMap-Property:
      type: object
      properties:
        protocolMap:
          oneOf:
            - $ref: './ProtocolMap-BLE.yaml#/components/schemas/ProtocolMap-BLE-Propmap'
            - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/ProtocolMap-Zigbee-Propmap'

## Protocol Map for an event
    ProtocolMap-Event:
      type: object
      properties:
        protocolMap:
          oneOf:
            - $ref: './ProtocolMap-BLE.yaml#/components/schemas/ProtocolMap-BLE-Event'
            - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/ProtocolMap-Zigbee-Event'


<CODE ENDS>
Figure 43

B.2. Protocol map for BLE

<CODE BEGINS> file "ProtocolMap-BLE.yaml"

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: [email protected]
  license:
    name: TBD
    url: TBD
  version: 0.5.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-Characteristic'

    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:
        errorCode:
          type: integer
          format: int32
          enum:
            - 1011 # BLE bonding failed
            - 1013 # BLE service discovery failed

<CODE ENDS>
Figure 44

B.3. Protocol map for Zigbee

<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: [email protected]
  license:
    name: TBD
    url: TBD
  version: 0.5.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:
        errorCode:
          type: integer
          format: int32
          enum:
            - 1021 # Zigbee join failed

<CODE ENDS>
Figure 45

Appendix C. NIPC API extensions

The following OpenAPI models define a few example extensions to the NIPC API.

C.1. NIPC API write binary blob extension

<CODE BEGINS> file "Extension-Blob.yaml"

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: [email protected]
  license:
    name: TBD
    url: TBD
  version: 0.5.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-04"
    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
  /{id}/extension/property/{property}/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: device id that need to be filtered, group id is not allowed
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: property
        in: path
        description: property that needs to be filtered
        required: true
        schema:
          type: string
          example: "bin_blob"
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Extension-Blob'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/Id'
                  - $ref: '../NIPC.yaml#/components/schemas/Property'
        '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/FailureResponse'
                  - $ref: '../NIPC.yaml#/components/schemas/PropertyErrorCodes'

components:
  schemas:
# Extensions
## A binary blob Extension
    Extension-Blob:
      required:
        - blob
      type: object
      properties:
        blob:
          type: string
          format: byte
        chunksize:
          type: integer

<CODE ENDS>

C.2. NIPC API bulk operations extension

<CODE BEGINS> file "Extension-Bulk.yaml"

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: [email protected]
  license:
    name: TBD
    url: TBD
  version: 0.5.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-04"
    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
  /{id}/extension/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: device id that need to be filtered, 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:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Extension-BulkResponse'
              examples:
                bulkResponse:
                  $ref: '#/components/examples/bulkResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '../NIPC.yaml#/components/schemas/FailureResponse'
                  - $ref: '../NIPC.yaml#/components/schemas/PropertyErrorCodes'
              examples:
                errorBulkResponse:
                  $ref: '#/components/examples/errorBulkResponse'
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '../NIPC.yaml#/components/schemas/FailureResponse'
                  - $ref: '../NIPC.yaml#/components/schemas/PropertyErrorCodes'

components:
  schemas:
# Extensions
## Bulk schema Extension
    Extension-Bulk:
      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:
                - /{id}/property/{property}
                - /{id}/action/{action}
                - /{id}/extension/property/{property}/read/conditional
              example: /12345678-1234-5678-1234-56789abcdef4/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            data:
              type: object
              oneOf:
                - $ref: '../NIPC.yaml#/components/schemas/Value'
                - $ref: './Extension-ReadConditional.yaml#/components/schemas/Extension-ConditionalRead'


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

## Return for an operation
    Extension-OperationResponse:
      allOf:
        - type: object
          properties:
            method:
              type: string
              enum:
               - POST
               - PUT
               - GET
            path:
              type: string
              enum:
                - /{id}/property/{property}
                - /{id}/action/{action}
                - /{id}/extension/property/{property}/read/conditional'
              example: /12345678-1234-5678-1234-56789abcdef4/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              anyOf:
                - allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/Id'
                  - $ref: '../NIPC.yaml#/components/schemas/PropertyValue'
                - allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/Id'
                  - $ref: '../NIPC.yaml#/components/schemas/ActionValue'
                - $ref: '../NIPC.yaml#/components/schemas/FailureResponse'
                - $ref: '../NIPC.yaml#/components/schemas/PropertyErrorCodes'

  examples:
    bulkRequest:
      summary: Bulk request example
      value:
        operations:
          - method: GET
            path: >-
              /12345678-1234-5678-1234-56789abcdef4/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
          - method: PUT
            path: >-
              /12345678-1234-5678-1234-56789abcdef4/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            data:
              value: dGVzdA==
          - method: POST
            path: >-
              /12345678-1234-5678-1234-56789abcdef4/extension/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature/read/conditional
            data:
              value: dGVzdA==
              maxRepeat: 5
              frequency: 1
    bulkResponse:
      summary: Bulk response example
      value:
        operations:
          - method: GET
            path: >-
              /12345678-1234-5678-1234-56789abcdef4/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              id: 12345678-1234-5678-1234-56789abcdef4
              property: >-
                https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
              value: dGVzdA==
          - method: PUT
            path: >-
              /12345678-1234-5678-1234-56789abcdef4/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              id: 12345678-1234-5678-1234-56789abcdef4
              property: >-
                https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
              value: dGVzdA==
          - method: POST
            path: >-
              /12345678-1234-5678-1234-56789abcdef4/extension/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature/read/conditional
            response:
              id: 12345678-1234-5678-1234-56789abcdef4
              property: >-
                https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
              value: dGVzdA==
    errorBulkResponse:
      summary: Error Bulk response example
      value:
        operations:
          - method: GET
            path: >-
              /12345678-1234-5678-1234-56789abcdef4/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              reason: Property not readable
              errorCode: 1100
          - method: PUT
            path: >-
              /12345678-1234-5678-1234-56789abcdef4/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
            response:
              reason: >-
                Operation was not executed since the previous
                operation failed
              errorCode: 1004
          - method: POST
            path: >-
              /12345678-1234-5678-1234-56789abcdef4/extension/property/https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature/read/conditional
            response:
              reason: >-
                Operation was not executed since the previous
                operation failed
              errorCode: 1004

<CODE ENDS>

C.3. NIPC API write file extension

<CODE BEGINS> file "Extension-File.yaml"

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: [email protected]
  license:
    name: TBD
    url: TBD
  version: 0.5.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-04"
    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
  /{id}/extension/property/{property}/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: device id that need to be filtered, group id is not allowed
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: property
        in: path
        description: property that needs to be filtered
        required: true
        schema:
          type: string
          example: "firmware"
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Extension-File'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/Id'
                  - $ref: '../NIPC.yaml#/components/schemas/Property'
        '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/FailureResponse'
                  - $ref: '../NIPC.yaml#/components/schemas/PropertyErrorCodes'

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>

C.4. NIPC API firmware update extension

<CODE BEGINS> file "Extension-Firmware.yaml"

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: [email protected]
  license:
    name: TBD
    url: TBD
  version: 0.5.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-04"
    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
  /{id}/extension/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: device id that need to be filtered, 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/Extension-File'
                - $ref: '#/components/schemas/Extension-Firmware'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/Id'
                  - $ref: '#/components/schemas/Extension-UpgradeStatus'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '../NIPC.yaml#/components/schemas/FailureResponse'

    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: device id that need to be filtered, group id is not allowed
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/Id'
                  - $ref: '#/components/schemas/Extension-UpgradeStatus'
        '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/FailureResponse'

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

## Firmware upgrade status extension
    Extension-UpgradeStatus:
      type: object
      properties:
        upgradeStatus:
          type: string
          enum:
            - started
            - completed
            - in progress
            - rolled-back
            - failed





<CODE ENDS>

C.5. NIPC API conditional read extension

<CODE BEGINS> file "Extension-ReadConditional.yaml"

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: [email protected]
  license:
    name: TBD
    url: TBD
  version: 0.5.0
externalDocs:
  description: NIPC IETF draft
  url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
servers:
  - url: "{gw_host}/nipc/draft-04"
    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
  /{id}/extension/property/{property}/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: device id that need to be filtered, group id is not allowed
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: property
        in: path
        description: property that needs to be filtered
        required: true
        schema:
          type: string
          example: "#/sdfObject/thermostat/sdfProperty/temperature"
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Extension-ConditionalRead'
        required: true
      responses:
        '200':
          description: Success
          headers:
            X-Request-ID:
              schema:
                type: integer
              description: Unique Request ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '../NIPC.yaml#/components/schemas/Id'
                  - $ref: '../NIPC.yaml#/components/schemas/PropertyValue'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '../NIPC.yaml#/components/schemas/FailureResponse'
                  - $ref: '../NIPC.yaml#/components/schemas/PropertyErrorCodes'

components:
  schemas:
# Extensions
    Extension-ConditionalRead:
      allOf:
        - $ref: '../NIPC.yaml#/components/schemas/Value'
        - type: object
          properties:
            maxRepeat:
              description: |-
                maximum time the conditional read should repeat
                (default 5, max 60)
              type: integer
              example: 5
            frequency:
              description: |-
                time between reads in seconds (default 1, max 60)
              type: integer
              example: 1

<CODE ENDS>

Appendix D. Example SDF model with protocol mappings for BLE

<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,
                            "protocolMap": {
                                "ble": {
                                    "serviceID": "1809",
                                    "characteristicID": "2A1D"
                                }
                            }
                        },
                        "measurement_interval": {
                            "description": "Measurement Interval",
                            "observable": false,
                            "writable": false,
                            "readable": true,
                            "protocolMap": {
                                "ble": {
                                    "serviceID": "1809",
                                    "characteristicID": "2A21"
                                }
                            }
                        }
                    },
                    "sdfEvent": {
                        "temperature_measurement": {
                            "description": "Temperature Measurement",
                            "sdfOutputData": {
                                "protocolMap": {
                                    "ble": {
                                        "type": "gatt",
                                        "serviceID": "1809",
                                        "characteristicID": "2A1C"
                                    }
                                }
                            }
                        },
                        "intermediate_temperature": {
                            "description": "Intermediate Temperature",
                            "sdfOutputData": {
                                "protocolMap": {
                                    "ble": {
                                        "type": "gatt",
                                        "serviceID": "1809",
                                        "characteristicID": "2A1E"
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "description": "Generic Access, Device Information",
            "sdfProperty": {
                "device_name": {
                    "description": "Device Name",
                    "observable": false,
                    "writable": true,
                    "readable": true,
                    "protocolMap": {
                        "ble": {
                            "serviceID": "1800",
                            "characteristicID": "2A00"
                        }
                    }
                },
                "appearance": {
                    "description": "Appearance",
                    "observable": false,
                    "writable": false,
                    "readable": true,
                    "protocolMap": {
                        "ble": {
                            "serviceID": "1800",
                            "characteristicID": "2A01"
                        }
                    }
                },
                "manufacturer_name_string": {
                    "description": "Manufacturer Name String",
                    "observable": false,
                    "writable": false,
                    "readable": true,
                    "protocolMap": {
                        "ble": {
                            "serviceID": "180A",
                            "characteristicID": "2A29"
                        }
                    }
                },
                "model_number_string": {
                    "description": "Model Number String",
                    "observable": false,
                    "writable": false,
                    "readable": true,
                    "protocolMap": {
                        "ble": {
                            "serviceID": "180A",
                            "characteristicID": "2A24"
                        }
                    }
                },
                "hardware_revision_string": {
                    "description": "Hardware Revision String",
                    "observable": false,
                    "writable": false,
                    "readable": true,
                    "protocolMap": {
                        "ble": {
                            "serviceID": "180A",
                            "characteristicID": "2A27"
                        }
                    }
                },
                "firmware_revision_string": {
                    "description": "Firmware Revision String",
                    "observable": false,
                    "writable": false,
                    "readable": true,
                    "protocolMap": {
                        "ble": {
                            "serviceID": "180A",
                            "characteristicID": "2A26"
                        }
                    }
                },
                "system_id": {
                    "description": "System ID",
                    "observable": false,
                    "writable": false,
                    "readable": true,
                    "protocolMap": {
                        "ble": {
                            "serviceID": "180A",
                            "characteristicID": "2A23"
                        }
                    }
                }
            },
            "sdfEvent": {
                "isPresent": {
                    "description": "BLE advertisements",
                    "sdfOutputData": {
                        "protocolMap": {
                            "ble": {
                                "type": "advertisements"
                            }
                        }
                    }
                },
                "isConnected": {
                    "description": "BLE connection events",
                    "sdfOutputData": {
                        "protocolMap": {
                            "ble": {
                                "type": "connection_events"
                            }
                        }
                    }
                }
            }
        }
    }
}

<CODE ENDS>
Figure 46: Example SDF model with protocol mappings for BLE

Authors' Addresses

Bart Brinckman
Cisco Systems
Brussels
Belgium
Rohit Mohan
Cisco Systems
170 West Tasman Drive
San Jose, 95134
United States of America
Braeden Sanford
Philips
Cambridge,
United States of America