<?xml version="1.0"?>
<!DOCTYPE rfc SYSTEM 'rfc2629.dtd'[
<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC2578 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2578.xml">
<!ENTITY RFC3410 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3410.xml">
<!ENTITY RFC3411 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3411.xml">
<!ENTITY RFC3414 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3414.xml">
<!ENTITY RFC3416 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3416.xml">
<!ENTITY RFC3418 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3418.xml">
<!ENTITY RFC4293 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4293.xml">
<!ENTITY RFC4648 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4648.xml">
<!ENTITY RFC4944 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4944.xml">
<!ENTITY RFC5277 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5277.xml">
<!ENTITY RFC6020 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6020.xml">
<!ENTITY RFC6241 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6241.xml">
<!ENTITY RFC6347 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6347.xml">
<!ENTITY RFC6643 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6643.xml">
<!ENTITY RFC6650 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6650.xml">
<!ENTITY RFC6775 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6775.xml">
<!ENTITY RFC6690 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6690.xml">
<!ENTITY RFC7049 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7049.xml">
<!ENTITY RFC7159 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7159.xml">
<!ENTITY RFC7223 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7223.xml">
<!ENTITY RFC7228 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7228.xml">
<!ENTITY RFC7252 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7252.xml">
<!ENTITY RFC7317 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7317.xml">
<!ENTITY I-D.ietf-core-block SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-core-block.xml">
<!ENTITY I-D.ietf-core-interfaces SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-core-interfaces.xml">
<!ENTITY I-D.ietf-core-observe SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-core-observe.xml">
<!ENTITY I-D.becker-core-coap-sms-gprs SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.becker-core-coap-sms-gprs.xml">
<!ENTITY I-D.ersue-constrained-mgmt SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ersue-constrained-mgmt.xml">
<!ENTITY I-D.ietf-netmod-yang-json SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-netmod-yang-json.xml">
<!ENTITY I-D.ietf-netconf-restconf SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-netconf-restconf.xml">
<!ENTITY I-D.ietf-netconf-yang-patch SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-netconf-yang-patch.xml">
<!ENTITY I-D.ietf-lwig-coap SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-lwig-coap.xml">
<!ENTITY I-D.vanderstok-core-patch SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.vanderstok-core-patch.xml">
]>


<?rfc toc="yes"?>
<?rfc symrefs="yes" ?>

<rfc category="std" ipr="trust200902" docName="draft-vanderstok-core-comi-07">
  <front>
    <title abbrev="CoMI">CoAP Management Interface</title>
    <author initials="P." surname="van der Stok" fullname="Peter van der Stok">
      <organization abbrev="consultant">consultant</organization>
      <address>
        <phone>+31-492474673 (Netherlands), +33-966015248 (France)</phone>
        <email>consultancy@vanderstok.org</email>
        <uri>www.vanderstok.org</uri>
      </address>
    </author>

   <author initials="A" surname="Bierman" fullname='Andy Bierman' >
      <organization>YumaWorks</organization>
      <address>
        <postal>
          <street>685 Cochran St.</street>
          <street>Suite #160</street>
          <city>Simi Valley</city>
          <region>CA</region>
          <code>93065</code>
          <country>USA</country>
        </postal>
        <email>andy@yumaworks.com</email>
      </address>
    </author>


    <author fullname="Juergen Schoenwaelder" initials="J"
            surname="Schoenwaelder">
      <organization>Jacobs University</organization>
      <address>
        <postal>
          <street>Campus Ring 1</street>
          <city>Bremen</city>
          <code>28759</code>
          <country>Germany</country>
        </postal>
        <email>j.schoenwaelder@jacobs-university.de</email>
      </address>
    </author>
    
    <author fullname="Anuj Sehgal" initials="A"
            surname="Sehgal">
      <organization abbrev="consultant">consultant</organization>
      <address>
        <postal>
          <street>Campus Ring 1</street>
          <city>Bremen</city>
          <code>28759</code>
          <country>Germany</country>
        </postal>
        <email>anuj@iurs.org</email>
      </address>
    </author>


    <date />
    <area>Applications</area>
    <workgroup>core</workgroup>
    <abstract>
      <t>
        This document describes a network management interface for constrained devices, called CoMI.
        CoMI is an adaptation of the RESTCONF protocol for use in constrained devices and networks.
        It is designed to reduce the message sizes, server code size, and application development complexity.
        The Constrained Application Protocol (CoAP) is used to access management data resources specified in YANG,
        or SMIv2 converted to YANG. The payload of the CoMI message is encoded in Concise Binary Object Representation (CBOR).
      </t>
    </abstract>
    <note title="Note">
      <t>
        Discussion and suggestions for improvement are requested,
        and should be sent to core@ietf.org.
      </t>
    </note>
  </front>
  <middle>

<section anchor="introduction" title="Introduction">
<t>
The Constrained Application Protocol (CoAP) <xref target="RFC7252"/> is designed for 
Machine to Machine (M2M) applications such as smart energy and building control.
Constrained devices need to be managed in an automatic fashion to handle the large quantities of devices that are expected in
future installations. The messages between devices need to be as small and infrequent as possible. The implementation
complexity and runtime resources need to be as small as possible.
</t><t>
The draft <xref target="I-D.ietf-netconf-restconf"/> describes a REST-like interface called RESTCONF,
which uses HTTP methods to access structured data defined in YANG <xref target="RFC6020"/>.
RESTCONF allows access to data resources contained in NETCONF <xref target="RFC6241"/> data-stores.
RESTCONF messages can be encoded in XML <xref target="XML"/> or JSON <xref target="RFC7159"/>. The GET method is used
to retrieve data resources and the POST, PUT, PATCH, and DELETE methods are used to create, replace,
merge, and delete data resources.
</t><t>
A large amount of  Management Information Base (MIB) <xref target="RFC3418"/> specifications already
exists for monitoring purposes. This data can be accessed in RESTCONF if the server converts the
SMIv2 modules to YANG, using the mapping rules defined in <xref target="RFC6643"/>.
</t><t>
The CoRE Management Interface (CoMI) is intended to work on standardized data-sets in a stateless client-server fashion.
The RESTCONF protocol is adapted and optimized for use in constrained environments, using
CoAP instead of HTTP.
Standardized data sets promote interoperability between small devices and applications from different manufacturers.
Stateless communication is encouraged to keep communications simple and the amount of state information small in
line with the design objectives of 6lowpan <xref target="RFC4944"/> <xref target="RFC6775"/>, RPL <xref target="RFC6650"/>, and CoAP <xref target="RFC7252"/>.
</t><t>
RESTCONF uses the HTTP methods HEAD, and OPTIONS, which are not available in CoAP.
HTTP uses TCP which is not recommended for CoAP. The transport protocols available to CoAP are
much better suited for constrained networks.
</t><t>
CoMI is low resource oriented, uses CoAP,
and only supports the methods GET, PUT, PATCH, POST and DELETE. The payload of CoMI is encoded in CBOR <xref target="RFC7049"/> which is automatically generated from JSON <xref target="RFC7159"/>.
CBOR has a binary format and hence has more coding efficiency than JSON.
To promote small packets, CoMI uses an additional "data-identifier string-to-number conversion" to minimise CBOR payloads and URI length.
It is assumed that the managed device is the most constrained entity. The client might be more capable,
however this is not necessarily the case.
</t><t>
Currently, small managed devices need to support at least two protocols: CoAP and SNMP <xref target="RFC3411"/>.
When the MIB can be accessed with the CoAP protocol, the SNMP protocol can be replaced with the CoAP protocol. Although the SNMP server size is not huge (see <xref target="code-sizes"/>), the code for the security aspects of SMIv3 <xref target="RFC3414"/> is not negligible.
Using CoAP to access secured management objects reduces the code complexity of the stack in the constrained device, and harmonizes applications development.
</t>
<t>
The objective of CoMI is to provide a CoAP based Function Set that reads and sets values of managed objects in devices to (1) initialize parameter values at start-up, (2) acquire statistics during operation, and (3) maintain nodes by adjusting parameter values during operation.
</t><t>
The end goal of CoMI is to provide information exchange over the CoAP transport protocol in a uniform manner as a first step to the full management functionality as specified in <xref target="I-D.ersue-constrained-mgmt"/>.
</t>

<section anchor="design" title="Design considerations">
  <t>
    CoMI supports discovery of resources, accompanied by reading,
    writing and notification of resource values.  As such it is close
    to the device management of the Open Mobile Alliance described in
    <xref target="OMA"/>. A comparison between CoMI and LWM2M
    management can be found in <xref target="LWM2M"/>.  CoMI supports
    MIB modules which have been translated from SMIv2 to YANG, using
    <xref target="RFC6643"/>.  This mapping is read-only so writable
    SMIv2 objects need to be converted to YANG using an
    implementation-specific mapping.
  </t>
  <t>
    CoMI uses a simple URI to access the management object
    resources. Complexity introduced by instance selection, or
    multiple object specification is expressed with uri-query
    attributes. The choice for uri-query attributes makes the URI
    structure less context dependent.  
</t><t> The YANG data model contains a lot of information that can be exploited by automation tools and need not be transported in the request messages, ultimately leading to reduced message sizes.
  </t>
</section>

<section anchor="terminology" title="Terminology">
<t>
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in <xref target="RFC2119"/>.
</t>
<t>
Readers of this specification should be familiar with all the terms and concepts discussed in <xref target="RFC3410"/>, <xref target="RFC3416"/>, and <xref target="RFC2578"/>.
</t>
<t>
  The following terms are defined in the NETCONF protocol <xref target="RFC6241"/>: client, configuration data, data-store, and server.
</t>
<t>
  The following terms are defined in the YANG data modelling language <xref target="RFC6020"/>: container, data node, key, key leaf, leaf, leaf-list, and list.
</t>
<t>
  The following terms are defined in RESTCONF protocol <xref target="I-D.ietf-netconf-restconf"/>: data resource, data-store resource, edit operation, query parameter, target resource, and unified data-store.
</t>
<t>
  The following terms are defined in this document:
  <list style="hanging">
    <t hangText="YANG hash:"> CoMI object identifier, which is a 30-bit numeric hash of the YANG object identifier
      string for the object. When a YANG hash value is printed in a request target URI, error-path or
      other string, then the lowercase hexadecimal representation is used. Leading zeros are used so the
      value uses 8 hex characters.
    </t>
    <t hangText="Data-node instance:"> An instance of a data-node specified in a YANG module present in the server. The instance is stored in the memory of the server.
    </t>
    <t hangText="Notification-node instance:"> An instance of a schema node of type notification, specified in a YANG module present in the server. The instance is generated in the server at the occurrence of the corresponding event and appended to the default stream.
    </t>
  </list>
</t>
<t>
  The following list contains the abbreviations used in this document.
  <list style="hanging">
    <t hangText="XXXX:">TODO, and others to follow.</t>
  </list>
</t>
<section anchor="tree-diagrams" title="Tree Diagrams">
<t>
A simplified graphical representation of the data model is used in
this document.  The meaning of the symbols in these
diagrams is as follows:
</t>
<t>
<list>
<t>Brackets "[" and "]" enclose list keys.</t>
<t>Abbreviations before data node names: "rw" means configuration
data (read-write) and "ro" state data (read-only).</t>
<t>Symbols after data node names: "?" means an optional node, "!" means
a presence container, and "*" denotes a list and leaf-list.</t>
<t>Parentheses enclose choice and case nodes, and case nodes are also
marked with a colon (":").</t>
<t>Ellipsis ("...") stands for contents of subtrees that are not shown.</t>
</list>
</t>
</section>

</section>  <!-- Terminology -->

</section>  <!-- Introduction -->


<section anchor="comi-architecture" title="CoMI Architecture">
<t>
This section describes the CoMI architecture to use CoAP for the reading and modifying of instrumentation variables used for the management of the instrumented node.
</t>
<figure anchor="archit" title="Abstract CoMI architecture"><artwork align="left"><![CDATA[

Client
+--------------------------------------------------------------+
| +----------------+    +----------------+                     |
| |    SMIv2       | >  |      YANG      |    >     COAP       |
| |specification(2)|    |specification(1)|       Request(3)    |
| +----------------+    +----------------+[         *          |
+-----------------------------*-----------[---------*----------+
                              *           [         *
                              *           [    +-----------+
                      mapping *   security[    |  Network  |
                              *      (8)  [    | packet(4) |
                              *           [    +-----------+
Server                        *           [         *
+-----------------------------*-----------[---------*----------+
|                             *           [         *          |
|                             *                 Retrieval,     |
|                             *               Modification(5)  |
|                            \*/                    *          |
| +-------------------------------------------------*--------+ |
| |                    +--------------+       +------------+ | |
| |                    |configuration |       |Operational | | |
| |                    |     (6b)     |       |  state(6a) | | |
| |                    +--------------+       +------------+ | |
| |                    variable store (6)           *        | |
| +-------------------------------------------------*--------+ |
|                                                   *          |
|                                                Variable      |
|                                            Instrumentation(7)|
+--------------------------------------------------------------+

]]></artwork></figure>
<t>
<xref target="archit"/> is a high level representation of the main elements of the CoAP management architecture. A client sends requests as payload in packets over the network to a managed constrained node. 
</t>
<t>
Objectives are:
<list style="symbols">
<t>Equip a constrained node with a management server that provides information about the operational characteristics of the code running in the constrained node.</t>
<t>The server provides this information in a variable store that contains values describing the performance characteristics and the code parameter values.</t>
<t>The client receives the performance characteristics on a regular basis or on request.</t>
<t>The client sets the parameter values in the server at bootstrap and intermittently when operational conditions change.</t>
<t>The constrained network requires the payload to be as small as possible, and the constrained server memory
requirements should be as small as possible.</t>
</list>
</t>
<t>
For interoperability it is required that in addition to using the Internet Protocol for data transport:
<list style="symbols">
<t>The names, type, and semantics of the instrumentation variables are standardized.</t>
<t>The instrumentation variables are described in a standard language. </t>
<t>The signature of the CoAP request in the server is standardized.</t>
<t>The format of the packet payload is standardized.</t>
<t>The notification from server to client is standardized.</t>
</list>
</t>
<t>
The different numbered components of Figure 1 are discussed according to component number.
<list style="hanging"> 
<t hangText="(1) YANG specification:"> contains a set of named and versioned modules. A module specifies a hierarchy of named and typed resources. A resource is uniquely identified by a sequence of its name and the names of the enveloping resources following the hierarchy order. The YANG specification serves as input to the writers of application and instrumentation code and the humans analysing the returned values (arrow from YANG specification to Variable store). The specification can be used to check the correctness of the CoAP request and do the CBOR
encoding.
</t>
<t hangText="(2) SMIv2 specification:"> A named module specifies a set of variables and "conceptual tables". Named variables have simple types. Conceptual tables are composed of typed named columns. The variable name and module name identify the variable uniquely. There is an algorithm to translate SMIv2 specifications to YANG specifications.
</t>
<t hangText="(3) CoAP request:"> The CoAP request needs a Universal Resource Identifier (URI) and the payload of the packet to send a request. The URI is composed of the schema, server, path and query and looks like coap://entry.example.com/&lt;path&gt;?&lt;query&gt;. Fragments are not supported. Allowed operations are PUT, PATCH, GET, DELETE, and POST. New variables can be created with POST when they exist in the YANG specification. The Observe option can be used to return variable values regularly or on event occurrence (notification).
</t>
<t hangText="(3.1) CoAP &lt;path&gt;:"> The path identifies the variable in the form "/mg/&lt;hash-value&gt;".</t>
<t hangText="(3.2) CoAP &lt;query&gt;:"> The query parameter is used to specify additional (optional) aspects like the module name, list instance, and others. The idea is to keep the path simple and put variations on variable specification in the query.
</t>
<t hangText="(3.3) CoAP discovery:"> Discovery of the variables is done with standard CoAP resource discovery using /.well-known/core with ?rt=/core.mg.
</t>
<t hangText="(4) Network packet:"> The payload contains the CBOR encoding of JSON objects.
This object corresponds to the converted RESTCONF message payload.
</t>
<t hangText="(5) Retrieval, modification:"> The server needs to parse the CBOR encoded message 
and identify the corresponding instances in the Variable store. In addition, this component
includes the code for CoAP Observe and block options.
</t>
<t hangText="(6) Variable store:"> The store is composed of two parts: Operational state and Configuration data-store (see <xref target= "restconf-architecture"/>). CoMI does not differentiate between variable store types. The Variable store contains data-node instances. Values are stored in the appropriate instances, and or values are returned from the instances into the payload of the packet.
</t>
<t hangText="(7) Variable instrumentation:"> This code depends on implementation of drivers and other node specific aspects. The Variable instrumentation code stores the values of the parameters into the appropriate places in the operational code. The variable instrumentation code reads current execution values from the operational code and stores them in the appropriate instances.
</t>
<t hangText="(8) Security:"> The server MUST prevent unauthorized users from reading or writing
any data resources. CoMI relies on DTLS <xref target="RFC6347"/> which is specified to secure CoAP communication.
</t>
</list>
</t>

<section anchor="restconf-architecture" title="RESTCONF/YANG Architecture">
<t>
CoMI adapts the RESTCONF architecture so data exchange and implementation requirements
are optimized for constrained devices.
</t>
<t>
The RESTCONF protocol uses a unified data-store to edit conceptual data structures
supported by the server. The details of transaction preparation and non-volatile
storage of the data are hidden from the RESTCONF client. CoMI also uses a unified data-store,
to allow stateless editing of configuration variables and the notification of operational variables.
</t>
<t>
The child schema nodes of the unified data-store include all the top-level YANG data nodes
in all the YANG modules supported by the server. The YANG data structures represent
a hierarchy of data resources. The client discovers the list of YANG
modules, and important conformance information such as the module revision dates,
YANG features supported, and YANG deviations required.  The individual data nodes are
discovered indirectly by parsing the YANG modules supported by the server.
</t>
<t>
The YANG data definition statements contain a lot of information that can help automation
tools, developers, and operators use the data model correctly and efficiently.  The YANG definitions
and server YANG module capability advertisements provide an "API contract" that allow a client
to determine the detailed server management capabilities very quickly.  CoMI allows access
to the same data resources as a RESTCONF server, except the messages are optimized
to reduce identifier and payload size.
</t>
<t>
RESTCONF uses a simple algorithmic mapping from YANG to URI syntax to identify the target resource
of a retrieval or edit operation. A client can construct operations or scripts using a
predictable syntax, based on the YANG data definitions. The target resource URI can
reference a data resource instance, or the data-store itself (to retrieve the entire data-store
or create a top-level data resource instance). CoMI uses a compression algorithm to reduce the size of the data-node instance identifier (see <xref target="object-id-compression"/>.
</t>
</section>

<section anchor="object-id-compression" title="Compression of data-node instance identifier">
<t>
The RESTCONF protocol uses the full path of the desired data resource
in the target resource URI.
The JSON encoding will include the module name string to specify
the YANG module.
If a representation of the target resource is included in the
request or response message in RESTCONF messages, then the
data definition name string is used to identify each node in the message.
The module namespace (or name) may also be present in these identifiers.
</t>
<t>
In order to greatly reduce the size of identifiers used in CoMI, numeric
object identifiers are used instead of these strings.
The specific encoding of the object identifiers
is not hard-wired in the protocol.
</t>
<t>
YANG Hash is the default encoding for object identifiers.
This encoding in considered to be "unstructured" since the particular
values for each object are determined by a hash algorithm.
It is possible for 2 different objects to generate the same
hash value.  If this occurs, then the client and server will
both need to rehash the colliding object identifiers to new unused hash values.
</t>
<t>
In order to eliminate the need for rehashing, CoMI allows for
alternate "structured" object identifier encoding formats.
Structured object identifier MUST be managed such that
no object ID collisions are possible, and therefore no rehash
procedures are needed.  Structured object identifiers can also be
selected to minimize the size of a subset of the
object identifiers (e.g., the most requested objects).
</t>
<t>
In <xref target="discovery"/> the discovery of the object ID compression scheme is described.
</t>
</section>

</section>  <!-- CoMI Architecture  -->


<section anchor="coap-interface" title="CoAP Interface">
<t>

In CoAP a group of links can constitute a Function Set. The format of the links is specified in <xref target="I-D.ietf-core-interfaces"/>.
  This note specifies a Management Function Set. CoMI end-points that implement the CoMI management protocol support
 at least one discoverable management resource of resource type (rt): core.mg, with path: /mg, where mg is short-hand for management. The name /mg is recommended but not compulsory (see <xref target="discovery"/>).
</t>
<t>
The path prefix /mg has resources accessible with the following five paths:
<list style="hanging">
<t hangText="/mg:">YANG-based data with path "/mg" and using CBOR content encoding format.
This path represents a data-store resource which contains YANG data resources as its descendant nodes.
All identifiers referring to YANG data nodes within this path are encoded as YANG hash values (see <xref target="base64url"/>).</t>
<t hangText="/mg/mod.uri:">URI identifying the location of the server module information, with path "/mg/mod.uri" and CBOR content format. This YANG data is encoded with plain identifier strings, not YANG hash values.</t>
<t hangText="/mg/mod.set:">String identifying the module set ID in use by the server,
which is defined as the 'module-set-id' leaf in the ietf-yang-library
module. This resource  MUST
change to a new value when the set of YANG modules in use by the server changes.
</t>
<t hangText="/mg/num.typ:">String identifying the object ID numbering scheme used
by the CoMI server. The only value defined in this document is 'yanghash' to
indicate that the YANG Hash numbering scheme defined in this document is used.
It is possible for other object numbering schemes to be defined outside the
scope of this document.
</t>
<t hangText="/mg/srv.typ:">String identifying the CoMI server type.
The value 'ro' indicates that the server is a read-only server and no editing operations
are supported. A read-only server is not required to provide YANG deviation statements
for any writable YANG data nodes.
The value 'rw' indicates that the server is a read-write server and editing operations
are supported. A read-write server is required to provide YANG deviation statements
for any writable YANG data nodes that are not fully implemented.
</t>

<t hangText="/mg/yh.uri:"> URI indicating the location of the server YANG hash information if any objects needed
to be re-hashed by the server. It has the path "/mg/yh.uri" and is encoded in CBOR format.
The "ietf-yang-hash" module of <xref target="YANGMOD"/> is used to define the syntax and semantics
of this data structure.
This YANG data is encoded with plain identifier strings, not YANG hash values. The server will only have
this resource if there are any objects that needed to be re-hashed due to a hash collision.
</t>
<t hangText="/mg/stream:"> String identifying the default stream resource to which YANG notification instances are appended.  Notification support is optional, so this resource will not exist
if the server does not support any notifications.
</t>
</list>
</t><t>
The mapping of YANG data node instances to CoMI resources is as follows:
A YANG module describes a set of data trees composed of YANG data nodes.
Every root of a data tree in a YANG module loaded in the CoMI server represents a resource of the server.
All data root descendants represent sub-resources.
</t><t>
The resource identifiers of the instances of the YANG specifications are YANG hash values, as described in <xref target="HASH-GEN"/>. When multiple instances of a list node exist, the instance selection is described in <xref target="keysParm"/>
</t>
<t>
The profile of the management function set, with IF=core.mg, is shown in the table below,
following the guidelines of <xref target="I-D.ietf-core-interfaces"/>:
</t>

<texttable>
  <ttcol align="left">name</ttcol>
  <ttcol align="left">path</ttcol>
  <ttcol align="left">rt</ttcol>
  <ttcol align="left">Data Type</ttcol>

  <c> Management  </c>   <c> /mg </c> <c> core.mg </c> <c> n/a </c>
  <c> Data  </c>   <c> /mg </c> <c> core.mg.data </c> <c> application/cbor </c>
  <c> Module Set URI </c>   <c> /mg/mod.uri </c> <c> core.mg.moduri </c> <c> application/cbor </c>
  <c> Module Set ID </c> <c> /mg/mod.set </c> <c> core.mg.modset </c> <c> application/cbor </c>
  <c> Numbering Type </c>   <c> /mg/num.typ </c> <c> core.mg.num-type </c> <c> application/cbor </c>
  <c> Server Type </c>   <c> /mg/srv.typ </c> <c> core.mg.srv-type </c> <c> application/cbor </c>
  <c> YANG Hash Info </c>   <c> /mg/yh.uri </c> <c> core.mg.yang-hash </c> <c> application/cbor </c>
  <c> Events </c>   <c> /mg/stream </c> <c> core.mg.stream </c> <c> application/cbor </c>

</texttable>

</section>   <!-- CoAP Interface -->

<section anchor="mgFS" title="MG Function Set">
<t>
The MG Function Set provides a CoAP interface to perform a subset of the functions provided by RESTCONF.
</t>

<t>
A subset of the operations defined in RESTCONF are used in CoMI:
</t>
<texttable>
  <ttcol align="left">Operation</ttcol>
  <ttcol align="left">Description</ttcol>
  <c> GET </c>   <c> Retrieve the data-store resource or a data resource </c>
  <c> POST </c>   <c> Create a data resource </c>
  <c> PUT </c>   <c> Create or replace a data resource </c>
  <c> PATCH </c>  <c> Replace a data resource partially </c>
  <c> DELETE </c>   <c> Delete a data resource </c>
</texttable>

<section anchor="DataRetrieval" title="Data Retrieval">

<section anchor="GetOperation" title="GET">
<t>
One or more instances of data resources are retrieved by the client with the GET method.
The RESTCONF GET operation is supported in CoMI.
The same constraints apply as defined in section 3.3 of <xref target="I-D.ietf-netconf-restconf"/>.
The operation is mapped to the GET method defined in section 5.8.1 of <xref target="RFC7252"/>.
</t><t>
It is possible that the size of the payload is too large to fit in a single message.
In the case that management data is bigger than the maximum supported payload size,
the Block mechanism from <xref target="I-D.ietf-core-block"/> is used, as explained in more detail in <xref target="block"/>.
</t>
<t>
There are two query parameters for the GET method.
A CoMI server MUST implement the keys parameter and MAY implement the select parameter to allow common data retrieval
filtering functionality.
</t>
<texttable>
  <ttcol align="left">Query Parameter</ttcol>
  <ttcol align="left">Description</ttcol>
  <c> keys </c> <c> Request to select instances of a YANG definition </c>
  <c> select </c>   <c> Request selected sub-trees from the target resource </c>
</texttable>
<t>
The "keys" parameter is used to specify a specific instance of the resource. When keys is not specified, all instances are returned. When no or one instance of the resource exists, the keys parameter is not needed.
</t>
</section>   <!-- GET -->

<section anchor="SelectParam" title="Mapping of the 'select' Parameter">
  <t>
    RESTCONF uses the 'select' parameter to specify an expression
    which can represent a subset of all data nodes within the target
    resource <xref target="I-D.ietf-netconf-restconf"/>. This
    parameter is useful for filtering sub-trees and retrieving only a
    subset that a managing application is interested in.
  </t>
  <t>
    However, filtering is a resource intensive task and not all
    constrained devices can be expected to have enough computing
    resources such that they will be able to successfully filter and
    return a subset of a sub-tree. This is especially likely to be
    true with Class 0 devices that have significantly lesser RAM than
    10 KiB <xref target="RFC7228"/>. Since CoMI is targeted at
    constrained devices and networks, only a limited subset of the
    'select' parameter is used here.
  </t>
  <t>
    Unlike the RESTCONF 'select' parameter, CoMI does not use object
    names in "XPath" or "path-expr" format to identify the subset that
    needs to be filtered. Parsing XML is resource intensive for
    constrained devices <xref target="management"/> and using object
    names can lead to large message sizes. Instead, CoMI utilizes the
    YANG hashes described in <xref target="mapping"/> to identify the
    sub-trees that should be filtered from a target resource. Using
    these hashes ensures that a constrained node can identify the
    target sub-tree without expending many resources and that the
    messages generated are also efficiently encoded.
  </t>
  <t>
    The implementation of the 'select' parameter is already optional
    for constrained devices, however, even when implemented it is
    expected to be a best effort feature, rather than a service that
    nodes must provide. This implies that if a node receives the
    'select' parameter specifying a set of sub-trees that should be
    returned, it will only return those that it is able to.
  </t>
</section>  <!-- Select -->

<section anchor="RetrievalExamples" title="Retrieval Examples">

<t>
In all examples the path is expressed in readable names and as a hash value of the name (where the hash value in the payload is expressed as a hexadecimal number, and the hash value in the URL as a base64 number). The examples in this section use a JSON payload with one or more entries describing the pair (identifier, value).
CoMI transports the CBOR format to transport the equivalent contents. The CBOR syntax of the payloads is specified in <xref target="mapping"/>.
</t>

<section anchor="single" title="Single instance retrieval">

<t>
A request to read the values of instances of a management object or the leaf of an object is sent with a confirmable CoAP GET message. A single object is specified in the URI path prefixed with /mg. 
</t>
<t>
Using for example the clock container from <xref target="RFC7317"/>, a request is sent to retrieve the value of clock/current-datetime specified in module system-state. The answer to the request returns a (identifier, value) pair.
</t>

 <figure>
    <artwork align="left"><![CDATA[

REQ: GET example.com/mg/system-state/clock/current-datetime

RES: 2.05 Content (Content-Format: application/cbor)
{
    "current-datetime" : "2014-10-26T12:16:31Z"
}
]]></artwork>
    </figure>


<t>
The YANG hash value for 'current-datetime' is calculated by constructing
the schema node identifier for the object:
</t>
 <figure>
    <artwork align="left"><![CDATA[
/sys:system-state/sys:clock/sys:current-datetime
]]></artwork>
    </figure>
<t>
The 30 bit murmur3 hash value is calculated on this string (0x15370408 and VNwQI).
The request using this hash value is shown below:
</t>

 <figure>
    <artwork align="left"><![CDATA[

REQ: GET example.com/mg/VNwQI

RES: 2.05 Content (Content-Format: application/cbor)
{
    0x15370408 : "2014-10-26T12:16:31Z"
}
]]></artwork>
    </figure>

<t>
The specified object can be an entire object. Accordingly, the returned payload is composed of all the leaves associated with the object. Each leaf is returned as a (YANG hash, value) pair. For example, the GET of the clock object, sent by the client, results in the following returned payload sent by the managed entity:
      </t>

<figure><artwork align="left">
<![CDATA[
REQ: GET example.com/mg/system-state/clock
   (Content-Format: application/cbor)

RES: 2.05 Content (Content-Format: application/cbor)
{
      "clock/current-datetime" : "2014-10-26T12:16:51Z",
      "clock/boot-datetime" : "2014-10-21T03:00:00Z"
}
]]></artwork></figure>

<t>
The YANG hash values for 'clock', 'current-datetime', and 'boot-datetime' are calculated by constructing
the schema node identifier for the objects, and then calculating the 30 bit murmur3 hash values (shown
in parenthesis):
</t>
 <figure>
    <artwork align="left"><![CDATA[
/sys:system-state/sys:clock (0x2eb2fa3b and usvo7)
/sys:system-state/sys:clock/sys:current-datetime (0x15370408)
/sys:system-state/sys:clock/sys:boot-datetime (0x1fa25361)
]]></artwork>
    </figure>
<t>
The request using the hash values is shown below:
</t>

<figure><artwork align="left">
<![CDATA[
REQ: GET example.com/mg/usvo7
   (Content-Format: application/cbor)

RES: 2.05 Content (Content-Format: application/cbor)
{
      0x15370408 : "2014-10-26T12:16:51Z",
      0x1fa25361 : "2014-10-21T03:00:00Z"
}
]]></artwork></figure>

</section>
<section anchor="multiple" title="Multiple instance retrieval">

<t>
A "list" node can have multiple instances. Accordingly, the returned payload is composed of all the instances associated with the list node. Each instance is returned as a (identifier, value) pair. The "keys" query parameter is used to identify a specific list instance by specifying a given index value (see <xref target="keysParm"/>).
</t><t>
For example, the GET of the /interfaces/interface/ipv6/neighbor instance identified with
interface index "eth0" <xref target="RFC7223"/>, sent by the client, results in the following returned payload sent by the managed entity:
</t>

<figure><artwork align="left">
<![CDATA[
REQ: GET example.com/mg/interfaces/interface/ipv6/neighbor?keys=eth0
   (Content-Format: application/cbor)

RES: 2.05 Content (Content-Format: application/cbor)
{
   "neighbor":[
     {
	"ip" : "fe80::200:f8ff:fe21:67cf",
	"link-layer-address" : "00:00::10:01:23:45"
     },
     {
	"ip" : "fe80::200:f8ff:fe21:6708",
	"link-layer-address" : "00:00::10:54:32:10"
     },
     {
	"ip" : "fe80::200:f8ff:fe21:88ee",
	"link-layer-address" : "00:00::10:98:76:54"
     }
   ]
}
]]></artwork></figure>

<t>
The YANG hash values for 'neighbor', 'ip', and 'link-layer-address' are calculated by constructing
the schema node identifier for the objects, and then calculating the 30 bit murmur3 hash values (shown
in parenthesis):
</t>
 <figure>
    <artwork align="left"><![CDATA[
/if:interfaces/if:interface/ip:ipv6/ip:neighbor (0x2354bc49 and jVLxJ)
/if:interfaces/if:interface/ip:ipv6/ip:neighbor/ip:ip
    (0x20b8907e and guJB_)
/if:interfaces/if:interface/ip:ipv6/ip:neighbor/ip:link-layer-address
   (0x16f47fd8)
]]></artwork>
    </figure>
<t>
The request using the hash values is shown below:
</t>

<figure><artwork align="left">
<![CDATA[
REQ: GET example.com/mg/jVLxJ?keys=eth0
   (Content-Format: application/cbor)

RES: 2.05 Content (Content-Format: application/cbor)
{
   0x2354bc49 : [
     {
	0x20b8907e : "fe80::200:f8ff:fe21:67cf",
	0x16f47fd8 : "00:00::10:01:23:45"
     },
     {
	0x20b8907e : "fe80::200:f8ff:fe21:6708",
	0x16f47fd8 : "00:00::10:54:32:10"
     },
     {
	0x20b8907e : "fe80::200:f8ff:fe21:88ee",
	0x16f47fd8 : "00:00::10:98:76:54"
     }
   ]
}
]]></artwork></figure>

</section>  <!-- Single object value -->

<section anchor="MIB" title="Access to MIB Data">

<t>
The YANG translation of the SMI specifying the ipNetToMediaTable <xref target="RFC4293"/> yields:
</t>
<figure><artwork align="left">
<![CDATA[
container IP-MIB {
  container ipNetToPhysicalTable {
    list ipNetToPhysicalEntry {
       key "ipNetToPhysicalIfIndex
            ipNetToPhysicalNetAddressType
            ipNetToPhysicalNetAddress";
       leaf ipNetToMediaIfIndex {
          type: int32;
       }
       leaf ipNetToPhysicalIfIndex {
         type if-mib:InterfaceIndex;
       }
       leaf ipNetToPhysicalNetAddressType {
         type inet-address:InetAddressType;
       }
       leaf ipNetToPhysicalNetAddress {
         type inet-address:InetAddress;
       }
       leaf ipNetToPhysicalPhysAddress {
         type yang:phys-address {
            length "0..65535";
         }
       }
       leaf ipNetToPhysicalLastUpdated {
         type yang:timestamp;
       }
       leaf ipNetToPhysicalType {
         type enumeration { ... }
       }
       leaf ipNetToPhysicalState {
         type enumeration { ... }
       }
       leaf ipNetToPhysicalRowStatus {
         type snmpv2-tc:RowStatus;
       }
    }
 }
]]></artwork></figure>
<t>
The following example shows an "ipNetToPhysicalTable" with 2 instances,
using JSON encoding:
</t>
<figure><artwork align="left">
<![CDATA[
{ 
  "IP-MIB/ipNetToPhysicalTable/ipNetToPhysicalEntry" : [
        {
          "ipNetToPhysicalIfIndex" : 1,
          "ipNetToPhysicalNetAddressType" : "ipv4",
          "ipNetToPhysicalNetAddress" : "10.0.0.51",
          "ipNetToPhysicalPhysAddress" : "00:00:10:01:23:45",
          "ipNetToPhysicalLastUpdated" : "2333943",
          "ipNetToPhysicalType" : "static",
          "ipNetToPhysicalState" : "reachable",
          "ipNetToPhysicalRowStatus" : "active"
        },
        {
          "ipNetToPhysicalIfIndex" : 1,
          "ipNetToPhysicalNetAddressType" : "ipv4",
          "ipNetToPhysicalNetAddress" : "9.2.3.4",
          "ipNetToPhysicalPhysAddress" : "00:00:10:54:32:10",
          "ipNetToPhysicalLastUpdated" : "2329836",
          "ipNetToPhysicalType" : "dynamic",
          "ipNetToPhysicalState" : "unknown",
          "ipNetToPhysicalRowStatus" : "active"
        }
      ]
    }
  }
}
]]></artwork></figure>        

<t>
The YANG hash values for 'ipNetToPhysicalEntry' and its child nodes are calculated by constructing
the schema node identifier for the objects, and then calculating the 30 bit murmur3 hash values (shown
in parenthesis):
</t>
 <figure>
    <artwork align="left"><![CDATA[
/ip-mib:IP-MIB/ip-mib:ipNetToPhysicalTable (0x30b7bc3f and wt7w_)
/ip-mib:IP-MIB/ip-mib:ipNetToPhysicalTable/ip-mib:ipNetToPhysicalEntry
   (0x1067f289 and QZ_KJ)
/ip-mib:IP-MIB/ip-mib:ipNetToPhysicalTable/ip-mib:ipNetToPhysicalEntry/
   ip-mib:ipNetToPhysicalIfIndex (0x00d38564)
/ip-mib:IP-MIB/ip-mib:ipNetToPhysicalTable/ip-mib:ipNetToPhysicalEntry/
   ip-mib:ipNetToPhysicalNetAddressType (0x2745e222)
/ip-mib:IP-MIB/ip-mib:ipNetToPhysicalTable/ip-mib:ipNetToPhysicalEntry/
   ip-mib:ipNetToPhysicalNetAddress (0x387804eb)
/ip-mib:IP-MIB/ip-mib:ipNetToPhysicalTable/ip-mib:ipNetToPhysicalEntry/
   ip-mib:ipNetToPhysicalPhysAddress (0x1a51514a)
/ip-mib:IP-MIB/ip-mib:ipNetToPhysicalTable/ip-mib:ipNetToPhysicalEntry/
   ip-mib:ipNetToPhysicalLastUpdated (0x03f95578)
/ip-mib:IP-MIB/ip-mib:ipNetToPhysicalTable/ip-mib:ipNetToPhysicalEntry/
   ip-mib:ipNetToPhysicalType (0x24ade115)
/ip-mib:IP-MIB/ip-mib:ipNetToPhysicalTable/ip-mib:ipNetToPhysicalEntry/
   ip-mib:ipNetToPhysicalState (0x09e640ef)
/ip-mib:IP-MIB/ip-mib:ipNetToPhysicalTable/ip-mib:ipNetToPhysicalEntry/
   ip-mib:ipNetToPhysicalRowStatus (0x3b5c1ab6)
]]></artwork>
    </figure>

<t>
The following example shows a request for the entire  ipNetToPhysicalTable.
Since all the instances are requested, no "keys" query parameter is needed.
</t>

 <figure>
    <artwork align="left"><![CDATA[
REQ: GET example.com/mg/wt7w_

RES: 2.05 Content (Content-Format: application/cbor)
{
      0x1067f289 : [
        {
          0x00d38564 : 1,
          0x2745e222 : "ipv4",
          0x387804eb : "10.0.0.51",
          0x1a51514a : "00:00:10:01:23:45",
          0x03f95578 : "2333943",
          0x24ade115 : "static",
          0x09e640ef : "reachable",
          0x3b5c1ab6 : "active"
        },
        {
          0x00d38564 : 1,
          0x2745e222 : "ipv4",
          0x387804eb : "9.2.3.4",
          0x1a51514a : "00:00:10:54:32:10",
          0x03f95578 : "2329836",
          0x24ade115 : "dynamic",
          0x09e640ef : "unknown",
          0x3b5c1ab6 : "active"
        }
      ]
}
]]></artwork>
    </figure>
    
</section>  <!-- MIB example -->

<section anchor="keysParm" title="The 'keys' Query Parameter">
<t>
There is a mandatory query parameter that MUST be supported by servers called "keys".
This parameter is used to specify the key values for an instance of an object
identified by a YANG hash value.  Any key leaf values of the instance are passed
in order. The first key leaf in the top-most list is the first key encoded in
the 'keys' parameter.
</t>
<t>
The key leafs from top to bottom and left to right are encoded
as a comma-delimited list. If a key leaf value is missing then
all values for that key leaf are returned.
</t>

<t>
Example:
In this example exactly 1 instance is requested from
the ipNetToPhysicalEntry (from a previous example).
</t>

 <figure>
    <artwork align="left"><![CDATA[
REQ: GET example.com/mg/QZ_KJ?keys=1,ipv4,10.0.0.51

RES: 2.05 Content (Content-Format: application/cbor)
{
   0x1067f289 : [
      {
        0x00d38564 : 1,
        0x2745e222 : "ipv4",
        0x387804eb : "10.0.0.51",
        0x1a51514a : "00:00:10:01:23:45",
        0x03f95578 : "2333943",
        0x24ade115 : "static",
        0x09e640ef : "reachable",
        0x3b5c1ab6 : "active"
      }
   ]
}
]]></artwork>
    </figure>



<t>
An example illustrates the syntax of keys query parameter.
In this example the following YANG module is used:
</t>

<figure>
   <artwork align="left"><![CDATA[

  module foo-mod {
    namespace foo-mod-ns;
    prefix foo;

    list A {
      key "key1 key2";
      leaf key1 { type string; }
      leaf key2 { type int32; }
      list B {
        key "key3";
        leaf key3 { type string; }
        leaf col1 { type uint32; }
      }
    }
  }

]]></artwork>
</figure>

<t>
The path identifier for the leaf "col1" is the following string:
</t>
<figure>
   <artwork align="left"><![CDATA[

   /foo:A/foo:B/foo:col1

]]></artwork>
</figure>
<t>
The YANG hash for this identifier string has values: 0xa9abdcca and pq9zK).
</t>
<t>
The following string represents the RESTCONF target resource URI expression for the "col1"
leaf for the key values "top", 17, and "group1":
</t>
<figure>
   <artwork align="left"><![CDATA[

   /restconf/data/foo-mod:A="top",17/B="group1"/col1

]]></artwork>
</figure>

<t>
The following string represents the CoMI target resource identifier for the same instance
of the "col1" leaf:
</t>
<figure>
   <artwork align="left"><![CDATA[

   /mg/pq9zK?keys="top",17,"group1"

]]></artwork>
</figure>

</section>  <!-- key query -->

<section anchor="SelectExample" title="The 'select' Query Parameter">
  <t>
    The select parameter is used along with the GET method to provide
    a sub-tree filter mechanism. A list of YANG hashes that should be
    filtered is provided along with a list of keys identifying the
    instances that should be returned. When the keys parameter is used together with the select, the key values are added in brackets without using the "keys=" text.
  </t>
  <t>
    The following example shows an "ipNetToPhysicalTable" (from a
    previous example) with 4 instances, using JSON encoding:
  </t>
  <figure><artwork align="left">
<![CDATA[
{ 
  "IP-MIB/ipNetToPhysicalTable/ipNetToPhysicalEntry" : [
        {
          "ipNetToPhysicalIfIndex" : 1,
          "ipNetToPhysicalNetAddressType" : "ipv4",
          "ipNetToPhysicalNetAddress" : "10.0.0.51",
          "ipNetToPhysicalPhysAddress" : "00:00:10:01:23:45",
          "ipNetToPhysicalLastUpdated" : "2333943",
          "ipNetToPhysicalType" : "static",
          "ipNetToPhysicalState" : "reachable",
          "ipNetToPhysicalRowStatus" : "active"
        },
        {
          "ipNetToPhysicalIfIndex" : 1,
          "ipNetToPhysicalNetAddressType" : "ipv4",
          "ipNetToPhysicalNetAddress" : "9.2.3.4",
          "ipNetToPhysicalPhysAddress" : "00:00:10:54:32:10",
          "ipNetToPhysicalLastUpdated" : "2329836",
          "ipNetToPhysicalType" : "dynamic",
          "ipNetToPhysicalState" : "unknown",
          "ipNetToPhysicalRowStatus" : "active"
        },
        {
          "ipNetToPhysicalIfIndex" : 2,
          "ipNetToPhysicalNetAddressType" : "ipv4",
          "ipNetToPhysicalNetAddress" : "10.24.2.53",
          "ipNetToPhysicalPhysAddress" : "00:00:10:28:19:CA",
          "ipNetToPhysicalLastUpdated" : "2124368",
          "ipNetToPhysicalType" : "static",
          "ipNetToPhysicalState" : "unknown",
          "ipNetToPhysicalRowStatus" : "active"
        },
	{
          "ipNetToPhysicalIfIndex" : 3,
          "ipNetToPhysicalNetAddressType" : "ipv4",
          "ipNetToPhysicalNetAddress" : "192.168.2.12",
          "ipNetToPhysicalPhysAddress" : "00:00:10:29:11:32",
          "ipNetToPhysicalLastUpdated" : "1925384",
          "ipNetToPhysicalType" : "dynamic",
          "ipNetToPhysicalState" : "reachable",
          "ipNetToPhysicalRowStatus" : "active"
        }	  
      ]
    }
  }
}
]]></artwork></figure>        
  <t>
    Data may be retrieved using the select query parameter in the
    following way:
  </t>
   <figure>
    <artwork align="left"><![CDATA[
REQ: GET example.com/mg/?select=wt7w_(ipv4,reachable)

RES: 2.05 Content (Content-Format: application/cbor)
{
   0x1067f289 : [
      {
        0x00d38564 : 1,
        0x2745e222 : "ipv4",
        0x387804eb : "10.0.0.51",
        0x1a51514a : "00:00:10:01:23:45",
        0x03f95578 : "2333943",
        0x24ade115 : "static",
        0x09e640ef : "reachable",
        0x3b5c1ab6 : "active"
	},
	{
          0x00d38564 : 3,
          0x2745e222 : "ipv4",
          0x387804eb : "192.168.2.12",
          0x1a51514a : "00:00:10:29:11:32",
          0x03f95578 : "1925384",
          0x24ade115 : "dynamic",
          0x09e640ef : "reachable",
          0x3b5c1ab6 : "active"
        }	
   ]
}
]]></artwork>
   </figure>
   <t>
     In this example exactly 2 instances are returned as response from
     the ipNetToPhysicalTable because both those instances match the
     provided keys.
   </t>
   <t>
     Supposing there were multiple YANG hashes with their own sets of
     keys that were to be filtered, the select query parameter can be
     used to retrieve results from these in one go as well. The
     following string represents the CoMI target resource identifier
     when multiple YANG hashes, with their own sets of keys are
     queried:
   </t>
   <figure>
     <artwork>
       /mg/?select=hash1(hash1-key1,hash1-key2,...),hash2(hash2-key1)...
     </artwork>
   </figure>
</section>  <!-- Select Example -->


</section>   <!-- Retrieval Examples -->

</section>  <!-- Data Retrieval -->

<section anchor="DataEditing" title="Data Editing">
<t>
CoMI allows data-store contents to be created, modified and deleted using CoAP methods.
</t>
<t>
Data-editing is an optional feature.
The server will indicate its editing capability with the "/core.rg.srv-type
resource type. If the value is 'rw' then the server supports editing operations.
If the value is 'ro' then the server does not support editing operations.
</t>

<section anchor="DataOrdering" title="Data Ordering">
<t>
A CoMI server is not required to support entry insertion of lists and leaf-lists
that are ordered by the user (i.e., YANG statement "ordered-by user").
The 'insert' and 'point' query parameters from RESTCONF are not used in CoMI.
</t>
<t>
A CoMI server SHOULD preserve the relative order of all user-ordered list and
leaf-list entries that are received in a single edit request.  These YANG
data node types are encoded as arrays so messages will preserve their order.
</t>
</section>

<section anchor="PostOperation" title="POST">
<t>
Data resource instances are created with the POST method.
The RESTCONF POST operation is supported in CoMI, however it is only allowed
for creation of data resources.
The same constraints apply as defined in section 3.4.1 of <xref target="I-D.ietf-netconf-restconf"/>.
The operation is mapped to the POST method defined in section 5.8.2 of <xref target="RFC7252"/>.
</t>
<t>
There are no query parameters for the POST method.
</t>


</section>

<section anchor="PutOperation" title="PUT">
<t>
Data resource instances are created or replaced with the PUT method.
The PUT operation is supported in CoMI.
A request to set the values of instances of an object/leaf is sent with a confirmable CoAP PUT message.
The Response is piggybacked to the CoAP ACK message corresponding with the Request.

The same constraints apply as defined in section 3.5 of <xref target="I-D.ietf-netconf-restconf"/>.
The operation is mapped to the PUT method defined in section 5.8.3 of <xref target="RFC7252"/>.
</t>
<t>
There are no query parameters for the PUT method.
</t>

</section>


<section anchor="PatchOperation" title="PATCH">
<t>
Data resource instances are partially replaced with the PATCH method <xref target="I-D.vanderstok-core-patch"/>.
The PATCH operation is supported in CoMI.
A request to set the values of instances of a subset of the values of the resource is sent with a confirmable CoAP PATCH message.
The Response is piggybacked to the CoAP ACK message corresponding with the Request.

The same constraints apply as defined in section 3.5 of <xref target="I-D.ietf-netconf-restconf"/>.
The operation is mapped to the PATCH method defined in <xref target="I-D.vanderstok-core-patch"/>.
</t>
<t>
There are no query parameters for the PATCH method.
</t>
</section>

<section anchor="DeleteOperation" title="DELETE">
<t>
Data resource instances are deleted with the DELETE method.
The RESTCONF DELETE operation is supported in CoMI.
The same constraints apply as defined in section 3.7 of <xref target="I-D.ietf-netconf-restconf"/>.
The operation is mapped to the DELETE method defined in section 5.8.4 of <xref target="RFC7252"/>.
</t>
<t>
There are no optional query parameters for the PUT method.
</t>
</section>

<section anchor="MultipleEdits" title="Editing Multiple Resources">
<t>
Editing multiple data resources at once can allow a client to use fewer
messages to make a configuration change.  It also allows multiple
edits to all be applied or none applied, which is not possible
if the data resources are edited one at a time.
</t>
<t>
It is easy to add multiple entries at once.  The "PATCH" method can be used
to simply patch the parent node(s) of the data resources to be added.
If multiple top-level data resources need to be added, then the
data-store itself ('/mg') can be patched.
</t>
<t>
If other operations need to be performed, or multiple operations
need to be performed at once, then the YANG Patch  <xref target="I-D.ietf-netconf-yang-patch"/>
media type can be used with the PATCH method.
A YANG patch is an ordered list of edits on the target resource,
which can be a specific data node instance, or the data-store itself.
The resource type used by
YANG Patch is 'application/yang.patch'.  A status message is returned in the
response, using resource type 'application/yang.patch.status'.
</t>
<t>
The following YANG tree diagram describes the YANG Patch structure,
Each 'edit' list entry has its own operation, sub-resource target,
and new value (if needed).
</t>

 <figure>
    <artwork align="left"><![CDATA[

  +--rw yang-patch
      +--rw patch-id?   string
      +--rw comment?    string
      +--rw edit* [edit-id]
         +--rw edit-id      string
         +--rw operation    enumeration
         +--rw target       target-resource-offset
         +--rw point?       target-resource-offset
         +--rw where?       enumeration
         +--rw value        

]]></artwork>
    </figure>

<t>
The YANG Hash values for the YANG Patch request objects are calculated as follows:
</t>

 <figure>
    <artwork align="left"><![CDATA[

0b346308: /ypatch:yang-patch
29988080: /ypatch:yang-patch/ypatch:patch-id
0c258737: /ypatch:yang-patch/ypatch:comment
316beed6: /ypatch:yang-patch/ypatch:edit
2f51f9f7: /ypatch:yang-patch/ypatch:edit/ypatch:edit-id
28f4669e: /ypatch:yang-patch/ypatch:edit/ypatch:operation
2cb909c9: /ypatch:yang-patch/ypatch:edit/ypatch:target
387d0cd8: /ypatch:yang-patch/ypatch:edit/ypatch:point
21899571: /ypatch:yang-patch/ypatch:edit/ypatch:where
1d86d302: /ypatch:yang-patch/ypatch:edit/ypatch:value

]]></artwork>
    </figure>

<t>
Refer to <xref target="I-D.ietf-netconf-yang-patch"/> for more details on
the YANG Patch request and response contents.
</t>

</section>

</section>   <!-- Edit Operations -->


<section anchor="Notify" title="Notify functions">
<t>
Notification by the server to a selection of clients when an event occurs in the server is an essential function for the management of servers. CoMI allows events specified in YANG <xref target="RFC5277"/> to be notified to a selection of requesting clients. There is one, so-called "default", stream in a CoMI server. The /mg/stream resource identifies the default stream. When a CoMI server generates an internal event, it is appended to the default stream, and the contents of a notification instance is ready to be sent to all CoMI clients which observe the default stream resource.
</t><t>
Reception of generated notification instances is enabled with the CoAP Observe <xref target="I-D.ietf-core-observe"/> function.
 The client subscribes to the notifications by sending a GET request with an "Observe" option, specifying the /mg/stream resource.
</t><t>
Every time an event is generated, the default stream is cleared, and the generated notification instance is appended to the stream. After appending the instance, the contents of the instance is sent to all observing clients. 
</t><t>
Suppose the server generates the event specified with:

</t>
 <figure>
    <artwork align="left"><![CDATA[

module example-port {
  ...
  prefix ep;
  ...
  notification example-port-fault {
    description
      "Event generated if a hardware fault on a
       line card port is detected";
    leaf port-name {
      type string;
      description "Port name";
    }
    leaf port-fault {
      type string;
      description "Error condition detected";
    }
  }
}

}]]></artwork>
    </figure>

<t>
The YANG Hash values for this notification are assigned as follows:
</t>

 <figure>
    <artwork align="left"><![CDATA[

1eed4674: /ep:example-port-fault
0cec9c71: /ep:example-port-fault/ep:port-name
228d3fa1: /ep:example-port-fault/ep:fault

}]]></artwork>
    </figure>

<t>
By executing a GET on the /mg/stream resource the client receives the following response:
</t>

 <figure>
    <artwork align="left"><![CDATA[

REQ: GET example.com/mg/stream
    (observe option register)

RES: 2.05 Content (Content-Format: application/cbor)
{
   "example-port-fault" : {
      "port-name" : "0/4/21",
      "port-fault" : "Open pin 2"
   }
}

TODO: fix YANG Hash/CBOR encoding example

RES: 2.05 Content (Content-Format: application/cbor)
{
   1eed4674 : {
      cec9c71 : "0/4/21",
      228d3fa1 : "Open pin 2"
   }
}



]]></artwork>
    </figure>

<t>
In the example, the request returns a success response with the contents of the last generated event. Consecutively the server will regularly notify the client when a new event is generated. 
</t><t>
To check that the client is still alive,
the server MUST send confirmable notifications once in a while. When the client does
not confirm the notification from the server, the server will remove
the client from the list of observers <xref target="I-D.ietf-core-observe"/>.
</t><t>
  In the registration request,
  the client MAY include a "Response-To-Uri-Host" and optionally "Response-To-Uri-Port" option as defined in
  <xref target="I-D.becker-core-coap-sms-gprs"/>.
  In this case,
  the observations SHOULD be sent to the address and port indicated in these options.
  This can be useful when the client wants the managed device to send the trap information to a multicast address.
</t>
</section>

<section anchor="block" title="Use of Block">
<t>
The CoAP protocol provides reliability by acknowledging the UDP datagrams. However, when large pieces of text need to be transported the datagrams get fragmented, thus creating constraints on the resources in the client, server and intermediate routers. The block option <xref target="I-D.ietf-core-block"/> allows the transport of the total payload in individual blocks of which the size can be adapted to the underlying fragment sizes such as: (UDP datagram size ~64KiB, IPv6 MTU of 1280, IEEE 802.15.4 payload of 60-80 bytes). Each block is individually acknowledged to guarantee reliability.
</t><t>
The block size is specified as exponents of the power 2. The SZX exponent value can have 7 values ranging from 0 to 6 with associated block sizes given by 2**(SZX+4); for example SZX=0 specifies block size 16, and SZX=3 specifies block size 128.
</t><t>
The block number of the block to transmit can be specified. There are two block options: Block1 option for the request payload transported with PUT, POST or PATCH, and the block2 option for the response payload with GET. Block1 and block2 can be combined. Examples showing the use of block option in conjunction with observer options are provided in <xref target="I-D.ietf-core-block"/>.
</t><t>
Notice that the Block mechanism splits the data at fixed positions,
such that individual data fields may become fragmented.
Therefore,  assembly of multiple blocks may be required to process the complete data field.
</t>
</section>


<section anchor="discovery" title="Resource Discovery">
<t>
The presence and location of (path to) the management data are discovered by sending a GET request to "/.well-known/core" including a resource type (RT) parameter with the value "core.mg" <xref target="RFC6690"/>. Upon success, the return payload will contain the root resource of the management data. It is up to the implementation to choose its root resource, but it is recommended that the value "/mg" is used, where possible. The example below shows the discovery of the presence and location of management data.
</t>
<figure><artwork align="left"><![CDATA[

  REQ: GET /.well-known/core?rt=core.mg

  RES: 2.05 Content </mg>; rt="core.mg"
  
]]></artwork>
    </figure>

<t>
Management objects MAY be discovered with the standard CoAP resource discovery. The implementation can add the hash values of the object identifiers to /.well-known/core with rt="core.mg.data". The available objects identified by the hash values can be discovered by sending a GET request to "/.well-known/core" including a resource type (RT) parameter with the value "core.mg.data". Upon success, the return payload will contain the registered hash values and their location. 
The example below shows the discovery of the presence and location of management data.
</t>
<figure><artwork align="left"><![CDATA[

  REQ: GET /.well-known/core?rt=core.mg.data

  RES: 2.05 Content </mg/BaAiN>; rt="core.mg.data",
  </mg/CF_fA>; rt="core.mg.data"

]]></artwork>
    </figure>

<t>
Lists of hash values may become prohibitively long. It is discouraged to provide long lists of objects on discovery. Therefore, it is recommended that details about management objects are discovered following the RESTCONF protocol. The YANG module information is stored in the "ietf-yang-library" module <xref target="I-D.ietf-netconf-restconf"/>.
The resource "/mg/mod.uri" is used to retrieve the location of the YANG module library.
</t>
<t>
Since many constrained servers within a deployment are likely to be similar,
the module list can be stored locally on each server, or remotely on a different server.
</t>

<figure><artwork align="left"><![CDATA[

  Local in example.com server:

  REQ: GET example.com/mg/mod.uri

  RES: 2.05 Content (Content-Format: application/cbor)
  {
    "mod.uri" : "example.com/mg/modules"
  }


  Remote in example-remote-server:

  REQ: GET example.com/mg/mod.uri

  RES: 2.05 Content (Content-Format: application/cbor)
  {
    "moduri" : "example-remote-server.com/mg/group17/modules"
  }

]]></artwork>
    </figure>

<t>
Within the YANG module library all information about the module is stored such as: module identifier, identifier hierarchy, grouping, features and revision numbers.
</t><t>
The hash identifier is obtained as specified in <xref target="HASH-GEN"/>. When a collision occurred in the name space of the target server, a rehash is executed as explained in <xref target="REHASH-ERR"/>.
</t>

</section>


<section anchor="error" title="Error Return Codes">
<t>
The RESTCONF return status codes defined in section 6 of the RESTCONF draft are used
in CoMI error responses, except they are converted to CoAP error codes.
</t>

<t>TODO: complete RESTCONF to CoAP error code mappings</t>

<t>TODO: assign an error cpde for a rehash-error. </t>

<texttable>
  <ttcol align="left">RESTCONF Status Line</ttcol>
  <ttcol align="left">CoAP Status Code</ttcol>
  <c> 100 Continue </c>   <c> none? </c>
  <c> 200 OK </c>   <c> 2.05 </c>
  <c> 201 Created </c>   <c> 2.01 </c>
  <c> 202 Accepted </c>   <c> none? </c>
  <c> 204 No Content </c>   <c> ? </c>
  <c> 304 Not Modified </c>   <c> 2.03 </c>
  <c> 400 Bad Request </c>   <c> 4.00 </c>
  <c> 403 Forbidden </c>   <c> 4.03 </c>
  <c> 404 Not Found </c>   <c> 4.04 </c>
  <c> 405 Method Not Allowed </c>   <c> 4.05 </c>
  <c> 409 Conflict </c>   <c> none? </c>
  <c> 412 Precondition Failed </c>   <c> 4.12 </c>
  <c> 413 Request Entity Too Large </c>   <c> 4.13 </c>
  <c> 414 Request-URI Too Large </c>   <c> 4.00 </c>
  <c> 415 Unsupported Media Type </c>   <c> 4.15 </c>
  <c> 500 Internal Server Error </c>   <c> 5.00 </c>
  <c> 501 Not Implemented </c>   <c> 5.01 </c>
  <c> 503 Service Unavailable </c>   <c> 5.03 </c>
</texttable>
</section>

</section>  <!-- MG Function Set -->

<section anchor="mapping" title="Mapping YANG to CoMI payload">
<t>
A mapping for the encoding of YANG data in CBOR is necessary for the efficient
transport of management data in the CoAP payload.
Since object names may be rather long and may occur repeatedly,
CoMI allows for association of a given object path identifier string value with an integer,
called a "YANG hash".
</t>

<section anchor="HASH-GEN" title="YANG Hash Generation">
<t>
The association between string value and string number is done through a hash algorithm.
The 30 least significant bits of the "murmur3" 32-bit hash algorithm are used.
This hash algorithm is
described online at http://en.wikipedia.org/wiki/MurmurHash.
Implementation are available online, including at
https://code.google.com/p/smhasher/wiki/MurmurHash.
When converting 4 input bytes to a 32-bit integer in the hash algorithm,
the Little-Endian convention MUST be used.
</t>
<t>
The hash is generated for the string representing the object path identifier.
A canonical representation of the path identifier is used.
<list>
 <t>
   Prefix values are used on every node.
 </t>
 <t>
   The prefix values defined in the YANG module containing the data object are used
   for the path expression.  For external modules, this is the value of the 'prefix'
   sub-statement in the 'import' statement for each external module.
 </t>
<t>
  Path expressions for objects which augment data nodes in external modules are calculated
  in the augmenting module, using the prefix values in the augmenting module.
</t>
<t>
  Choice and case node names are not included in the path expression. Only 'container', 'list',
  'leaf', 'leaf-list', and 'anyxml' nodes are listed in the path expression.
</t>
</list>
</t>
<t>
The "murmur3_32" hash function is executed for the entire path string.
The value '42' is used as the seed for the hash function.
The YANG hash is subsequently calculated by taking the 30 least significant bits.
</t>
<t>
The resulting 30-bit number is used by the server, unless the value is already being
used for a different object by the server. In this case, the re-hash procedure
in the following section is executed.
</t>
</section>


<section anchor="REHASH-ERR" title="Re-Hash Error Procedure">
<t>
A hash collision occurs if two different path identifier strings have the same hash value.
If the server has over 30,000 objects in its YANG modules, then the probability
of a collision is 10% or higher.
If a hash collision occurs on the server, then the object that is causing the
conflict has to be altered, such that the new hash value does not conflict
with any value already in use by the server.
</t>
<t>
In most cases, the hash function is expected to produce unique values for all the objects
supported by a constrained device. Given a known set of YANG modules, both server and client
can calculate the YANG hashes independently, and offline.
</t>
<t>
Even though collisions are expected to happen rather rarely, they need to be considered.
Collisions can be detected before deployment, if the vendor knows which modules are supported
by the server, and hence all YANG hashes can be calculated.
Collisions are only an issue when they occur at the same server. The client needs to
discover any re-hash mappings on a per server basis.
</t>
<t>
If the server needs to re-hash any object identifiers, then it MUST create a "rehash-map"
entry for all its rehashed objects, as described in the following YANG module.
</t>
</section>

<section anchor="YANGMOD" title="ietf-yang-hash YANG Module">
<t>
The "ietf-yang-hash" YANG module is used by the server to report any objects that
have been mapped to produce a new hash value that does not conflict with any other
YANG hash values used by the server.
</t>
<t>
YANG tree diagram for "ietf-yang-hash" module:
</t>

<figure>
  <artwork align="left"><![CDATA[

  +--ro yang-hash
      +--ro rehash* [hash]
         +--ro hash      uint32
         +--ro object*
            +--ro module     string
            +--ro newhash    uint32
            +--ro pathlen?   uint32
            +--ro path?      string

]]></artwork>
 </figure>


<figure><artwork align="left"><![CDATA[

<CODE BEGINS> file "ietf-yang-hash@2015-06-06.yang"

module ietf-yang-hash {
  namespace "urn:ietf:params:xml:ns:yang:ietf-yang-hash";
  prefix "yh";

  organization
    "IETF CORE (Constrained RESTful Environments) Working Group";

  contact
    "WG Web:   <http://tools.ietf.org/wg/core/>
     WG List:  <mailto:core@ietf.org>

     WG Chair: Carsten Bormann
               <mailto:cabo@tzi.org>

     WG Chair: Andrew McGregor
               <mailto:andrewmcgr@google.com>

     Editor:   Peter van der Stok
               <mailto:consultancy@vanderstok.org>

     Editor:   Andy Bierman
               <mailto:andy@yumaworks.com>

     Editor:   Juergen Schoenwaelder
               <mailto:j.schoenwaelder@jacobs-university.de>

     Editor:   Anuj Sehgal
               <mailto:s.anuj@jacobs-university.de>";

  description
    "This module contains re-hash information for the CoMI protocol.

     Copyright (c) 2015 IETF Trust and the persons identified as
     authors of the code.  All rights reserved.

     Redistribution and use in source and binary forms, with or
     without modification, is permitted pursuant to, and subject
     to the license terms contained in, the Simplified BSD License
     set forth in Section 4.c of the IETF Trust's Legal Provisions
     Relating to IETF Documents
     (http://trustee.ietf.org/license-info).

     This version of this YANG module is part of RFC XXXX; see
     the RFC itself for full legal notices.";

  // RFC Ed.: replace XXXX with actual RFC number and remove this
  // note.

  // RFC Ed.: remove this note
  // Note: extracted from draft-vanderstok-core-comi-07.txt

  // RFC Ed.: update the date below with the date of RFC publication
  // and remove this note.
  revision 2015-06-06 {
    description
      "Initial revision.";
    reference
      "RFC XXXX: CoMI Protocol.";
  }

  container yang-hash {
    config false;
    description
      "Contains information on the YANG Hash values used by
       the server.";

    list rehash {
      key hash;
      description
        "Each entry describes an re-hash mapping in use by
         the server.";

      leaf hash {
        type uint32;
        description 
          "The hash value that has a collision.  This hash value
           cannot be used on the server.  The rehashed
           value for each affected object must be used instead.";
      }

      list object {
        min-elements 2;

        description
          "Each entry identifies one of the objects involved in the
           hash collision and contains the rehash information for
           that object.";

        leaf module {
          type string;
          mandatory true;
          description
            "The module name for this object.";
        }

        leaf newhash {
          type uint32;
          mandatory true;
          description
            "The new hash value for this object.";
        }

        leaf pathlen {
          type uint32;
          description
            "The length of the path expression of the object with
             this hash value.  This object MUST be included
             for any objects in the rehash entry with the
             same 'module' value.";
        }

        leaf path {
          type string;
          description
            "The path expression of the object with
             this hash value. This object MUST be included
             for any objects in the rehash entry with the
             same 'module' and 'pathlen' values.";
        }

      }
    }
  }
}

<CODE ENDS>

]]></artwork>
    </figure>

</section>   <!-- YANG Module  -->

<section anchor="rehashExamples" title="YANG Re-Hash Examples">
<t>
In this example there are three YANG modules, "foo", "bar", and
"bar1".
</t>

<figure>
  <artwork align="left"><![CDATA[

module foo {
  namespace "http://example.com/ns/foo";
  prefix "f";
  revision 2015-06-07;

  container A {
    list B {
      key name;
      leaf name { type string; }
      leaf col1 { type int32; }
      leaf counter1 { type uint32; }
    }
  }
}

module bar {
  namespace "http://example.com/ns/bar";
  prefix "b";
  revision 2015-06-07;

  leaf bar { type string; }
}

module bar1 {
  namespace "http://example.com/ns/bar1";
  prefix "b1";
  import foo { prefix f; }
  revision 2015-06-07;

  augment /f:A/f:B {
    leaf bar1 { type string; }
  }
}

]]></artwork>
 </figure>

<t>
This set of 3 YANG modules containing a total of 7 objects
produces the following object list.
Note that actual hash values are not shown,
since these modules do not actually cause the YANG Hash
clashes described in the examples.
</t>

<figure>
  <artwork align="left"><![CDATA[

   Object    Path               Hash

foo:

   container /f:A                h1
   list      /f:A/f:B            h2
   leaf      /f:A/f:B/f:name     h3
   leaf      /f:A/f:B/f:col1     h4
   leaf      /f:A/f:B/f:counter1 h5

bar:

   leaf      /b:bar              h6

bar1:

  leaf      /f:A/f:B/b1:bar1     h7

]]></artwork>
 </figure>

<section anchor="rehash-multimod" title="Multiple Modules">
<t>
In this example, assume that the following 3 objects produce
the same hash value, so 'h3', 'h6', and 'h7' have the same value (e.g. '1234'):
</t>
<t>
The client might retrieve the container "/f:A" which
could cause its sub-nodes to be returned.
Instead, the server will return a message with
the resource type "core.mg.", representing the "yang-hash"
data structure.
</t>


 <figure>
    <artwork align="left"><![CDATA[

REQ: GET example.com/mg/h1

RES: 4.00 "Bad Request" (Content-Format: application/cbor)
{
   "ietf-yang-hash:yang-hash" : {
     "rehash" : [
        {
          "hash" : 1234,
           "object" : [
             {
               "module" : "foo",
               "newhash" : 5678
             },
             {
               "module" : "bar",
               "newhash" : 3579
             },
             {
               "module" : "bar1",
               "newhash" : 8182
             }
           ]
        }
     ]
  }
}

]]></artwork>
 </figure>

</section>


<section anchor="rehash-same-mod2-example" title="Same Module">
<t>
In this example, assume that the following 4 objects produce
the same hash value, so 'h3', 'h5', 'h6', and 'h7' 
all have the same value (e.g. '1234'):
</t>
<t>
The client might retrieve the list "/f:A/f:B" which
would cause its sub-nodes to be returned.
Instead, the server will return a message with
the resource type "core.mg.yanh-hash", representing the "yang-hash"
data structure.  Note that the "pathlen" field
is not needed for the 'h6' and 'h7' objects.
</t>

 <figure>
    <artwork align="left"><![CDATA[

REQ: GET example.com/mg/h2?keys="entry1"

RES: 4.00 "Bad Request" (Content-Format: application/cbor)
{
   "ietf-yang-hash:yang-hash" : {
     "rehash" : [
        {
          "hash" : 1234,
           "object" : [
             {
               "module" : "foo",
               "newhash" : 5678,
               "pathlen" : 15
             },
             {
               "module" : "foo",
               "newhash" : 7863,
               "pathlen" : 19
             },
             {
               "module" : "bar",
               "newhash" : 3579
             },
             {
               "module" : "bar1",
               "newhash" : 8182
             }
           ]
        }
     ]
  }
}

]]></artwork>
 </figure>
</section>

<section anchor="rehash-same-mod3-example" title="Same Module and Same Path Length">

<t>
In this example, assume that the following 5 objects produce
the same hash value, so 'h3', 'h4', 'h5', 'h6', and 'h7' 
all have the same value (e.g. '1234'):
</t>
<t>
The client might retrieve the list "/f:A/f:B" which
would cause its sub-nodes to be returned.
Instead, the server will return a message with
the resource type "core.mg.yang-hash", representing the "yang-hash"
data structure.  The "path" leaf is included 2 entries
because the "module" and "pathlen" values are the same for the objects.
</t>

 <figure>
    <artwork align="left"><![CDATA[

REQ: GET example.com/mg/h2?keys="entry2"

RES: 4.00 "Bad Request" (Content-Format: application/cbor)
{
   "ietf-yang-hash:yang-hash" : {
     "rehash" : [
        {
          "hash" : 1234,
           "object" : [
             {
               "module" : "foo",
               "newhash" : 5678,
               "pathlen" : 15,
               "path" : "/f:A/f:B/f:name"
             },
             {
               "module" : "foo",
               "newhash" : 7863,
               "pathlen" : 15,
               "path" : "/f:A/f:B/f:col1"
             },
             {
               "module" : "foo",
               "newhash" : 9172,
               "pathlen" : 19
             },
             {
               "module" : "bar",
               "newhash" : 3579
             },
             {
               "module" : "bar1",
               "newhash" : 8182
             }
           ]
        }
     ]
  }
}

]]></artwork>
 </figure>

</section>

</section>  <!-- YANG re_hash examples -->


<section title="YANG Hash in URL" anchor="base64url">
  <t>
    When a URL contains a YANG hash, it is encoded using base64url "URL and Filename safe" 
encoding as specified in <xref target="RFC4648"/>.
  </t>
  <t>
    The hash H is represented as a 30-bit integer,
    divided into five 6-bit integers as follows:
  </t>
<figure><artwork align="left"><![CDATA[
B1 = (H & 0x3f000000) >> 24
B2 = (H & 0xfc0000) >> 18
B3 = (H & 0x03f000) >> 12
B4 = (H & 0x000fc0) >> 6
B5 =  H & 0x00003f
]]></artwork></figure>
  <t>
    Subsequently,
    each 6-bit integer Bx is translated into a character Cx using
Table 2 from <xref target="RFC4648"/>,
    and a string is formed by concatenating the characters in the
order C1, C2, C3, C4, C5.
  </t>
  <t>
    For example,
    the YANG hash 0x29abdcca is encoded as "pq9zK".
  </t>
</section> <!-- YANG hash in URL  -->


</section>  <!-- Mapping YANG to CoMI Payload -->

<section anchor="CBOR-mapping" title="Mapping YANG to CBOR">

  <section title="High level encoding">
    <t>
      When encoding YANG variables in CBOR,
      the CBOR encodings entry is a map.
      The key is the YANG hash of entry variable,
      whereas the value contains its value.
    </t>
    <t>
      For encoding of the variable values,
      a CBOR datatype is used.
      <xref target="YANGtoCBOR"/> provides the mapping between YANG datatypes and CBOR datatypes.
    </t>
  </section>

  <section anchor="YANGtoCBOR" title="Conversion from YANG datatypes to CBOR datatypes">
    <t>
      <xref target="YANG-CBOR"/> defines the mapping between YANG datatypes and CBOR datatypes.
    </t>
    <t>    
      Elements of types not in this table,
      and of which the type cannot be inferred from a type in this table,
      are ignored in the CBOR encoding by default.
      Examples include the "description" and "key" elements.
      However, conversion rules for some elements to CBOR MAY be defined elsewhere.
    </t>
  <texttable anchor="YANG-CBOR" title="Conversion of YANG datatypes to CBOR">
    <ttcol align="left">YANG type</ttcol>
    <ttcol align="left">CBOR type</ttcol>
    <ttcol align="left">Specification</ttcol>
    
    <c>int8, int16, int32, int64, uint16, uint32, uint64, decimal64</c>
    <c>unsigned int (major type 0) or negative int (mayor type 1)</c>
    <c>The CBOR integer type depends on the sign of the actual value.</c>
    
    <c>boolean</c>
    <c>either "true" (major type 7, simple value 21) or "false" (major type 7, simple value 20)</c>
    <c></c>
    
    <c>string</c>
    <c>text string (major type 3)</c>
    <c></c>
    
    <c>enumeration</c>
    <c>unsigned int (major type 0)</c>
    <c></c>
    
    <c>bits</c>
    <c>array of text strings</c>
    <c>Each text string contains the name of a bit value that is set.</c>
    
    <c>binary</c>
    <c>byte string (major type 2)</c>
    <c></c>
    
    <c>empty</c>
    <c>null (major type 7, simple value 22)</c>
    <c>TBD: This MAY not be applicable to true MIBs, as SNMP may not support empty variables...</c>
    
    <c>union</c>
    <c></c>
    <c>
      Similar to the JSON transcription from <xref target="I-D.ietf-netmod-yang-json"/>,
      the elements in a union MUST be determined using the procedure specified in section 9.12 of <xref target="RFC6020"/>.
    </c>
   
    <c>leaf-list</c>
    <c>array (major type 4)</c>
    <c>The array is encapsulated in the map associated with the YANG variable.</c>
    
    <c>list</c>
    <c>array (major type 4) of maps (major type 5)</c>
    <c>      
      Each array element contains a map of associated YANG hash - value pairs.
    </c>
    
    <c>container</c>
    <c>map (major type 5)</c>
    <c>The map contains YANG hash - value pairs corresponding to the elements in the container.</c>
    
    <c>smiv2:oid</c>
    <c>array of integers</c>
    <c>
      Each integer contains an element of the OID,
      the first integer in the array corresponds to the most left element in the OID.
    </c>


  </texttable>    
  </section>
  </section>


<section anchor="ERRORS" title="Error Handling">
  <t>
    In case a request is received which cannot be processed properly,
    the managed entity MUST return an error message.
    This error message MUST contain a CoAP 4.xx or 5.xx response code,
    and SHOULD include additional information in the payload.
  </t>
  <t>
    Such an error message payload is encoded in CBOR,
    using the following structure:
  </t>
  <t>
    TODO: Adapt RESTCONF &lt;errors&gt; data structure for use in CoMI. Need
    to select the most important fields like &lt;error-path&gt;.
  </t>

<figure><artwork align="left">
<![CDATA[
errorMsg     : ErrorMsg;

*ErrorMsg {
  errorCode  : uint;
  ?errorText : tstr;
}
]]></artwork></figure>
  <t>
    The variable "errorCode" has one of the values from the table below,
    and the OPTIONAL "errorText" field contains a human readable explanation of the error.
  </t>
  
    <texttable>
      <ttcol align="left">CoMI Error Code</ttcol>
      <ttcol align="left">CoAP Error Code</ttcol>
      <ttcol align="left">Description</ttcol>
      
      <c>0</c>
      <c>4.00</c>
      <c>General error</c>

      <c>1</c>
      <c>4.00</c>
      <c>Malformed CBOR data</c>
      
      <c>2</c>
      <c>4.00</c>
      <c>Incorrect CBOR datatype</c>
      
      <c>3</c>
      <c>4.00</c>
      <c>Unknown MIB variable</c>
      
      <c>4</c>
      <c>4.00</c>
      <c>Unknown conversion table</c>

      <c>5</c>
      <c>4.05</c>
      <c>Attempt to write read-only variable</c>

  	<c>0..2</c>
      <c>5.01</c>
      <c>Access exceptions</c>

	<c>0..18</c>
	<c>5.00</c>
	<c> SMI error status </c>
    </texttable>

<t>
The CoAP error code 5.01 is associated with the exceptions defined in <xref target="RFC3416"/> and CoAP error code 5.00 is associated with the error-status defined in <xref target="RFC3416"/>.
</t>
  
</section>

<section title="Security Considerations">
  <t>
    For secure network management,
    it is important to restrict access to MIB variables only to authorised parties.
    This requires integrity protection of both requests and responses,
    and depending on the application encryption.
  </t>
  <t>
    CoMI re-uses the security mechanisms already available to CoAP as much as possible.
    This includes DTLS <xref target="RFC6347"/> for protected access to resources,
    as well suitable authentication and authorisation mechanisms.
  </t>
  <t>
    Among the security decisions that need to be made are
    selecting security modes and encryption mechanisms (see <xref target="RFC7252"/>).
    This requires a trade-off,
    as the NoKey mode gives no protection at all,
    but is easy to implement,
    whereas the X.509 mode is quite secure, 
    but may be too complex for constrained devices.
  </t>
  <t>
    In addition,
    mechanisms for authentication and authorisation may need to be selected.
  </t>
  <t>
    CoMI avoids defining new security mechanisms as much as possible.
    However some adaptations may still be required,
    to cater for CoMI's specific requirements.
  </t>
</section>

<section  title="IANA Considerations">  
  <t>
    'rt="core.mg.data"' needs registration with IANA.
  </t>
  <t>
    'rt="core.mg.moduri"' needs registration with IANA.
  </t>
   <t>
    'rt="core.mg.modset"' needs registration with IANA.
  </t>
  <t>
    'rt="core.mg.yang-hash"' needs registration with IANA.
  </t>
   <t>
    'rt="core.mg.yang-stream"' needs registration with IANA.
  </t>
  <t>
    Content types to be registered:
    <list style="symbols">
      <t>application/comi+cbor</t>
    </list>
  </t>
</section>

<section title="Acknowledgements">
<t>
We are very grateful to Bert Greevenbosch who was one of the original authors of the CoMI specification and specified CBOR encoding and use of hashes.
Mehmet Ersue and Bert Wijnen explained the encoding aspects of PDUs transported under SNMP. Carsten Bormann has given feedback on the use of CBOR.
The draft has benefited from comments (alphabetical order) by Dee Denteneer, Esko Dijk, Michael van Hartskamp, Zach Shelby, Michel Veillette, Michael Verschoor, and Thomas Watteyne.
The CBOR encoding borrows extensively from Ladislav Lhotka's description on conversion from YANG to JSON.
</t><t>
This material is based upon work supported by Philips Research, Huawei, and The Space &amp; Terrestrial Communications Directorate (S&amp;TCD); the latter under Contract No. W15P7T-13-C-A616. Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of Philips Research, Huawei, or The Space &amp; Terrestrial Communications Directorate (S&amp;TCD).
</t><t>
Juergen Schoenwaelder and Anuj Sehgal were partly funded by Flamingo,
a Network of Excellence project (ICT-318488) supported by the
European Commission under its Seventh Framework Programme.

</t>
</section>

<section title="Changelog">
<t>
Changes from version 00 to version 01
<list style="symbols">
<t> Focus on MIB only</t>
<t> Introduced CBOR, JSON, removed BER </t>
<t> defined mappings from SMI to xx </t>
<t> Introduced the concept of addressable table rows </t>
</list>
</t>
<t>
Changes from version 01 to version 02
<list style="symbols">
<t> Focus on CBOR, used JSON for examples, removed XML and EXI</t>
<t> added uri-query attributes mod and con to specify modules and contexts </t>
<t> Definition of CBOR string conversion tables for data reduction </t>
<t> use of Block for multiple fragments </t>
<t> Error returns generalized </t>
<t> SMI - YANG - CBOR conversion </t>
</list>
</t>
<t>
Changes from version 02 to version 03
<list style="symbols">
<t> Added security considerations</t>
</list>
</t>
<t>
Changes from version 03 to version 04
<list style="symbols">
<t> Added design considerations section</t>
<t> Extended comparison of management protocols in introduction </t>
<t> Added automatic generation of CBOR tables </t>
<t> Moved lowpan table to Appendix </t>
</list>
Changes from version 04 to version 05
<list style="symbols">
<t> Merged SNMP access with RESTCONF access to management objects in small devices </t>
<t> Added CoMI architecture section</t>
<t> Added RESTCONf NETMOD description </t>
<t> Rewrote section 5 with YANG examples </t>
<t> Added server and payload size appendix</t>
<t> Removed Appendix C for now. It will be replaced with a YANG example. </t>
</list>
Changes from version 04 to version 05
<list style="symbols">
<t> Extended examples with hash representation </t>
<t> Added keys query parameter text</t>
<t> Added select query parameter text </t>
<t> Better separation between specification and instance </t>
<t> Section on discovery updated</t>
<t> Text on rehashing introduced </t>
<t> Elaborated SMI MIB example </t>
<t> Yang libary use described </t>
<t> use of BigEndian/LittleEndian in Hash generation specified </t>
</list>
Changes from version 05 to version 06
<list style="symbols">
<t> Hash values in payload as hexadecimal and in URL in base64 numbers </t>
<t> Streamlined CoMI architecture text</t>
<t> Added select query parameter text </t>
<t> Data editing optional </t>
<t> Text on Notify added</t>
<t> Text on rehashing improved with example </t>
</list>
Changes from version 06 to version 07
<list style="symbols">
<t> reduced payload size by removing JSON hierachy </t>
<t> changed rehash handling to support small clients </t>
<t> added LWM2M comparison </t>
<t> Notification handling as specified in YANG </t>
<t> Added Patch function </t>
<t> Rehashing completely reviewed </t>
<t> Discover type of YANG name encoding </t>
<t> Added new resource types </t>
<t> Read-only servers introduced </t>
<t> Multiple updates explained </t>
</list>

</t>

</section>

</middle>
  <back>
    <references title="Normative References">
      &RFC2119;
	 &RFC4648;
	&RFC5277;
      &RFC6020;
      &RFC7049;
      &RFC7159;
      &RFC7252;
      &I-D.becker-core-coap-sms-gprs;
      &I-D.ietf-core-block;
      &I-D.ietf-core-observe;
      &I-D.ietf-netmod-yang-json;
      &I-D.ietf-netconf-restconf;
	 &I-D.vanderstok-core-patch;
    </references>
    <references title="Informative References">
      &RFC2578;
      &RFC3410;
      &RFC3411;
      &RFC3414;
      &RFC3416;
      &RFC3418;
      &RFC4293;
      &RFC4944;
      &RFC6241;
      &RFC6347;
      &RFC6643;
      &RFC6650;
      &RFC6690;
      &RFC6775;
	&RFC7223;
      &RFC7228;            
      &RFC7317;            
      &I-D.ietf-core-interfaces;
      &I-D.ersue-constrained-mgmt;

	&I-D.ietf-lwig-coap;

       
  <reference anchor="XML">
        <front>
          <title>Extensible Markup Language (XML)</title>
        <author />
        <date />
          </front>
          <seriesInfo name="Web" value="http://www.w3.org/xml"/>
        </reference>

  <reference anchor="OMA">
        <front>
          <title>OMA-TS-LightweightM2M-V1_0-20131210-C</title>
	  <author fullname="Open Mobile Alliance (OMA)"/>
        <date />
          </front>
          <seriesInfo name="Web" value="http://technical.openmobilealliance.org/Technical/current_releases.aspx"/>
        </reference>


  <reference anchor="DTLS-size">
        <front>
          <title>Delegation-based Authentication and Authorization for the IP-based Internet of Things</title>
<author fullname="R.Hummen" initials="R." surname="Hummen"/>
<author fullname="H.Shafagh" initials="H." surname="Shafagh"/>
<author fullname="S.Raza" initials="S." surname="Raza"/>
<author fullname="T.Voigt" initials="T." surname="Voigt"/>
<author fullname="K.Wehrle" initials="K." surname="Wehrle"/>
        <date />
          </front>
          <seriesInfo name="Web" value="http://www.vs.inf.ethz.ch/publ/papers/mshafagh_secon14.pdf"/>
        </reference>


<reference anchor="dcaf">
        <front>
          <title>Delegated Authenticated Authorization for
Constrained Environments </title>
        <author fullname="Carsten Bormann" initials="C." surname="Bormann"/>
        <author fullname="Olaf Bergmann" initials="O." surname="Bergmann"/>
        <author fullname="Stefanie Gerdes" initials="S." surname="Gerdes"/>
        <date />
          </front>
          <seriesInfo name="Private Information" value=""/>
        </reference>

<reference anchor="openwsn">
        <front>
          <title>Coap size in Openwsn
</title>
        <author fullname="Thomas Watteijne" initials="T." surname="Watteijne"/>
        <date />
          </front>
          <seriesInfo name="Web" value="http://builder.openwsn.org/" />
        </reference>


<reference anchor="Erbium">
        <front>
          <title>Erbium Memory footprint for coap-18</title>
        <author fullname="Matthias Kovatsch" initials="M." surname="Kovatsch"/>
        <date />
          </front>
          <seriesInfo name="Private Communication" value=""/>
        </reference>

  <reference anchor="management">
        <front>
          <title>Management of the Internet of Things</title>
        <author fullname="Juergen Schoenwalder" initials="J." surname="Schoenwalder"/>
<author fullname="Anuj Sehgal" initials="A." surname="Sehgal"/>
        <date year="2013"/>
          </front>
          <seriesInfo name="Web" value="http://cnds.eecs.jacobs-university.de/slides/2013-im-iot-management.pdf"/>
        </reference>


<reference anchor="I-D.ietf-netconf-yang-patch">
<front>
<title>YANG Patch Media Type</title>
<author initials="A" surname="Bierman" fullname="Andy Bierman">
<organization/>
</author>
<author initials="M" surname="Bjorklund" fullname="Martin Bjorklund">
<organization/>
</author>
<author initials="K" surname="Watsen" fullname="Kent Watsen">
<organization/>
</author>
<date month="June" day="4" year="2015"/>
<abstract>
<t>
This document describes a method for applying patches to NETCONF data-stores using data defined with the YANG data modeling language.
</t>
</abstract>
</front>
<seriesInfo name="Internet-Draft" value="draft-ietf-netconf-yang-patch-04"/>
<format type="TXT" target="http://www.ietf.org/internet-drafts/draft-ietf-netconf-yang-patch-04.txt"/>
</reference>


    </references>

<section title="Payload and Server sizes" anchor="code-sizes">
<t>
This section provides information on code sizes and payload sizes for a set of management servers. Approximate code sizes are:
</t>
  <texttable>
  <ttcol align="left">Code</ttcol>
  <ttcol align="left">processor</ttcol>
   <ttcol align="left">Text</ttcol>
  <ttcol align="left">Data</ttcol>
  <ttcol align="left">reference</ttcol>

  <c> Observe agent</c>   <c> erbium </c> <c> 800 </c> <c> n/a </c> <c> <xref target="Erbium"/> </c>
  <c> CoAP server     </c>   <c> MSP430 </c> <c> 1K </c> <c> 6 </c> <c> <xref target="openwsn"/> </c>
<c> SNMP server </c>   <c> ATmega128 </c> <c> 9K </c> <c> 700 </c> <c> <xref target="management"/> </c>
<c> Secure SNMP </c>   <c> ATmega128</c> <c> 30K </c> <c> 1.5K </c> <c> <xref target="management"/>  </c>
<c> DTLS server </c>   <c> ATmega128</c> <c> 37K </c> <c> 2K </c> <c> <xref target="management"/>  </c>
<c> NETCONF </c>   <c> ATmega128</c> <c> 23K </c> <c> 627 </c> <c> <xref target="management"/>  </c>
<c> JSON parser </c>   <c> CC2538</c> <c> 4.6K </c> <c> 8 </c> <c> <xref target="dcaf"/> </c>
<c> CBOR parser </c>   <c> CC2538</c> <c> 1.5K </c> <c> 2.6K </c> <c> <xref target="dcaf"/> </c>
<c> DTLS server </c>   <c> ARM7</c> <c> 15K </c> <c> 4 </c> <c> <xref target="I-D.ietf-lwig-coap"/> </c>
<c> DTLS server </c>   <c> MSP430</c> <c> 15K </c> <c> 4 </c> <c><xref target="DTLS-size"/> </c>
<c> Certificate </c>   <c> MSP430</c> <c> 23K </c> <c>  </c> <c> <xref target="DTLS-size"/>  </c>
<c> Crypto </c>   <c> MSP430</c> <c> 2-8K </c> <c>  </c> <c> <xref target="DTLS-size"/>  </c>
</texttable>
<t>
Thomas says that the size of the CoAP server is rather arbitrary, as its size depends mostly on the implementation of the underlying library modules and interfaces. 
</t><t>
Payload sizes are compared for the following request payloads, where each attribute value is null (N.B. these sizes are educated guesses, will be replaced with generated data). The identifier are assumed to be a string representation of the OID. Sizes for SysUpTime differ due to preambles of payload. "CBOR opt" stands for CBOR payload where the strings are replaced by table numbers.
</t>
  <texttable>
  <ttcol align="left">Request</ttcol>
  <ttcol align="left">BERR SNMP</ttcol>
   <ttcol align="left">JSON</ttcol>
  <ttcol align="left">CBOR</ttcol>
  <ttcol align="left">CBOR opt</ttcol>

  <c> IPnetTOMediaTable</c>   <c> 205 </c> <c> 327 </c> <c> ~327</c> <c> ~51 </c>
  <c> lowpanIfStatsTable     </c>   <c>  </c> <c> 710 </c> <c> 614 </c> <c> 121 </c>
<c> sysUpTime </c>   <c> 29 </c> <c> 13 </c> <c> ~13 </c> <c> 20 </c>
<c> RESTCONF example </c>   <c> </c> <c> </c> <c>  </c> <c> </c>
</texttable>

</section>


<section title="Notational Convention for CBOR data" anchor="notConv">
  <t>
    To express CBOR structures <xref target="RFC7049"/>,
    this document uses the following conventions:
  </t>
  <t>
    A declaration of a CBOR variable has the form:
<figure><artwork align="left"><![CDATA[
   name : datatype;
]]></artwork></figure>
    where "name" is the name of the variable,
    and "datatype" its CBOR datatype.
  </t>
  <t>
    The name of the variable has no encoding in the CBOR data.
  </t>
  <t>
    "datatype" can be a CBOR primitive such as:
    <list style="hanging">    
      <t hangText="tstr:">A text string (major type 3)</t>
      <t hangText="uint:">An unsigned integer (major type 0)</t>
      <t hangText="map(x,y):">
        A map (major type 5), where each first element of a pair is of datatype x, and each second element of datatype y.
        A '.' character for either x or y means that all datatypes for that element are valid.
      </t>
    </list>
  </t>
  <t>
    A datatype can also be a CBOR structure,
    in which case the variable's "datatype" field contains the name of the CBOR structure.
    Such CBOR structure is defined by a character sequence consisting of first its name,
    then a '{' character,
    then its subfields
    and finally a '}' character.
  </t>
  <t>
    A CBOR structure can be encapsulated in an array,
    in which case its name in its definition is preceded by a '*' character.
    Otherwise the structure is just a grouping of fields,
    but without actual encoding of such grouping.
  </t>
  <t>
    The name of an optional field is preceded by a '?' character.
    This means,
    that the field may be omitted if not required.
  </t>
</section>

<section anchor="LWM2M" title="comparison with LWM2M">
  <t>
    CoMI and LWM2M, both, provide RESTful device management services
    over CoAP. Differences between the
    designs are highlighted in this section.
  </t>
  <t>
    Unlike CoMI, which enables the use of SMIv2 and YANG data models
    for device management, LWM2M defines a new object resource
    model. This means that data models need to be redefined in order
    to use LWM2M. In contrast, CoMI provides access to a large variety of
    SMIv2 and YANG data modules that can be used immediately.
  </t>
  <t>
    Objects and resources within CoMI are identified with a YANG hash
    value, however, each object is described as a link in the CoRE
    Link Format by LWM2M. This approach by LWM2M can lead to larger
    complex URIs and more importantly payloads can grow large in
    size. Using a hash value to represent the objects and resources
    allows URIs and payloads to be smaller in size, which is important
    for constrained devices that may not have enough resources to
    process large messages.
  </t>
  <t>
    LWM2M encodes payload data in Type-length-value (TLV), JSON or
    plain text formats. While the TLV encoding is binary and can
    result in reduced message sizes, JSON and plain text are likely to
    result in large message sizes when lots of resources are being
    monitored or configured. Furthermore, CoMI's use of CBOR gives it
    an advantage over the LWM2M's TLV encoding as well since this too
    is more efficient [citation needed].
  </t>
  <t>
    CoMI is aligned with RESTCONF for constrained devices and uses YANG data models that have objects containing resources
    organized in a tree-like structure. On the other hand, LWM2M uses
    a very flat data model that follows the "object/instance/resouce"
    format, with no possibility to have subresouces. Complex data
    models are, as such, harder to model with LWM2M.
  </t>
  <t>
    In situations where resources need to be modified, CoMI uses the
    CoAP PATCH operation when resources are modified partially. However, LWM2M
    uses the CoAP PUT and POST operations, even when a subset of the resource
    needs modifications.
  </t>
</section>


  </back>

</rfc>
