Thing-to-Thing Research Group (T2TRG) L. Toutain Internet-Draft IMT Atlantique Intended status: Informational 16 September 2026 Expires: 20 March 2027 CORECONF for Machine-to-Machine Communication draft-toutain-t2trg-coreconf-m2m-01 Abstract The document addresses the specific challenges of M2M interactions where both endpoints may be constrained nodes, and explores the use of CORECONF primitives. This document describes the use of CORECONF (CoAP Management Interface) for Machine-to-Machine (M2M) communication in constrained IoT environments. It defines a YANG data model enabling remote management and configuration of constrained devices using CoAP, CBOR, and YANG SID identifiers. The serialization in CBOR of this data model limits the payload size. It documents also how the YANG data model can interact with common IoT ontologies such as SOSA or SAREF. The same CORECONF/SID serialization also enables full interoperability between constrained devices and AI agents, by exposing device actions and data through an MCP (Model Context Protocol) server without requiring an intermediate, device-specific translation layer. About This Document This note is to be removed before publishing as an RFC. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-toutain-t2trg-coreconf-m2m/. Discussion of this document takes place on the T2TRG Research Group mailing list (mailto:t2trg@irtf.org), which is archived at https://mailarchive.ietf.org/arch/browse/t2trg/. Subscribe at https://www.ietf.org/mailman/listinfo/t2trg/. Source for this draft and an issue tracker can be found at https://github.com/ltn22/coreconf-m2m. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Toutain Expires 20 March 2027 [Page 1] Internet-Draft coreconf-m2m September 2026 Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 20 March 2027. Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1. Use Cases . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2. Data Representation . . . . . . . . . . . . . . . . . . . 6 1.3. Requirements Language . . . . . . . . . . . . . . . . . . 7 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 7 3. YANG Modules needed for coreconf-m2m . . . . . . . . . . . . 7 3.1. Identities Data Model . . . . . . . . . . . . . . . . . . 8 3.2. Overview of the coreconf-m2m Module . . . . . . . . . . . 8 3.2.1. Bootstrap Sub-Tree . . . . . . . . . . . . . . . . . 9 3.2.2. Characteristics Sub-Tree . . . . . . . . . . . . . . 10 3.2.3. Transducer Sub-Tree . . . . . . . . . . . . . . . . . 11 3.3. Notifications . . . . . . . . . . . . . . . . . . . . . . 14 4. CORECONF Overview in the M2M Context . . . . . . . . . . . . 15 4.1. CoAP Methods Mapping . . . . . . . . . . . . . . . . . . 15 4.2. SID Allocations . . . . . . . . . . . . . . . . . . . . . 16 5. CORECONF Traffic . . . . . . . . . . . . . . . . . . . . . . 16 5.1. Resource Discovery . . . . . . . . . . . . . . . . . . . 16 5.2. Querying a quantity . . . . . . . . . . . . . . . . . . . 19 5.3. Notification . . . . . . . . . . . . . . . . . . . . . . 20 6. From CBOR/SID to Textual Identifiers . . . . . . . . . . . . 23 7. Interconnection with an Ontology . . . . . . . . . . . . . . 24 7.1. Extending Ontology to coreconf-m2m . . . . . . . . . . . 24 7.2. SOSA . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Toutain Expires 20 March 2027 [Page 2] Internet-Draft coreconf-m2m September 2026 7.2.1. Instantiating from YANG . . . . . . . . . . . . . . . 26 7.2.2. Control . . . . . . . . . . . . . . . . . . . . . . . 28 7.2.3. Storing Transducer Quantities . . . . . . . . . . . . 30 7.2.4. Storing Actuator Commands . . . . . . . . . . . . . . 31 7.3. SensorThings . . . . . . . . . . . . . . . . . . . . . . 33 7.3.1. Example . . . . . . . . . . . . . . . . . . . . . . . 33 7.4. SAREF . . . . . . . . . . . . . . . . . . . . . . . . . . 38 8. MCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 9. Compression . . . . . . . . . . . . . . . . . . . . . . . . . 41 9.1. SID translation . . . . . . . . . . . . . . . . . . . . . 41 9.2. SCHC . . . . . . . . . . . . . . . . . . . . . . . . . . 42 10. Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . 42 11. Security Considerations . . . . . . . . . . . . . . . . . . . 43 12. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 43 12.1. YANG Module Registration . . . . . . . . . . . . . . . . 43 12.2. SID Range Allocation . . . . . . . . . . . . . . . . . . 43 13. References . . . . . . . . . . . . . . . . . . . . . . . . . 43 13.1. Normative References . . . . . . . . . . . . . . . . . . 43 13.2. Informative References . . . . . . . . . . . . . . . . . 45 Appendix A. Module Tree . . . . . . . . . . . . . . . . . . . . 47 Appendix B. Complete YANG Module . . . . . . . . . . . . . . . . 49 Appendix C. SID File (CSV) . . . . . . . . . . . . . . . . . . . 64 Appendix D. atmos YANG Module . . . . . . . . . . . . . . . . . 66 Appendix E. atmos SID File (CSV) . . . . . . . . . . . . . . . . 71 Appendix F. ccm2m Ontology . . . . . . . . . . . . . . . . . . . 71 Appendix G. SCHC Rule Set . . . . . . . . . . . . . . . . . . . 75 G.1. Rule 0: Used to fetch a single value (bidirect) . . . . . 76 G.2. Rule 1: Used to iPatch, ack with 7/3. Empty CoAP for notification in UP . . . . . . . . . . . . . . . . . . . 80 G.3. Rule 2: Used for notitifications (observe) . . . . . . . 82 G.4. Rule 3: Empty messages (e.g., ACK with empty code, or RST) . . . . . . . . . . . . . . . . . . . . . . . . . . 86 G.5. Rule 4: ICMPv6 destination unreachable (any code) . . . . 86 Appendix H. Private SID Translation . . . . . . . . . . . . . . 88 H.1. Worked Example (atmos first) . . . . . . . . . . . . . . 89 H.2. Second Example: Time-Series Subscription and Notification . . . . . . . . . . . . . . . . . . . . . . 90 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 90 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 91 1. Introduction This document proposes a YANG data model designed for constrained devices and low-power networks. By combining YANG's strong typing with CBOR's compact binary serialization and CoAP's lightweight transport, the model enables efficient Machine-to-Machine (M2M) data exchange while remaining within the bandwidth and energy budgets of constrained environments. SCHC header compression [RFC8724] may Toutain Expires 20 March 2027 [Page 3] Internet-Draft coreconf-m2m September 2026 further be used to reduce the overhead of IPv6, UDP, and CoAP headers on the most constrained links. Some data models and protocols already exist for M2M communication in IoT environments, but none is fully adapted to the constraints of low-power networks in terms of message size, energy consumption, and interaction patterns. This section reviews the main existing approaches and explains why a new model is needed. SenML [RFC8428] has become a widely adopted format for Machine-to- Machine (M2M) data exchange in IoT environments, enabling constrained devices to report sensor measurements and time series in JSON or CBOR. However, SenML is primarily a data serialization format: it structures payloads but does not enforce strong type checking, schema validation, or support for configuration and remote operations. SenML is also part of the LwM2M framework [OMA-LwM2M], which defines a broader device management protocol built on CoAP and SenML for operator-to-device interactions. However, LwM2M relies on periodic reporting and registration messages that impose a non-trivial overhead, particularly on Low-Power Wide-Area Networks (LPWANs) [RFC8376] where bandwidth and energy budgets are severely constrained. In some ways, SenML may be described by a YANG Data Model [I-D.gudi-t2trg-senml-as-coreconf], but the integration in the YANG ecosystem remains limited. The CORECONF protocol stack using YANG [RFC7950] for Data Modeling, CoAP [RFC7252] for data transport, and CBOR [RFC8949] and YANG SID identifiers [I-D.ietf-core-sid] for the compact data serialization provides the richer foundation that SenML lacks: a strongly typed data model, schema validation, and support for full CRUD operations and actions. However, CORECONF has so far been designed for operator-to-device management, leaving peer-to-peer M2M communication — where both endpoints may themselves be constrained nodes — largely unaddressed. Some YANG Data Models have been defined for telemetry. [RFC9232] introduces Network Telemetry used to collect vast amounts of data to supervise a network. [RFC8639] allows subscribing to a datastore filtered through XPath and receiving notifications. [I-D.birkholz-yang-core-telemetry] proposes to extend telemetry to CORECONF, but using a traditional approach. None of these attempt to limit the size of the exchanged data, which is essential on the constrained links this document targets. Toutain Expires 20 March 2027 [Page 4] Internet-Draft coreconf-m2m September 2026 This document adopts a different approach. The goal is to define a YANG Data Model that will benefit from CBOR serialization to optimize the bandwidth to extend CORECONF for M2M use cases over low-power links. The data model turns around transducers held by a device. A transducer is the abstract representation of a sensor and/or an actuator, transforming an analog value into a digital value, or a digital value into a physical action. This document focuses on transducer management: resource discovery, value polling, statistical computation, threshold alerts, and time-series history notifications. This is an early-stage work; future revisions will explore other categories of measurements and interaction patterns. Beyond its use as a wire format, the structure defined by the YANG Data Model can be mapped into a Semantic Web ontology, giving each container, list, and leaf a counterpart class or property that common IoT ontologies such as SOSA or SensorThings already understand. Section 7.1 details this mapping and how it lets a device modeled with coreconf-m2m be integrated into an existing ontology-based deployment without a device-specific adaptation layer. 1.1. Use Cases The targeted use cases are remote sensors installed in the field and connected with LPWAN or Satellite connectivity. SCHC [RFC8724] [RFC8824] is used to compress headers such as IPv6, UDP and CoAP for CORECONF traffic. The payload results from the serialization of the datastore in CBOR. The model covers the following use cases: * resource discovery: sensors or actuators, regrouped under the name transducers, are discovered with their characteristics (units, precision) * simple query: each transducer can be individually queried or set. * statistical computation: the sensor can compute some statistical values, such as mean, variance, min and max. They can be reset. * alert notification: when a value reaches a threshold (minimum and maximum) a notification message is sent * time series: values are collected by the device and sent when a limit is reached (number of samples, duration, message size) Toutain Expires 20 March 2027 [Page 5] Internet-Draft coreconf-m2m September 2026 1.2. Data Representation CBOR is designed to be concise to represent numerical information since it is directly coded in binary and not represented in ASCII. CBOR also uses binary representation to encode structures such as Maps and Arrays. The length of a numerical value depends on its value; for instance, numbers between -24 and 23 are coded on a single byte, values between -255 and 255 on two bytes,... Nevertheless, some representations may be less efficient numerically or less precise. CBOR defines three IEEE 754 encodings on 3, 5, or 9 bytes. The smallest representation introduces a close to 1% error. CBOR also provides a decimal fraction type (tag 4) encoding a value as a [exponent, mantissa] pair, which avoids floating-point rounding. However, this representation requires the exponent (the divider) to be repeated alongside every individual quantity, adding overhead for each encoded value. The assumption leading to this YANG module is to avoid floating-point numbers for their size or precision and rely on integers with a precision parameter indicating, if positive, the number of digits after the decimal point, or the power of 10 if negative. The module also introduces the notion of time series to record several measurements during a period of time and send them in a single message using a notification. Time series values may further be compressed depending on the nature of the data. This version proposes a compression based on delta encoding: instead of transmitting absolute values, each sample is encoded as the difference from the previous one, which significantly reduces the CBOR payload size for slowly-varying measurements. The device can also send an alert when a measured value reaches a threshold, allowing the receiver to react promptly without waiting for a scheduled report. Since the targeted networks are constrained in bandwidth, measurements are expected to be reported infrequently, so the second is chosen as the time unit. To limit the size of the timestamps, they are expressed as the number of seconds elapsed since the equipment was started, rather than as an absolute date and time. If the equipment is able to do so, it can indicate its startup epoch to reconstitute an absolute time. Toutain Expires 20 March 2027 [Page 6] Internet-Draft coreconf-m2m September 2026 1.3. Requirements Language The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. 2. Terminology The following terminology is used in this document: CORECONF: : CoAP Management Interface, as defined in [I-D.ietf-core-comi]. M2M: : Machine-to-Machine communication, referring to direct data exchanges between devices without human intervention. SID: : YANG Schema Item iDentifier, a compact numeric identifier for YANG data nodes, as defined in [I-D.ietf-core-sid]. Constrained Device: : A device with limited processing, memory, and energy resources, as characterized in [RFC7228]. Device: : A piece of equipment containing one or more transducers. Transducer: : an interface between the analog and digital world. Transducers are sensors reporting values or actuators having an action on the physical world. Quantity: : values manipulated by transducers. Value: : other information stored in the datastore including quantities 3. YANG Modules needed for coreconf-m2m coreconf-m2m YANG module is a framework: it defines the generic structure of a CORECONF server hosting one or several transducers, a generic name for a sensor or an actuator, but it does not define the transducers themselves. Each transducer is identified by a unique identity, and if several transducers report the same kind of measurement, several instances of the same identity have to be defined. Toutain Expires 20 March 2027 [Page 7] Internet-Draft coreconf-m2m September 2026 A device manufacturer using coreconf-m2m MUST therefore define, or reuse, a YANG module describing the transducers embedded in its device, as identities extending the base "transducer-type" identity defined in coreconf-m2m (see Section 3.1). 3.1. Identities Data Model The identity data model defines all the transceivers that may be used inside the hosts, this can be a generic data model or a model specific to the hosts. This module indicates default parameters used for that transceiver (units, precision, nature). These values are mandatory and may be overridden by the coreconf-m2m. A manufacturer module defines the concrete transducer-type identities for a given product family; coreconf-m2m only defines the base "transducer-type" identity that these modules extend. The ATMOS41 weather station example used throughout this document is defined this way, in a separate "atmos" module that imports coreconf-m2m and extends its base identity with atmospheric and weather-related transducer types. coreconf-m2m defines the template for identities extensions. Figure 1 gives an example of an identity definition, where "ccm2m" refers to the coreconf-m2m module. identity air-temperature { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "Cel"; ccm2m:default-precision "2"; description "Air temperature measurement (°C)."; } Figure 1: Example of an identity definition using the coreconf- m2m extensions Identity names and descriptions SHOULD be explicit, since this information may be used by a human, e.g. through an interface, or by an AI agent, to formulate requests. 3.2. Overview of the coreconf-m2m Module The coreconf-m2m module is organized into three sub-modules: Toutain Expires 20 March 2027 [Page 8] Internet-Draft coreconf-m2m September 2026 * "bootstrap" contains the context needed by the client to interact with the server and its transducers. It mainly contains the time reference and the transducer list. These values cannot be changed by the client (config false); only a reboot, which also resets the communications, allows their modification - "characteristics" contains stable information describing the host. This information may be necessary for some ontologies such as [SOSA] and [SAREF]. These values may be modified during runtime, and * "transducers" contains the runtime values of all the sensors and actuators maintained by the host. It also contains parameters to control notifications issued by the device. * an RPC, now limited to resetting all statistics * two notification types: one to collect time-series history, and one to alert when a quantity reaches a minimum or maximum threshold. Figure 28 in Appendix A gives an overview of the module YANG tree. 3.2.1. Bootstrap Sub-Tree module: coreconf-m2m +--ro bootstrap +--ro reference-epoch? uint64 +--ro uptime uint64 +--ro minimal-step? uint32 +--ro inventory* [type] +--ro type identityref +--ro unit-override? string +--ro precision-override? uint8 +--ro category-override? enumeration Figure 2: bootstrap sub-tree The bootstrap sub-tree contains information determined at bootstrap: * reference-epoch: the absolute time at bootstrap, if a reference time source (battery-powered clock, GPS, ...) is available on the device. This leaf is absent if no reference time is available. * uptime: the number of seconds elapsed since bootstrap. A client can combine reference-epoch and uptime to estimate clock drift or propagation delay. Toutain Expires 20 March 2027 [Page 9] Internet-Draft coreconf-m2m September 2026 * minimal-step: the minimum number of seconds between two transceiver readings. For instance, if a node updates its reading every 2 minutes, querying it more frequently only increases battery drain without yielding fresher data. * inventory: the list of transducers known to the device, identified by their "type" and their configuration overrides (see Section 3.2.3). These values can only change on a reboot, which also resets the communications and forces the client into a new bootstrap phase to recover the data. 3.2.2. Characteristics Sub-Tree module: coreconf-m2m +--rw characteristics +--rw geo-location | +--rw reference-frame | | +--rw alternate-system? string {alternate-systems}? | | +--rw astronomical-body? string | | +--rw geodetic-system | | +--rw geodetic-datum? string | | +--rw coord-accuracy? decimal64 | | +--rw height-accuracy? decimal64 | +--rw (location)? | | +--:(ellipsoid) | | | +--rw latitude? decimal64 | | | +--rw longitude? decimal64 | | | +--rw height? decimal64 | | +--:(cartesian) | | +--rw x? decimal64 | | +--rw y? decimal64 | | +--rw z? decimal64 | +--rw velocity | | +--rw v-north? decimal64 | | +--rw v-east? decimal64 | | +--rw v-up? decimal64 | +--rw timestamp? yang:date-and-time | +--rw valid-until? yang:date-and-time +--rw name? string +--rw version? string +--rw identifier? string +--rw description? string +--rw manufacturer? string +--rw model? string +--rw hosted-by? string +--rw installation-time? uint64 Toutain Expires 20 March 2027 [Page 10] Internet-Draft coreconf-m2m September 2026 Figure 3: characteristics sub-tree This sub-tree contains stable information about the device that is not expected to change across reboots: * geo-location: the fixed geographic position of the device, set once at deployment and not expected to change during normal operation. The module reuses the "ietf-geo-location" YANG module [RFC9179], of which only the "ellipsoid" choice is normally needed. Note that its coordinates are typed as "decimal64", encoded in CBOR as a tagged array containing an exponent and a mantissa. This encoding was not chosen for transducer values, in order to avoid repeating the exponent (called "precision" in this model) with every quantity. If the device is mobile, its coordinates should instead be exposed through a transducer. * name: a human-readable name for the device. * version: the firmware or software version running on the device. * identifier: a unique identifier for the device, such as a serial number or EUI. * description: a free-text description of the device, its purpose, or its deployment context. * manufacturer: the name of the device manufacturer. * model: the commercial model name or number of the device. * hosted-by: an identifier of the platform hosting this device, when applicable. * installation-time: the absolute date and time (Unix epoch, in seconds) at which the device was installed or commissioned. Unlike bootstrap/reference-epoch, this is an absolute value, not a reference point for the device's internal clock. 3.2.3. Transducer Sub-Tree Toutain Expires 20 March 2027 [Page 11] Internet-Draft coreconf-m2m September 2026 module: coreconf-m2m +--rw transducers +--rw transducer* [type] +--rw type identityref +--ro quantity | +--ro value? int64 | +--ro timestamp? uint64 | +--ro timestamp-source? enumeration +--ro statistics +--ro min? int64 +--ro max? int64 +--ro mean? int64 +--ro median? int64 +--ro stdev? uint64 +--ro sample-count? uint64 Figure 4: transducer sub-tree (type, quantity and statistics) The transducers sub-tree contains the list of transducers (i.e., sensors and actuators) maintained by the device, listed in "/bootstrap/inventory". A transducer is identified by its "type", the same identityref used in the "/bootstrap/inventory" entry. This branch holds two kinds of information: "quantity" carries the values manipulated by the transducer, while "notification-parameters" configures notifications through which the device can proactively inform the client. Quantity contains: * "value": the raw integer value, computed as value = measurement * 10^precision, * "timestamp": the relative time of the measurement, in seconds, * the entity in charge of the timestamp, which can be the device itself or the receiver. "statistics" is a sibling of "quantity" and holds the main statistics locally computed for a specific transducer, accumulated over a window of samples rather than tied to the current measurement. Statistics can be reset for a single transducer via the "reset-stats" action, or for all transducers at once via the "reset-stats" RPC. Toutain Expires 20 March 2027 [Page 12] Internet-Draft coreconf-m2m September 2026 module: coreconf-m2m +--rw transducers +--rw transducer* [type] +--rw notification-parameters +--rw history | +--ro active? boolean | +--rw step? uint32 | +--rw precision? uint8 | +--rw max-samples? uint32 | +--rw time-period? uint32 | +--rw encoding? encoding-type | +--rw max-payload? uint32 +--rw sensor-alert | +--ro active? boolean | +--rw t-min? int32 | +--rw t-max? int32 | +--rw hysteresis? uint8 | +--rw dampening? uint32 +--rw check-interval? uint16 Figure 5: notification-parameters sub-tree Notification Parameters supports two kinds of notifications: * "sensor-alert" will send a notification when the measured quantity reaches one or two limits, minimal and maximal, or goes back to a value between these two bounds. To avoid fluctuations, two mechanisms are in place: - "hysteresis" defines a percentage, by default 5% around the limit, so if a maximum limit is set to 100, an alert message will be triggered when the quantity is higher than 105 and another alert will be sent when the quantity becomes lower than 95%. The value is sent in the notification message, so the client is able to know the state of the alert. - "dampening" limits the number of messages sent. When a crossing is suppressed because of dampening, the notification eventually sent MUST carry a None value, so the client can distinguish a dampened event from an actual measured value. * "history" builds time series: - "step" parameter defines at which interval samples are taken. - "precision" allows overriding the quantity precision defined in the transducer. By default the precision is the one associated with the transducer for "quantity". Toutain Expires 20 March 2027 [Page 13] Internet-Draft coreconf-m2m September 2026 - "encoding" indicates how information is stored in the time series: o "direct": all the values are stored with the precision. o "delta": the first value is the reference and the following ones are the difference with the previous. This allows limiting the size of the message since CBOR encodes small numbers more efficiently. - A notification is sent when a number of measurements is reached, either: o the number of samples in the time series reaches "max- samples", o "max-payload" is based on the size of the time series. Since small numbers take less space than large numbers in CBOR, a time series may contain a different number of samples. o the "time-period" after which the collection should be sent. * "check-interval" controls how often a CON (confirmable) notification is sent instead of NON (non-confirmable), for both the history and sensor-alert streams of this transducer: 0 (default) disables it, so all notifications are NON; 1 makes every notification CON; N sends one CON every N notifications, all others being NON. The read-only active flag in both notification types is set when one or more clients observe a notification. Parameters are common to all observations of a particular transducer. 3.3. Notifications As seen in the previous section, each transducer has a "notification- parameters" branch holding its notification settings. A client MAY FETCH this branch to retrieve its content and check the current status of the notification (e.g., the "active" flag). A client wishing to start a notification MAY first send an iPATCH to configure its parameters. Parameters changed while a notification is already active take effect immediately. These parameters are global to the transducer: a modification impacts every notification currently active for that transducer, regardless of which client configured it. Toutain Expires 20 March 2027 [Page 14] Internet-Draft coreconf-m2m September 2026 Notification is started by sending a FETCH+Observe request on the notification stream resource (/s), with a body identifying the SID of the transducer to observe. Multiple clients may observe the same transducer simultaneously; each receives an independent copy of every notification. The notification ends when either: * the client explicitly sends a termination message (a GET/FETCH with the Observe option set to 1, i.e. deregister, using the same token as the original observation), or * the client sends a RST in response to a notification, or * the server sends Confirmable notifications and does not receive an acknowledgment, or * an ICMPv6 unreachable message is received by the server in response to the IPv6/UDP/CoAP packet carrying the notification's token. 4. CORECONF Overview in the M2M Context 4.1. CoAP Methods Mapping CORECONF defines mappings for all CoAP methods, but this document uses only two: * FETCH is used instead of GET to retrieve values from the YANG Data Model. Unlike GET, FETCH carries a body specifying the exact SIDs to retrieve, enabling precise and bandwidth-efficient queries. Combined with the CoAP Observe option, FETCH also serves to subscribe to notification streams. * iPATCH is used instead of PUT or POST to modify quantities and notification parameters. It supports partial updates: only the specified nodes are modified, leaving others unchanged, following the merge semantics of [RFC7396]. Setting a node to an empty value with iPATCH is the preferred way to clear a parameter, making DELETE unnecessary for datastore modifications. The recommended CoAP Content-Format for all exchanges is Content- Format 140 (application/yang-data+cbor;id=sid [RFC9254]), used uniformly for FETCH request bodies (which carry the list of SIDs to retrieve), response bodies, and iPATCH payloads, where data nodes are identified by their SID. Toutain Expires 20 March 2027 [Page 15] Internet-Draft coreconf-m2m September 2026 Using a single content format ensures maximum interoperability with CORECONF implementations and keeps the payloads as compact as possible. Limiting exchanges to a single well-known packet format also benefits SCHC compression [RFC8724]: the fewer distinct header patterns in use, the more efficiently SCHC rules can compress the CoAP headers, reducing overhead on the most constrained links. FETCH and iPATCH requests MUST be sent as Non-Confirmable (NON) CoAP messages. This leaves the application free to implement its own retransmission strategy and timer management, which is essential on constrained networks where the default CoAP confirmable retransmission behavior may be inappropriate or wasteful. For notification streams (Observe), Confirmable (CON) messages MAY be used. A CON notification allows the server to detect that the observer is no longer reachable when no ACK is received, and to cancel the Observe subscription accordingly. A RST response from the client is also a valid way to signal that the subscription should be terminated. 4.2. SID Allocations The coreconf-m2m model is intended to be assigned in the IETF experimental SID space, with a model entry point of 62000. Appendix C gives the complete SID mapping for this model. The atmos module, however, cannot be assigned SIDs in the IETF or another SDO space, unless this commercial module is itself standardized. For commercial modules, we assume that a registrar allocates SIDs and implements the constraints defined in [I-D.ietf-core-comi]. In this example, we assume that the registrar owns a 10 million SID mega-range. Appendix D gives the atmos.yang model, and Appendix E gives the corresponding SID mapping, composed of the identities representing the transducers. 5. CORECONF Traffic This section illustrates different traffic patterns used in coreconf- m2m. 5.1. Resource Discovery The client does not know the transducers managed by the device. It sends a FETCH on "/bootstrap" (SID 62002) as shown in Figure 6. Toutain Expires 20 March 2027 [Page 16] Internet-Draft coreconf-m2m September 2026 CoAP Request: Non-Confirmable, FETCH, MID:39919 Token: 2aaf Opt #1: Uri-Path: c Opt #2: Content-Format: 140 (application/yang-data+cbor;id=sid) Opt #3: Accept: 140 (application/yang-data+cbor;id=sid) Payload: 3 bytes 19 F2 32 # unsigned(62002) : /bootstrap CoAP Response: Non-Confirmable, 2.05 Content, MID:57745 Token: 2aaf Opt #1: Content-Format: 140 (application/yang-data+cbor;id=sid) Payload: 118 bytes {62002: {7: 1788334280, 8: 30172, 6: 120, 1: [{3: 10000010}, {3: 10000008}, {3: 10000011}, {3: 10000002}, {3: 10000014}, {3: 10000016}, {3: 10000015}, {3: 10000012}, {3: 10000001}, {3: 10000013}, {3: 10000003}, {3: 10000009}, {3: 10000006}, {3: 10000004}]}} Figure 6: Resource discovery: FETCH request and response (SCHC Rule 0) In the request, the payload 19 F2 32 is the CBOR encoding of the unsigned integer 62002, which is the SID of "/bootstrap". In the response, the outer key 62002 identifies the bootstrap branch, and the inner keys are delta SIDs relative to 62002, as defined in [RFC9254]: 7 (reference-epoch), 8 (uptime), 6 (minimal-step), and 1 (the "inventory" list). Each entry in the inventory list is itself a map whose key 3 is a delta SID relative to the list SID (62003), i.e. "type", carrying the identity SID of one transducer known to the device; no override is present here, meaning every transducer uses the default-unit, default-precision and default-category declared on its identity. The client MUST have access to the corresponding YANG files to discover the transducers' default parameters, indicating the unit, the precision and the nature of the transducer. Toutain Expires 20 March 2027 [Page 17] Internet-Draft coreconf-m2m September 2026 coreconf-m2m:bootstrap reference-epoch 1788334280 (2026-09-02 09:31:20) ← origin of every timestamp in the model uptime 30172 s minimal-step 120 s ← floor for history/step coreconf-m2m:bootstrap/inventory — SID → module → YANG defaults resolution SID Identity Module Unit Prec. Category ──────────────────────────────────────────────────────────────────────────────────────────── 10000010 atmos:solar-radiation atmos W/m2 0 sensor 10000008 atmos:precipitation atmos mm 3 sensor 10000011 atmos:strike-count atmos count 0 sensor 10000002 atmos:average-distance atmos km 0 sensor 10000014 atmos:wind-direction atmos deg 0 sensor 10000016 atmos:wind-speed atmos m/s 2 sensor 10000015 atmos:wind-gust atmos m/s 2 sensor 10000012 atmos:tilt atmos deg 1 sensor 10000001 atmos:air-temperature atmos Cel 1 sensor 10000013 atmos:vapor-pressure atmos kPa 2 sensor 10000003 atmos:barometric-pressure atmos kPa 2 sensor 10000009 atmos:relative-humidity atmos %RH 1 sensor 10000006 atmos:humidity-sensor-temperature atmos Cel 1 sensor 10000004 atmos:compass-heading atmos deg 0 sensor ──────────────────────────────────────────────────────────────────────────────────────────── * override sent by the device; without a star, default value read from the YANG module. The inventory completed this way stays local: bootstrap is config false and is never sent back. Connected. 14 sensor(s) discovered, minimal step 120 s. # Type Unit Prec. Filter ────────────────────────────────────────────────────────────────────────────── 1 solar-radiation W/m2 0 [type='atmos:solar-radiation'] 2 precipitation mm 3 [type='atmos:precipitation'] 3 strike-count count 0 [type='atmos:strike-count'] 4 average-distance km 0 [type='atmos:average-distance'] 5 wind-direction deg 0 [type='atmos:wind-direction'] 6 wind-speed m/s 2 [type='atmos:wind-speed'] 7 wind-gust m/s 2 [type='atmos:wind-gust'] 8 tilt deg 1 [type='atmos:tilt'] 9 air-temperature Cel 1 [type='atmos:air-temperature'] 10 vapor-pressure kPa 2 [type='atmos:vapor-pressure'] 11 barometric-pressure kPa 2 [type='atmos:barometric-pressure'] 12 relative-humidity %RH 1 [type='atmos:relative-humidity'] 13 humidity-sensor-temperature Cel 1 [type='atmos:humidity-sensor-temperature'] 14 compass-heading deg 0 [type='atmos:compass-heading'] Figure 7: Decoded transducer inventory from resource discovery response Toutain Expires 20 March 2027 [Page 18] Internet-Draft coreconf-m2m September 2026 5.2. Querying a quantity A specific quantity may be requested through a FETCH. Figure 8 shows the exchange for the current value of air-temperature. CoAP Request: Non-Confirmable, FETCH, MID:12229 Token: 2dae Opt #1: Uri-Path: c Opt #2: Content-Format: 140 (application/yang-data+cbor;id=sid) Opt #3: Accept: 140 (application/yang-data+cbor;id=sid) Payload: 9 bytes [62077, 10000001] CoAP Response: Non-Confirmable, 2.05 Content, MID:57779 Token: 2dae Opt #1: Content-Format: 140 (application/yang-data+cbor;id=sid) Payload: 6 bytes {62077: 196} Figure 8: FETCH request and response for air-temperature current value (SCHC Rule 0) The FETCH body [62077, 10000001] is a CORECONF instance-identifier: the first element (62077) is the SID of "/transducers/transducer/quantity/value", followed by the list key value identifying the transducer (type=10000001, i.e. atmos:air- temperature). The response carries only that leaf: the value 196, combined with the precision=1 declared on the air-temperature identity, decodes to 19.6°C. Fetching the "value" leaf directly, rather than the whole "quantity" sub-tree, avoids returning timestamp and timestamp-source when only the current reading is needed. Figure 9 shows the FETCH for the full statistics table of the same transducer: Toutain Expires 20 March 2027 [Page 19] Internet-Draft coreconf-m2m September 2026 CoAP Request: Non-Confirmable, FETCH, MID:18878 Token: 5420 Opt #1: Uri-Path: c Opt #2: Content-Format: 140 (application/yang-data+cbor;id=sid) Opt #3: Accept: 140 (application/yang-data+cbor;id=sid) Payload: 9 bytes [62081, 10000001] CoAP Response: Non-Confirmable, 2.05 Content, MID:32290 Token: 5420 Opt #1: Content-Format: 140 (application/yang-data+cbor;id=sid) Payload: 21 bytes {62081: {4: 196, 1: 217, 2: 203, 3: 202, 6: 7, 5: 8}} Figure 9: FETCH request and response for air-temperature statistics (SCHC Rule 0) The FETCH body [62081, 10000001] requests the statistics sub-tree (SID 62081) for air-temperature (10000001). In the response, the inner map keys are delta SIDs relative to 62081, each encoding the difference between consecutive SIDs to minimize CBOR size. The six values correspond to the statistics leaves: min (196), max (217), mean (203), median (202), stdev (7), and sample-count (8), all scaled by the transducer precision except sample-count. The client decodes the response and displays the statistics as shown in Figure 10: [9] Statistics — air-temperature: min: 19.6 Cel max: 21.7 Cel mean: 20.3 Cel median: 20.2 Cel σ: 0.7 Cel n: 8 Figure 10: Decoded statistics for air-temperature 5.3. Notification The client first sends an iPATCH to configure the history notification parameters for the air-temperature transducer, as shown in Figure 11. Toutain Expires 20 March 2027 [Page 20] Internet-Draft coreconf-m2m September 2026 CoAP Request: Non-Confirmable, iPATCH, MID:42310 Token: 248e Opt #1: Uri-Path: c Opt #2: Content-Format: 140 (application/yang-data+cbor;id=sid) Payload: 22 bytes {[62060, 10000001]: {62060: {6: 120, 4: 10, 2: 1}}} CoAP Response: Non-Confirmable, 2.04 Changed, MID:65147 Token: 248e Figure 11: iPATCH to configure history notification parameters for air- temperature (SCHC Rule 1) The iPATCH key [62060, 10000001] is an instance-identifier targeting the notification-parameters/history node (SID 62060) for air- temperature (type 10000001). The value {62060: {6: 120, 4: 10, 2: 1}} sets three history parameters using delta SIDs relative to 62060: step=120 s, max-samples=10, and encoding=delta (value 1). An iPATCH is used the same way to configure a sensor-alert: the client sets the low and high thresholds, and activates the alert, as shown in Figure 12. CoAP Request: Non-Confirmable, iPATCH, MID:42312 Token: 2490 Opt #1: Uri-Path: c Opt #2: Content-Format: 140 (application/yang-data+cbor;id=sid) Payload: 24 bytes {[62068, 10000001]: {62068: {1: true, 4: 350, 5: 50}}} CoAP Response: Non-Confirmable, 2.04 Changed, MID:65150 Token: 2490 Figure 12: iPATCH to configure sensor-alert thresholds for air- temperature (SCHC Rule 1) Toutain Expires 20 March 2027 [Page 21] Internet-Draft coreconf-m2m September 2026 The iPATCH key [62068, 10000001] targets the notification-parameters/ sensor-alert node (SID 62068) for air-temperature. The value {62068: {1: true, 4: 350, 5: 50}} sets three leaves using delta SIDs relative to 62068: active=true (delta 1), t-max=350 (delta 4), and t-min=50 (delta 5). Since air-temperature has precision=1 (as in Figure 8), these raw integers represent 35.0 Cel and 5.0 Cel: the device raises an alert once the temperature leaves that range. The client then initiates an Observe subscription with a FETCH on the notification stream resource /s, as shown in Figure 13. CoAP Request: Non-Confirmable, FETCH, MID:42311 Token: 248f Opt #1: Observe: 0 Opt #2: Uri-Path: s Opt #3: Content-Format: 140 (application/yang-data+cbor;id=sid) Opt #4: Accept: 140 (application/yang-data+cbor;id=sid) Payload: 9 bytes [62048, 10000001] CoAP Response (subscription acknowledgment): Non-Confirmable, 2.05 Content, MID:65148 Token: 248f Opt #1: Observe: 0 Opt #2: Content-Format: 140 (application/yang-data+cbor;id=sid) Payload: 1 byte {} CoAP Notification: Non-Confirmable, 2.05 Content, MID:65149 Token: 248f Opt #1: Observe: 1 Opt #2: Content-Format: 140 (application/yang-data+cbor;id=sid) Payload: 16 bytes {62048: [189, 14, -3, 1, 5, 7, 3, 2, 1, 2]} Figure 13: FETCH+Observe subscription on `/s` and history notification for air- temperature (SCHC Rule 2) The FETCH body [62048, 10000001] subscribes directly to the time- series "values" leaf-list (SID 62048) for air-temperature, rather than the whole time-series entry: since the subscription is already transducer-specific, echoing the "type" back in every notification would only repeat what the client already knows. The server Toutain Expires 20 March 2027 [Page 22] Internet-Draft coreconf-m2m September 2026 acknowledges with an empty map {}. The notification then carries the values list under its absolute SID, [189, 14, -3, 1, 5, 7, 3, 2, 1, 2], using delta encoding: 189 is the absolute reference (18.9°C, precision=1), and each subsequent value is the difference from the previous one. The client decodes the delta-encoded time-series values and displays the result as shown in Figure 14: [9] air-temperature: 18.9 Cel (09:57:42) [9] air-temperature: 20.3 Cel (09:59:42) [9] air-temperature: 20.0 Cel (10:01:42) [9] air-temperature: 20.1 Cel (10:03:42) [9] air-temperature: 20.6 Cel (10:05:42) [9] air-temperature: 21.3 Cel (10:07:42) [9] air-temperature: 21.6 Cel (10:09:42) [9] air-temperature: 21.8 Cel (10:11:42) [9] air-temperature: 21.9 Cel (10:13:42) [9] air-temperature: 22.1 Cel (10:15:42) Figure 14: Decoded air-temperature time-series from history notification The whole batch of samples is decoded from a single notification message. Since the device timestamp is not carried in this payload, the client reconstructs one from the configured "step" (120 s): the last sample is stamped with the local time at which the notification was received, and earlier samples are stepped back by 120 s each, oldest first. 6. From CBOR/SID to Textual Identifiers The examples throughout this document use CBOR payloads keyed by SIDs (application/yang-data+cbor;id=sid), which is the compact representation intended for constrained links. Ontologies generally use a textual representation, and interacting with a human user likewise requires presenting the information with understandable identifiers (see the example in Figure 7). To perform this translation, the recipient of a coreconf-m2m message needs access to the .sid file and, in some cases, the YANG file, in order to recover the transducers' default values. [I-D.toutain-core-sid-encoding] defines a way to use DNS to locate a SID and a YANG file. An experimental service running with the "sid.yt" suffix has been deployed. It allows finding the SID and YANG files associated with a specific SID. Toutain Expires 20 March 2027 [Page 23] Internet-Draft coreconf-m2m September 2026 7. Interconnection with an Ontology The goal of coreconf-m2m is to discover the resources managed by the device and to provide a lightweight transport for information coming from a sensor or dedicated to an actuator; it is not itself an ontology. This section discusses how the elements it carries relate to some existing ontologies and APIs, so that a gateway or application can align them with a richer semantic model when needed, once translated to textual identifiers as described in Section 6. 7.1. Extending Ontology to coreconf-m2m Before looking at how YANG information can be included into an existing ontology, it may also be important to enrich the ontology with coreconf-m2m information concerning the device's CORECONF capabilities; this may be helpful for future interactions with the device. This document therefore assumes a small ccm2m: extension vocabulary, applicable regardless of which ontology (SOSA, SAREF, SensorThings, ...) a device or transducer is otherwise mapped to. Appendix F gives its full definition, as an OWL ontology in Turtle. The ccm2m ontology defines a single datatype, ccm2m:SID: a non- negative integer that uniquely identifies a YANG node, identity, or feature within a SID file, used instead of a plain xsd:nonNegativeInteger so that the nature of the value is self- documenting. It defines properties attached to a sosa:Platform, giving the coordinates needed to reach and query the device: * ccm2m:coapEndpoint is the CoAP access address of the device (e.g. coap://[::1]); * ccm2m:accessProtocol is the default applicative protocol used on that platform (e.g. "coreconf"); * ccm2m:bootstrapSid is the SID used at bootstrap to discover the YANG model exposed by the platform (see Section 5.1); it is multi- valued, since several bootstrap SIDs are possible. It also defines properties attached to a sosa:Sensor, tying it back to its YANG identity: * ccm2m:type carries the transducer's identity SID (see Figure 7); Toutain Expires 20 March 2027 [Page 24] Internet-Draft coreconf-m2m September 2026 * ccm2m:id is the instance identifier of the sensor on its platform, distinguishing multiple sensors of the same type; * ccm2m:precision and ccm2m:outputUnit carry the default-precision and default-unit declared on that identity, or their overrides (see Section 3.2.3), and are declared once rather than repeated on every observation. Finally, it models the applicative operations that can be performed on a device or transducer, i.e. its CORECONF capabilities, deliberately kept outside SOSA/SSN's Sampling/Sensing semantics: * ccm2m:Control is an applicative operation exposed over CORECONF/ CoAP (a single-value read, a history-buffer notification subscription, or a threshold-alert notification subscription), linked to a Platform or Sensor via ccm2m:hasControl. Its ccm2m:controlType names the operation (e.g. "read-single", "subscribe-history", "reset-all-stat"), ccm2m:targetSid gives the SID of the YANG leaf/container it targets, and ccm2m:coapMethod, ccm2m:coapPath, and ccm2m:contentFormat describe how to invoke it over CoAP; * ccm2m:SetupNotification is a Control that configures notification parameters on a transducer before subscribing (an iPATCH on /c); its ccm2m:hasParam links to one or more ccm2m:NotificationParam, each giving, via ccm2m:paramName and ccm2m:paramSid, the YANG leaf name and SID of one configurable parameter (e.g. "step", "encoding"; see Figure 5). Without these properties, a graph would describe what a platform observes, but not how to obtain the corresponding coreconf-m2m data, nor how to act on it. The following subsections use this ccm2m: vocabulary to bridge the elements of coreconf-m2m to specific ontologies. 7.2. SOSA The Sensor, Observation, Sample, and Actuator (SOSA) ontology is maintained jointly by the W3C and the Open Geospatial Consortium (OGC), as part of the broader SSN (Semantic Sensor Network) ontology [SOSA]. It defines a sosa:Platform as an entity that hosts other objects, such as sensors, actuators, or samplers. The device described by the "characteristics" sub-tree (Section 3.2.2) maps to a sosa:Platform, and each of its transducers maps to a sosa:Sensor or a sosa:Actuator hosted by that platform. Toutain Expires 20 March 2027 [Page 25] Internet-Draft coreconf-m2m September 2026 SOSA also defines a sosa:Sampler type, but it corresponds more to sample-taking than to measurement, so it may be present in the ontology without requiring a link with the coreconf-m2m YANG data model. Figure 15 shows a generic, abstract example of such a platform, expressed in the Turtle RDF syntax, independently of any particular naming scheme. @prefix sosa: . a sosa:Platform ; sosa:hosts . a sosa:Sensor ; sosa:isHostedBy ; sosa:observes . Figure 15: Generic Turtle example of a sosa:Platform hosting a sosa:Sensor 7.2.1. Instantiating from YANG To turn this generic pattern into a concrete graph, the platform's IRI can be derived from the device's DNS name, e.g. station.example.com, and the IRI of each hosted object can in turn be derived from that name and from its entry in "/bootstrap/inventory", e.g. station.example.com/sensor/air-temperature. Figure 16 gives the CDDL [RFC8610] for constructing such an object IRI from the platform's DNS name and an inventory entry, using the ".cat" control operator [RFC9165] to express the concatenation of its text fragments. category = "sensor" / "actuator" object-iri = platform-name .cat "/" .cat category .cat "/" .cat transducer-name platform-name = tstr transducer-name = tstr Figure 16: CDDL for a sosa object IRI derived from the platform's DNS name Toutain Expires 20 March 2027 [Page 26] Internet-Draft coreconf-m2m September 2026 For example, with platform-name = "station.example.com", category = "sensor", and transducer-name = "air-temperature", the resulting object-iri is station.example.com/sensor/air-temperature, matching the example already given above. Figure 17 shows this instantiation in Turtle. @prefix sosa: . @prefix rdfs: . @prefix ccm2m: . @prefix unit: . @prefix xsd: . @prefix geo: . a sosa:Platform ; sosa:hosts ; geo:lat "48.1173"^^xsd:decimal ; geo:long "-1.6778"^^xsd:decimal ; ccm2m:accessProtocol "coreconf" ; ccm2m:coapEndpoint "coap://[2001:db8::1]"^^xsd:anyURI ; ccm2m:bootstrapSid "62002"^^ccm2m:SID . a sosa:Sensor ; sosa:isHostedBy ; sosa:observes ; ccm2m:type "10000001"^^ccm2m:SID ; ccm2m:precision 1 ; ccm2m:outputUnit unit:DEG_C . a sosa:ObservableProperty ; rdfs:label "air-temperature" ; sosa:isObservedBy . Figure 17: Concrete instantiation of the sosa:Platform/ sosa:Sensor pattern for air-temperature, with ccm2m: properties bridging back to the YANG/SID data The ccm2m: properties used above are not part of SOSA; see Section 7.1 for their meaning. SOSA has no native geo-location property either; geo:lat/geo:long, from the lightweight W3C Basic Geo (WGS84) vocabulary, are commonly paired with SOSA for this purpose, and correspond to "characteristics/geo-location" (Section 3.2.2) in the YANG model. Toutain Expires 20 March 2027 [Page 27] Internet-Draft coreconf-m2m September 2026 7.2.2. Control A sosa:Sensor or sosa:Actuator is not limited to being observed or acted upon: the actions actually available on the corresponding transducer are attached to it as ccm2m:Control instances, via ccm2m:hasControl. These cover reading the current value ("read- single"), reading or resetting its statistics ("read-stat", "reset- stat", "reset-all-stat"), configuring and subscribing to history or threshold-alert notifications ("subscribe-history", "subscribe- threshold"), and, for an actuator, writing a new value ("instant- write"). Figure 18 shows the air-temperature sosa:Sensor with its ccm2m:Control instances attached via ccm2m:hasControl, using the SIDs introduced in Section 5.2 and Section 5.3. @prefix sosa: . @prefix rdfs: . @prefix ccm2m: . @prefix unit: . @prefix ex: . ex: a sosa:Sensor ; sosa:isHostedBy ; sosa:observes ; ccm2m:type "10000001"^^ccm2m:SID ; ccm2m:precision 1 ; ccm2m:outputUnit unit:DEG_C ; ccm2m:hasControl ex:control/read-single , ex:control/reset-stat , ex:control/setup-history , ex:control/subscribe-history . ex:control/read-single a ccm2m:Control ; ccm2m:controlType "read-single" ; ccm2m:coapMethod "FETCH" ; ccm2m:coapPath "/c" ; ccm2m:targetSid "62077"^^ccm2m:SID . ex:control/reset-stat a ccm2m:Control ; rdfs:label "reset statistics" ; ccm2m:controlType "reset-stat" ; ccm2m:coapMethod "POST" ; ccm2m:coapPath "/c" ; ccm2m:targetSid "62078"^^ccm2m:SID . ex:control/setup-history a ccm2m:SetupNotification ; ccm2m:controlType "setup-history" ; Toutain Expires 20 March 2027 [Page 28] Internet-Draft coreconf-m2m September 2026 ccm2m:coapMethod "iPATCH" ; ccm2m:coapPath "/c" ; ccm2m:targetSid "62060"^^ccm2m:SID ; ccm2m:hasParam ex:control/setup-history/step , ex:control/setup-history/encoding . ex:control/setup-history/step a ccm2m:NotificationParam ; ccm2m:paramName "step" ; ccm2m:paramSid "62066"^^ccm2m:SID . ex:control/setup-history/encoding a ccm2m:NotificationParam ; ccm2m:paramName "encoding" ; ccm2m:paramSid "62062"^^ccm2m:SID . ex:control/subscribe-history a ccm2m:Control ; rdfs:label "start history notifications" ; ccm2m:controlType "subscribe-history" ; ccm2m:coapMethod "FETCH+Observe" ; ccm2m:coapPath "/s" ; ccm2m:targetSid "62048"^^ccm2m:SID . Figure 18: ccm2m:Control instances attached to the air- temperature sosa:Sensor ex:control/read-single is the same as described in Figure 8 (SID 62077, "/transducers/transducer/quantity/value"). ex:control/reset- stat is the same as the "reset-stats" action (SID 62078, "/transducers/transducer/reset-stats"), invoked with a POST to reset the statistics of this single transducer, as opposed to the "reset- all-stat" control on the platform which resets every transducer at once via the top-level "reset-stats" RPC. ex:control/setup-history is the same as the iPATCH described in Figure 11 (SID 62060, "/transducers/transducer/notification-parameters/history"), with its two configurable parameters "step" (SID 62066) and "encoding" (SID 62062); it only configures the notification and does not itself start it. ex:control/subscribe-history is the control that actually starts the history stream: it is the same as the FETCH+Observe described in Figure 13 (SID 62048, "/history/time-series/values"). A client that already knows this graph can therefore issue the corresponding CoAP requests without a separate FETCH+parse round trip on the YANG/SID files. Toutain Expires 20 March 2027 [Page 29] Internet-Draft coreconf-m2m September 2026 ccm2m:Control has no dedicated "stop" instance: as described in Section 3.3, a subscription started by subscribe-history ends when the client explicitly deregisters (a GET/FETCH with the Observe option set to 1, using the same token as subscribe-history), or when the server stops receiving acknowledgments for its Confirmable notifications. No separate SID-targeted control is needed for this, since it operates at the CoAP transport level rather than on a specific YANG resource. "category" is one of the two roles a transducer can be given, taken from its default-category (or category-override, see Section 3.1). A transducer whose category is "sensor-actuator" yields two object IRIs, one under each role, since it is instantiated as both a sosa:Sensor and a sosa:Actuator. 7.2.3. Storing Transducer Quantities Each value received from a transducer, whether from a plain FETCH or decoded from a history notification, is stored as a sosa:Observation. SOSA distinguishes two timestamps: sosa:phenomenonTime, when the device actually took the measurement, and sosa:resultTime, when the result was obtained (here, stored) by the client. For a plain FETCH of "quantity", "timestamp-source" indicates which one to use as phenomenonTime: if it is "source", the device's own "timestamp" is used; if it is "receiver", the device did not supply one, and the receiver's own local time at reception is used instead. For a single FETCH the two nearly coincide. For a history notification, phenomenonTime is reconstructed per sample from "step" as described in Section 3.3, while resultTime is the single instant at which the whole batch was received. Figure 19 shows three such observations, taken from the air-temperature values already decoded in Figure 14: all three share the same resultTime, since they were delivered together in one notification. Toutain Expires 20 March 2027 [Page 30] Internet-Draft coreconf-m2m September 2026 @prefix sosa: . @prefix xsd: . @prefix ex: . ex:observation/1 a sosa:Observation ; sosa:madeBySensor ex: ; sosa:observedProperty ; sosa:hasSimpleResult "18.9"^^xsd:decimal ; sosa:phenomenonTime "2026-09-02T09:57:42Z"^^xsd:dateTime ; sosa:resultTime "2026-09-02T10:15:45Z"^^xsd:dateTime . ex:observation/2 a sosa:Observation ; sosa:madeBySensor ex: ; sosa:observedProperty ; sosa:hasSimpleResult "20.3"^^xsd:decimal ; sosa:phenomenonTime "2026-09-02T09:59:42Z"^^xsd:dateTime ; sosa:resultTime "2026-09-02T10:15:45Z"^^xsd:dateTime . ex:observation/3 a sosa:Observation ; sosa:madeBySensor ex: ; sosa:observedProperty ; sosa:hasSimpleResult "20.0"^^xsd:decimal ; sosa:phenomenonTime "2026-09-02T10:01:42Z"^^xsd:dateTime ; sosa:resultTime "2026-09-02T10:15:45Z"^^xsd:dateTime . Figure 19: Three dated sosa:Observation instances, decoded from a history notification 7.2.4. Storing Actuator Commands A value written to a transducer via the "instant-write" control (see Section 7.2.2) is not an observation: it is a command sent to the device, not a measurement received from it. SOSA models this with sosa:Actuation rather than sosa:Observation: sosa:hasResult carries the value that was written, sosa:actsOnProperty identifies the actuatable property that was acted upon, and sosa:resultTime is when the command was issued by the client — there is no phenomenonTime, since nothing was measured. None of the ATMOS41 transducers used throughout this document is an actuator (all declare default-category: "sensor"), so Figure 20 illustrates the pattern with a fictitious device instead: a pump whose rotation speed is set through an "instant-write" command. Toutain Expires 20 March 2027 [Page 31] Internet-Draft coreconf-m2m September 2026 @prefix sosa: . @prefix xsd: . @prefix ccm2m: . @prefix unit: . @prefix ex: . ex: a sosa:Actuator ; sosa:isHostedBy ; sosa:actsOnProperty ; ccm2m:type "PPPPPP"^^ccm2m:SID ; ccm2m:precision 0 ; ccm2m:outputUnit unit:REV-PER-MIN ; ccm2m:hasControl ex:control/instant-write . ex:control/instant-write a ccm2m:Control ; ccm2m:controlType "instant-write" ; ccm2m:coapMethod "iPATCH" ; ccm2m:coapPath "/c" ; ccm2m:targetSid "62077"^^ccm2m:SID . ex:actuation/1 a sosa:Actuation ; sosa:madeByActuator ex: ; sosa:actsOnProperty ; sosa:hasResult "1500"^^xsd:integer ; sosa:resultTime "2026-09-07T14:22:10Z"^^xsd:dateTime . Figure 20: Fictitious sosa:Actuation setting a pump's rotation speed to 1500 rpm, with its ccm2m: data "PPPPPP" is a placeholder: this pump does not exist in the atmos module used throughout this document, so its identity has no real SID (unlike 10000001 for air-temperature, defined in atmos). ccm2m:targetSid, however, is the real SID 62077 for "/transducers/transducer/quantity/value": this leaf is defined in coreconf-m2m itself, not in a device-specific module, so it is the same structural node used to read air-temperature's current value in Section 7.2.2 — writing to it with an iPATCH, targeting this pump's own instance via its (fictitious) type, is the write counterpart of that same "read-single" FETCH. The pattern is otherwise symmetrical to Figure 19: sosa:Observation, sosa:observedProperty and sosa:hasSimpleResult become sosa:Actuation, sosa:actsOnProperty and sosa:hasResult, and sosa:madeBySensor becomes sosa:madeByActuator. Toutain Expires 20 March 2027 [Page 32] Internet-Draft coreconf-m2m September 2026 7.3. SensorThings Unlike SOSA/SSN, the OGC SensorThings API [SensorThings] is not a Semantic Web ontology: it is a structured, relational-like data model, exposed through a REST API inspired by OData, using plain JSON rather than RDF or JSON-LD. It defines a fixed set of entity types (Thing, Location, HistoricalLocation, Datastream, Sensor, ObservedProperty, Observation, FeatureOfInterest, and, for actuation, Actuator, Task, and TaskingCapability) linked by navigation properties, much like foreign keys between tables; most implementations are in fact backed by a relational database. Queries use OData-style $filter, $expand, and $select, rather than SPARQL. Its data model is nonetheless closely related to SOSA/SSN's concepts (Datastream/Sensor/Observation mirror sosa:Sensor/sosa:Observation), so the mapping from coreconf-m2m largely follows the same pattern as [SOSA], but produces structured, tabular entities rather than RDF triples. 7.3.1. Example Figure 21, Figure 24, and Figure 25 transpose the SOSA example of Section 7.2.2 and Figure 19 into SensorThings JSON entities, using the same station.example.com platform and air-temperature transducer. SensorThings has no equivalent of RDF's open, arbitrary predicates, so the ccm2m: extension is added as ancillary data instead: each entity's properties field is a free-form JSON object, into which the same ccm2m: keys used in the SOSA examples are placed as ordinary object members. GET /Things(1) { "@iot.id": 1, "name": "station.example.com", "description": "CORECONF-M2M platform station.example.com", "properties": { "ccm2m:accessProtocol": "coreconf", "ccm2m:bootstrapSid": 62002, "ccm2m:coapEndpoint": "coap://[2001:db8::1]" } } Figure 21: A coreconf-m2m platform as a SensorThings Thing Toutain Expires 20 March 2027 [Page 33] Internet-Draft coreconf-m2m September 2026 A Thing's properties bag is where the ccm2m: extension lives: there is no dedicated Thing property for a CoAP endpoint or a bootstrap SID, so they are carried as ancillary data instead, the same role played by ccm2m:coapEndpoint and ccm2m:bootstrapSid on a sosa:Platform. Unlike sosa:hosts, which links a sosa:Platform directly to the sosa:Sensor instances it hosts, SensorThings has no direct Thing-to- Sensor navigation link: a Sensor is only reachable through the Datastream that uses it. Finding the sensors (and, symmetrically, the actuators) associated with a Thing therefore takes an extra hop: GET /Things(1)/Datastreams { "value": [ { "@iot.id": 1, "name": "station.example.com/air-temperature", "Sensor@iot.navigationLink": "http://.../Datastreams(1)/Sensor" } ] } Figure 22: Reaching a Thing's Sensor via its Datastream i.e. Thing → Datastream → Sensor, rather than Thing → Sensor directly. The symmetric path for actuation is Thing → TaskingCapability → Actuator, via /Things(1)/TaskingCapabilities and /TaskingCapabilities(x)/Actuator. Unlike SOSA, SensorThings has a dedicated entity for geo-location: Location, reached via Thing/Locations (a Thing can have more than one, and a Location can be shared by several Things). GET /Things(1)/Locations { "value": [{ "@iot.id": 1, "name": "station.example.com location", "encodingType": "application/vnd.geo+json", "location": { "type": "Point", "coordinates": [-1.6778, 48.1173] } }] } Toutain Expires 20 March 2027 [Page 34] Internet-Draft coreconf-m2m September 2026 Figure 23: A Thing's Location, the SensorThings equivalent of the geo:lat/ geo:long pair used with SOSA This corresponds to the same "characteristics/geo-location" (Section 3.2.2) as the geo:lat/geo:long pair used in Figure 17. HistoricalLocations additionally tracks changes of Location over time, for a mobile device. GET /Sensors(1) { "@iot.id": 1, "name": "air-temperature", "description": "air-temperature on station.example.com", "encodingType": "application/pdf", "metadata": "https://metergroup.com/documents/ATMOS41-Manual.pdf", "properties": { "ccm2m:type": 10000001, "ccm2m:precision": 1 } } GET /Datastreams(1) { "@iot.id": 1, "name": "station.example.com/air-temperature", "description": "air-temperature measured by station.example.com", "observationType": "http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement", "unitOfMeasurement": { "definition": "http://qudt.org/vocab/unit/DEG_C", "name": "http://qudt.org/vocab/unit/DEG_C", "symbol": "Cel" } } Figure 24: The air-temperature Sensor and its Datastream Toutain Expires 20 March 2027 [Page 35] Internet-Draft coreconf-m2m September 2026 A Sensor's encodingType/metadata pair describes its datasheet, not its identity: metadata is a URL to that document (or the document itself, for a text-based encodingType), and encodingType says what format it is in — application/pdf and SensorML are the two most common in practice. The Sensor's ccm2m:type plays the same role as on a sosa:Sensor. Unlike SOSA, where ccm2m:outputUnit had to be added because SOSA has no native concept of unit, a Datastream already carries unitOfMeasurement natively (a QUDT IRI, symbol, and name), so no ccm2m: property is needed for it here. An ObservedProperty entity (not shown), linked from the Datastream, plays the role of sosa:ObservableProperty. GET /Datastreams(1)/Observations?$top=3&$orderby=phenomenonTime desc { "value": [ { "@iot.id": 1, "phenomenonTime": "2026-09-02T09:57:42Z", "resultTime": "2026-09-02T10:15:45Z", "result": 18.9 }, { "@iot.id": 2, "phenomenonTime": "2026-09-02T09:59:42Z", "resultTime": "2026-09-02T10:15:45Z", "result": 20.3 }, { "@iot.id": 3, "phenomenonTime": "2026-09-02T10:01:42Z", "resultTime": "2026-09-02T10:15:45Z", "result": 20.0 } ] } Figure 25: Three dated Observations, the SensorThings equivalent of fig-sosa- observations These are the same three samples as Figure 19: result plays the role of sosa:hasSimpleResult, already a plain JSON number rather than a typed literal, and phenomenonTime/resultTime carry the same distinction as sosa:phenomenonTime/sosa:resultTime — all three share one resultTime, since they were delivered together in one history notification, while phenomenonTime is reconstructed per sample from "step". Toutain Expires 20 March 2027 [Page 36] Internet-Draft coreconf-m2m September 2026 For actuation, SensorThings has a separate set of entities (the "Tasking Core" profile): Actuator, TaskingCapability, and Task, mirroring Sensor, Datastream, and Observation respectively. Figure 26 transposes the fictitious pump of Figure 20 into these entities. GET /Actuators(1) { "@iot.id": 1, "name": "rotation-speed", "description": "rotation-speed actuator on pump.example.com", "encodingType": "application/pdf", "metadata": "https://pump.example.com/docs/pump-datasheet.pdf", "properties": { "ccm2m:type": "PPPPPP" } } GET /TaskingCapabilities(1) { "@iot.id": 1, "name": "pump.example.com/rotation-speed", "description": "Set the pump's rotation speed", "taskingParameters": { "type": "object", "properties": { "rotation-speed": { "type": "integer" } } }, "properties": { "ccm2m:targetSid": 62077 } } GET /TaskingCapabilities(1)/Tasks { "value": [{ "@iot.id": 1, "creationTime": "2026-09-07T14:22:10Z", "taskingParameters": { "rotation-speed": 1500 } }] } Figure 26: Actuator, TaskingCapability, and Task, the SensorThings equivalent of fig-sosa-actuation Toutain Expires 20 March 2027 [Page 37] Internet-Draft coreconf-m2m September 2026 The Actuator plays the same role as the Sensor of Figure 24, including the same application/pdf/metadata pattern for its datasheet. ccm2m:targetSid on the TaskingCapability plays the role of ccm2m:targetSid on the SOSA ccm2m:Control for "instant-write": both name the SID to iPATCH to actually issue the command. A Task's taskingParameters plays the role of sosa:hasResult, and creationTime of sosa:resultTime; as with the Sensor's ccm2m:type, "PPPPPP" is a placeholder, since this pump has no real identity SID. 7.4. SAREF To be defined. 8. MCP CORECONF/CoAP and the SensorThings/FROST database are both, in essence, REST-style interfaces: a small set of operations (read, write, query, subscribe) applied to addressable resources. Each can therefore be documented as a set of typed, named operations and exposed to an AI agent as an MCP (Model Context Protocol) server, rather than requiring the agent to construct raw CoAP/CBOR or FROST query requests itself. This document's companion implementation uses two such servers, kept separate because they act on two different things: one performs live CoAP actions against the physical device, the other queries and edits the structured historical data already stored in FROST. The "coreconf-m2m" MCP server wraps live device actions, each tool resolving what it needs (the platform's CoAP endpoint, the sensor's identity/instance SIDs, the target field SID) from the FROST database before issuing the corresponding CoAP request: * read_instant(hostname, sensor) — FETCH the current value, already scaled by the sensor's ccm2m:precision; * read_stat(hostname, sensor) — FETCH accumulated statistics (min/max/mean/median/stdev/sample-count), scaled; * start_history_notify(hostname, sensor, step_ms, max_samples, check_interval) — iPATCH to configure, then FETCH+Observe to start, a history-notification subscription; incoming samples are written to FROST as Observations as they arrive; * stop_history_notify(hostname, sensor) — cancel a running subscription; Toutain Expires 20 March 2027 [Page 38] Internet-Draft coreconf-m2m September 2026 * list_active_history_subscriptions() — list every subscription currently running, across clients. The "frost-sensorthings" MCP server wraps the SensorThings REST API itself, generically (not tied to the ccm2m ontology), respecting FROST's own query syntax, on any of the entity sets of Section 7.3: * list_service_capabilities() — the entity sets this FROST-Server instance exposes; * query_entities(entity_set, filter, expand, select, orderby, top, skip, count) — list/filter an entity set, e.g. query_entities( "Observations", filter="phenomenonTime gt 2026-07-01T00:00:00Z", orderby="phenomenonTime desc", top=20); * get_entity(entity_set, entity_id, expand, select) — get one entity by its @iot.id; * get_related(entity_set, entity_id, relation, ...) — navigate a relationship, e.g. get_related("Things", 1, "Datastreams") (see Figure 22); * create_entity, update_entity, delete_entity — write access. Because both servers resolve identities (SIDs, hostnames, sensor names) against the same FROST database, an agent can freely mix tools from both — e.g. list a Thing's Datastreams via get_related, then call read_instant for one of them — without separately tracking SID files or CoAP endpoints itself. Figure 27 illustrates this with a concrete question: "what is the temperature right now in Rennes?" The agent first uses FROST to turn "Rennes" into a device and a sensor, then uses coreconf-m2m to read that sensor live; the result is written back to FROST as it comes in, so a later question about the same value would find it already there instead of triggering a new CoAP exchange. Toutain Expires 20 March 2027 [Page 39] Internet-Draft coreconf-m2m September 2026 Device MCP CoreCONF MCP Frost LLM | | | | query_entities("Things", filter: near Rennes) | | <-------------------| | | | | Thing, ccm2m:coapEndpoint | | |-------------------> | | | | get_related(Thing, "Datastreams") | | <-------------------| | | | | Sensor SID, precision | | |-------------------> | | | | read_instant(hostname, sensor) | <---------------------------------------| | | | | resolve endpoint/SIDs | |-------------------> | | | | | endpoint, type SID | <-------------------| | | | | | FETCH quantity/value <-----------------| | | | | | | 2.05 Content (raw value) |-----------------> | | | | | | create Observation (store result) | |-------------------> | | | | | scaled value + unit | |---------------------------------------> | | | | Figure 27: Answering "what is the temperature right now in Rennes?" by combining the frost-sensorthings and coreconf-m2m MCP servers The LLM then answers the user directly from the value returned in the last step, e.g. "It's 19.6 C in Rennes". Toutain Expires 20 March 2027 [Page 40] Internet-Draft coreconf-m2m September 2026 It should be noted that the LLM selects the appropriate sensor from its name, "air-temperature": without the mapping between the identityref SID and the associated name, the LLM would not have been able to retrieve the information. More exhaustively, the LLM may also have access to the YANG data model describing the device, and use its descriptions to gain a better understanding of the device. 9. Compression 9.1. SID translation Official YANG SIDs [I-D.ietf-core-sid] are globally unique integers, but that global scope makes them larger than strictly necessary on a link where only two endpoints ever talk to each other and no third- party CORECONF implementation needs to be interoperable with. [I-D.toutain-core-private-sid-translation] defines a mechanism for such closed deployments: each official SID is transformed, purely arithmetically, into a small negative integer, as a "private SID", which encodes in a smaller CBOR sequence. The transformation is: privateSID = (offset - 1) - (current_sid - entry_point) where entry_point is the lowest SID officially allocated to the YANG Data Model the SID belongs to, and offset is a non-positive integer that shifts the model's private range so that it does not overlap with another translated model's range. With offset = 0, the node at entry_point maps to -1, the next one to -2, and so on: offset lets a second, third, etc. model be translated in the same session by shifting each one's private range further into negative territory, without changing the formula itself or which module a given negative SID belongs to. Both endpoints MUST share the same entry_point and offset per model for the translation to be consistent. More generally, a coreconf-m2m deployment involves at least two kinds of YANG Data Models translated together: the coreconf-m2m model itself, together with augmentations it may receive, and one or more device-description models, such as atmos in this document's examples. If coreconf-m2m is eventually standardized as an IETF model, its SIDs will sit in the low thousands, while device-description models, being commercial and vendor-specific, are expected to be assigned SIDs in a Registrar's block or a Private Enterprise Number range [RFC9371] both starting much higher. The device-description model SHOULD therefore be given the smaller offset (typically 0, the deepest range), and the coreconf-m2m model the larger one (or not translated). Appendix H works out this recommendation on two concrete examples. Toutain Expires 20 March 2027 [Page 41] Internet-Draft coreconf-m2m September 2026 A SID that falls outside every configured (entry_point, offset) pair is simply sent as its official value, without breaking any SID that is left out. 9.2. SCHC The traffic profile given in Section 4.1 recommends limiting exchanges to FETCH and iPATCH. This limits the number of rules needed to compress coreconf-m2m traffic with SCHC [RFC8724]. Appendix G gives an example where two rules are used to cover the bidirectional traffic for FETCH and iPATCH (Rules 0 and 1). Another rule is related to notifications, carrying an Observe option (Rule 2). It is important to also cover error messages. The example defines one generic CoAP rule to cover any TYPE and CODE, without options, corresponding to error notifications (Rule 3), and one rule for ICMP traffic, to inform the server that the client is no longer active (Rule 4). 10. Conclusion This document has shown that it is possible to seamlessly interconnect a YANG data model to the ontologies used by domain professionals. 1. Devices cannot directly use such an ontology representation themselves, since it is too verbose for a constrained device. 2. RESTCONF and NETCONF, using JSON or XML, are also too verbose, so the benefit of mapping directly from them to an ontology is limited. 3. CORECONF is constrained, and this constrained representation is what lets a device benefit from the ontology mapping without paying its verbosity cost. 4. The ontology is used to store all the information concerning the systems. 5. CORECONF uses the ontology information to form its requests. 6. Naming is very important, and DNS will play an important role in automatically mapping a SID into a name. 7. Names are used both to form names in the ontology and to allow an LLM to identify resources. Toutain Expires 20 March 2027 [Page 42] Internet-Draft coreconf-m2m September 2026 8. Interoperability is possible since coreconf-m2m offers a strict data representation of the information, and allows a systematic conversion into the ontology. Based on the coreconf-m2m model, a device manufacturer only has to publish its data model, with its identityref identities, for that device to be included into the ontology and be understood by humans or by an LLM. 11. Security Considerations CORECONF operations over CoAP MUST be secured using either DTLS [RFC6347] or OSCORE [RFC8613]. In M2M scenarios where a central manager is absent, the trust model requires particular attention. 12. IANA Considerations 12.1. YANG Module Registration This document registers the following YANG module in the "YANG Module Names" registry [RFC7950]: +=========+=======================================+======+=========+ | Name | Namespace |Prefix|Reference| +=========+=======================================+======+=========+ |coreconf-| urn:ietf:params:xml:ns:yang:coreconf- | cm2m | This | | m2m | m2m | | document| +---------+---------------------------------------+------+---------+ Table 1 12.2. SID Range Allocation This document requests the SID range starting at entry-point TBD with a size of 100, as defined in [I-D.ietf-core-sid]. Transducer identites MUST be sperated from this document and defined in anjother YANG module. 13. References 13.1. Normative References Toutain Expires 20 March 2027 [Page 43] Internet-Draft coreconf-m2m September 2026 [I-D.ietf-core-comi] Veillette, M., Van der Stok, P., Pelov, A., Bierman, A., and C. Bormann, "CoAP Management Interface (CORECONF)", Work in Progress, Internet-Draft, draft-ietf-core-comi-21, 2 March 2026, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC7252] Shelby, Z., Hartke, K., and C. Bormann, "The Constrained Application Protocol (CoAP)", RFC 7252, DOI 10.17487/RFC7252, June 2014, . [RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", RFC 7950, DOI 10.17487/RFC7950, August 2016, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC8610] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, June 2019, . [RFC8724] Minaburo, A., Toutain, L., Gomez, C., Barthel, D., and JC. Zuniga, "SCHC: Generic Framework for Static Context Header Compression and Fragmentation", RFC 8724, DOI 10.17487/RFC8724, April 2020, . [RFC8824] Minaburo, A., Toutain, L., and R. Andreasen, "Static Context Header Compression (SCHC) for the Constrained Application Protocol (CoAP)", RFC 8824, DOI 10.17487/RFC8824, June 2021, . [RFC9165] Bormann, C., "Additional Control Operators for the Concise Data Definition Language (CDDL)", RFC 9165, DOI 10.17487/RFC9165, December 2021, . Toutain Expires 20 March 2027 [Page 44] Internet-Draft coreconf-m2m September 2026 [RFC9254] Veillette, M., Ed., Petrov, I., Ed., Pelov, A., Bormann, C., and M. Richardson, "Encoding of Data Modeled with YANG in the Concise Binary Object Representation (CBOR)", RFC 9254, DOI 10.17487/RFC9254, July 2022, . [RFC9363] Minaburo, A. and L. Toutain, "A YANG Data Model for Static Context Header Compression (SCHC)", RFC 9363, DOI 10.17487/RFC9363, March 2023, . 13.2. Informative References [I-D.birkholz-yang-core-telemetry] Birkholz, H. and E. Voit, "Concise YANG Telemetry", Work in Progress, Internet-Draft, draft-birkholz-yang-core- telemetry-01, 16 July 2018, . [I-D.gudi-t2trg-senml-as-coreconf] G, M., Toutain, L., Fernandez, A., and J. BONNIN, "SenML is CORECONF (almost)", Work in Progress, Internet-Draft, draft-gudi-t2trg-senml-as-coreconf-00, 7 October 2024, . [I-D.ietf-core-sid] Veillette, M., Pelov, A., Petrov, I., Bormann, C., and M. Richardson, "YANG Schema Item iDentifier (YANG SID)", Work in Progress, Internet-Draft, draft-ietf-core-sid-24, 22 December 2023, . [I-D.toutain-core-private-sid-translation] Toutain, L., "Private SID Translation for CORECONF", Work in Progress, Internet-Draft, draft-toutain-core-private- sid-translation-00, 31 May 2026, . [I-D.toutain-core-sid-encoding] Balakrichenan, S., Pelov, A., and L. Toutain, "YANG SID Discovery Using the Domain Name System", Work in Progress, Internet-Draft, draft-toutain-core-sid-encoding-00, 1 July 2026, . Toutain Expires 20 March 2027 [Page 45] Internet-Draft coreconf-m2m September 2026 [OMA-LwM2M] "Lightweight Machine to Machine Technical Specification: Core", 2020, . [RFC6347] Rescorla, E. and N. Modadugu, "Datagram Transport Layer Security Version 1.2", RFC 6347, DOI 10.17487/RFC6347, January 2012, . [RFC7228] Bormann, C., Ersue, M., and A. Keranen, "Terminology for Constrained-Node Networks", RFC 7228, DOI 10.17487/RFC7228, May 2014, . [RFC7396] Hoffman, P. and J. Snell, "JSON Merge Patch", RFC 7396, DOI 10.17487/RFC7396, October 2014, . [RFC8376] Farrell, S., Ed., "Low-Power Wide Area Network (LPWAN) Overview", RFC 8376, DOI 10.17487/RFC8376, May 2018, . [RFC8428] Jennings, C., Shelby, Z., Arkko, J., Keranen, A., and C. Bormann, "Sensor Measurement Lists (SenML)", RFC 8428, DOI 10.17487/RFC8428, August 2018, . [RFC8613] Selander, G., Mattsson, J., Palombini, F., and L. Seitz, "Object Security for Constrained RESTful Environments (OSCORE)", RFC 8613, DOI 10.17487/RFC8613, July 2019, . [RFC8639] Voit, E., Clemm, A., Gonzalez Prieto, A., Nilsen-Nygaard, E., and A. Tripathy, "Subscription to YANG Notifications", RFC 8639, DOI 10.17487/RFC8639, September 2019, . [RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, . [RFC9179] Hopps, C., "A YANG Grouping for Geographic Locations", RFC 9179, DOI 10.17487/RFC9179, February 2022, . Toutain Expires 20 March 2027 [Page 46] Internet-Draft coreconf-m2m September 2026 [RFC9232] Song, H., Qin, F., Martinez-Julia, P., Ciavaglia, L., and A. Wang, "Network Telemetry Framework", RFC 9232, DOI 10.17487/RFC9232, May 2022, . [RFC9371] Baber, A. and P. Hoffman, "Registration Procedures for Private Enterprise Numbers (PENs)", RFC 9371, DOI 10.17487/RFC9371, March 2023, . [SAREF] "SAREF: the Smart Applications REFerence ontology", 2020, . [SCHC-TOWARD-9363BIS] Toutain, L., "Toward RFC 9363bis: Changes to the SCHC YANG Data Model", 2026. [SensorThings] "OGC SensorThings API Part 1: Sensing", 2016, . [SOSA] "Semantic Sensor Network Ontology", 2017, . Appendix A. Module Tree module: coreconf-m2m +--ro bootstrap | +--ro reference-epoch? uint64 | +--ro uptime uint64 | +--ro minimal-step? uint32 | +--ro inventory* [type] | +--ro type identityref | +--ro unit-override? string | +--ro precision-override? uint8 | +--ro category-override? enumeration +--rw characteristics | +--rw geo-location | | +--rw reference-frame | | | +--rw alternate-system? string {alternate-systems}? | | | +--rw astronomical-body? string | | | +--rw geodetic-system | | | +--rw geodetic-datum? string | | | +--rw coord-accuracy? decimal64 | | | +--rw height-accuracy? decimal64 | | +--rw (location)? | | | +--:(ellipsoid) | | | | +--rw latitude? decimal64 Toutain Expires 20 March 2027 [Page 47] Internet-Draft coreconf-m2m September 2026 | | | | +--rw longitude? decimal64 | | | | +--rw height? decimal64 | | | +--:(cartesian) | | | +--rw x? decimal64 | | | +--rw y? decimal64 | | | +--rw z? decimal64 | | +--rw velocity | | | +--rw v-north? decimal64 | | | +--rw v-east? decimal64 | | | +--rw v-up? decimal64 | | +--rw timestamp? yang:date-and-time | | +--rw valid-until? yang:date-and-time | +--rw name? string | +--rw version? string | +--rw identifier? string | +--rw description? string | +--rw manufacturer? string | +--rw model? string | +--rw hosted-by? string | +--rw installation-time? uint64 +--rw transducers +--rw transducer* [type] +--rw type identityref +--ro quantity | +--ro value? int64 | +--ro timestamp? uint64 | +--ro timestamp-source? enumeration +--ro statistics | +--ro min? int64 | +--ro max? int64 | +--ro mean? int64 | +--ro median? int64 | +--ro stdev? uint64 | +--ro sample-count? uint64 +--rw notification-parameters | +--rw history | | +--ro active? boolean | | +--rw step? uint32 | | +--rw precision? uint8 | | +--rw max-samples? uint32 | | +--rw time-period? uint32 | | +--rw encoding? encoding-type | | +--rw max-payload? uint32 | +--rw sensor-alert | | +--ro active? boolean | | +--rw t-min? int32 | | +--rw t-max? int32 | | +--rw hysteresis? uint8 Toutain Expires 20 March 2027 [Page 48] Internet-Draft coreconf-m2m September 2026 | | +--rw dampening? uint32 | +--rw check-interval? uint16 +---x reset-stats rpcs: +---x reset-stats notifications: +---n history | +--ro last? boolean | +--ro time-series* [type] | +--ro type identityref | +--ro values* int64 | +--ro internal | +--ro last-update? uint64 | +--ro start-time? uint64 | +--ro messages-sent? uint64 +---n sensor-alert +--ro target* [type] +--ro type identityref +--ro value? int64 Figure 28: coreconf-m2m module tree Appendix B. Complete YANG Module file "coreconf-m2m@2026-09-01.yang" module coreconf-m2m { yang-version 1.1; namespace "urn:ietf:params:xml:ns:yang:coreconf-m2m"; prefix ccm2m; import ietf-geo-location { prefix geo; reference "RFC 9179"; } organization "IETF"; contact "Internet Engineering Task Force (IETF) https://www.ietf.org/"; description "YANG data model for a generic M2M CoMI weather station. This model defines the operational state data for sensor readings."; revision 2026-09-01 { description Toutain Expires 20 March 2027 [Page 49] Internet-Draft coreconf-m2m September 2026 "Move container statistics out of container quantity, making it a sibling of quantity under list transducer. Statistics accumulate over a window and are not part of the current measurement, so nesting them under quantity conflated two different lifetimes and cost one extra level of delta encoding on every statistics access. This reverts the nesting introduced in revision 2026-03-29."; } revision 2026-08-28 { description "Rename the 'states' container to 'bootstrap', since it holds operational data determined once at bootstrap time. Split the transducer list: unit-override, precision-override and category-override are moved out of /transducers/transducer into a new /bootstrap/inventory list (also keyed by type). This list describes the fixed configuration of each transducer instance, determined at bootstrap and not expected to change afterwards, separately from the transducer's runtime data (quantity, statistics, notification parameters) which stays in /transducers/transducer. Hoist check-interval from notification-parameters/history and notification-parameters/sensor-alert to notification-parameters: it was defined identically in both containers, and a single CON/NON cadence now applies to both notification streams."; } revision 2026-08-24 { description "Remove type from list keys; id alone now identifies a transducer instance, distinguishing multiple actuators of the same type. This reduces the key size. Add a reference-epoch leaf in the state container; other epochs in the model are relative to this one. Move all concrete transducer-type identities (solar-radiation, precipitation, air-temperature, relative-humidity, barometric-pressure, vapor-pressure, wind-speed, wind-direction, wind-gust, north-wind-speed, east-wind-speed, strike-count, average-distance, tilt, x-orientation, y-orientation, humidity-sensor-temperature, compass-heading) out of coreconf-m2m and into the new atmos module; coreconf-m2m now only defines the base transducer-type identity, which product-specific modules extend. Rename transducer/unit and transducer/precision to unit-override and precision-override (both now optional, no default): they only need to be set when they differ from the default-unit/default-precision extension declared on the transducer's type identity. Add default-unit and default-precision extensions, for use by product-specific modules (e.g. atmos) annotating the transducer-type identities they define. Toutain Expires 20 March 2027 [Page 50] Internet-Draft coreconf-m2m September 2026 Add SOSA/SAREF-aligned leafs to the characteristics container (description, manufacturer, model, hosted-by, installation-time); move uptime back into states, as bootstrap operational data. Add default-category extension, for product-specific modules to mark each transducer-type identity as 'sensor', 'actuator' or 'sensor-actuator', and a matching category-override leaf on the transducer list for per-instance overrides. Remove u-timestamp: all timestamps are now second-resolution only; sub-second precision would require a model update. Change history/step units from milliseconds to seconds, for the same reason. Add minimal-step leaf in states and a must constraint requiring history/step >= states/minimal-step. Move geo-location from states into characteristics: it is configuration data set once at deployment, not runtime state. Make states/uptime mandatory. Revert the id-based key: transducer, transducers-list/time-series and sensor-alert/target are again keyed on type alone, and the id leaf is removed from all three lists (only one transducer per type is supported)."; } revision 2026-06-07 { description "Add humidity-sensor-temperature and compass-heading transducer-type identities."; } revision 2026-05-26 { description "Add check-interval leaf to history and sensor-alert notification parameters."; } revision 2026-03-29 { description "Move container statistics inside container quantity."; } revision 2026-03-25 { description "Add dampening leaf to sensor-alert notification parameters."; } revision 2026-03-23 { description "Make active leaf config false (reflects observe subscription state). Add must constraint t-min < t-max on sensor-alert. Add timestamp-source enum in quantity to indicate timestamp origin (source = timestamped by the sensor, receiver = timestamped on receipt)."; Toutain Expires 20 March 2027 [Page 51] Internet-Draft coreconf-m2m September 2026 } revision 2026-03-22 { description "Rename branch measurement to transducer (container, list, identity, notification)."; } revision 2026-03-08 { description "Module renamed to coreconf-m2m for generic M2M CoMI use."; } revision 2026-03-02 { description "Major update for CoMI compliance: - Added multi-sensor support (id key). - Measurements are now configurable (writable). - Added standard deviation (stdev). - Added uptime to state. - Removed tilt from fixed state (now a measurement type). - Removed legacy RPCs (subscribe, get-stats) in favor of CoMI/Observe. - Cleaned up measurement lists and notifications."; } revision 2026-02-27 { description "Initial revision for testing."; } /* ------------------------------------------------------------------ */ /* Extensions */ /* ------------------------------------------------------------------ */ extension default-unit { argument "senml-unit"; description "Recommended default value for a transducer's unit-override leaf, expressed as a SenML (RFC 8428) unit string. Applied by product-specific modules to the transducer-type identities they define. Intended as guidance for clients populating /transducers/transducer/unit-override; not enforced by the schema."; } extension default-precision { argument "decimal-places"; description "Recommended default value for a transducer's precision-override leaf Toutain Expires 20 March 2027 [Page 52] Internet-Draft coreconf-m2m September 2026 (number of decimal places, i.e. real value = raw_value * 10^-precision) when using the default-unit. Applied by product-specific modules to the transducer-type identities they define. Intended as guidance for clients populating /transducers/transducer/precision-override; not enforced by the schema."; } extension default-category { argument "category"; description "Recommended default value for a transducer's category-override leaf. Extension arguments are plain strings and cannot be constrained to an enumeration by the YANG language itself; the value SHOULD be one of the category-override enums: 'sensor' (the transducer-type identity represents an observed property), 'actuator' (it represents a property acted upon), or 'sensor-actuator' (both). Applied by product-specific modules to the transducer-type identities they define, since this role is a property of the measurement type, not of the device as a whole (a device can carry a mix of sensor- and actuator-typed transducers). For example, in the SOSA/SSN ontology 'sensor' corresponds to sosa:Sensor/sosa:ObservableProperty and 'actuator' to sosa:Actuator; in SAREF they correspond to the SensingFunction and ActuatingFunction classes respectively."; } /* ------------------------------------------------------------------ */ /* Measurement-type identity hierarchy */ /* ------------------------------------------------------------------ */ identity transducer-type { description "Base identity for all measurement types. Concrete transducer types are defined by product-specific modules, e.g. atmos."; } /* ------------------------------------------------------------------ */ /* Typedefs */ /* ------------------------------------------------------------------ */ typedef encoding-type { type enumeration { enum direct { value 0; description "Value is encoded directly as an integer."; } enum delta { Toutain Expires 20 March 2027 [Page 53] Internet-Draft coreconf-m2m September 2026 value 1; description "Value is encoded as a delta from the previous value."; } } description "Encoding used for the measurement values."; } /* ------------------------------------------------------------------ */ /* Shared grouping used by notifications */ /* ------------------------------------------------------------------ */ grouping transducers-list { list time-series { key "type"; description "List of measurements included in this notification."; leaf type { type identityref { base transducer-type; } description "The type of measurement (e.g., air-temperature)."; } leaf-list values { type int64; ordered-by user; description "List of encoded measurement values."; } } } /* ------------------------------------------------------------------ */ /* State data */ /* ------------------------------------------------------------------ */ container bootstrap { config false; description "Operational data determined once at bootstrap time."; leaf reference-epoch { type uint64; units "seconds"; description "Epoch timestamp used as the reference point for the device's internal clock. Other epoch/timestamp values in this model are Toutain Expires 20 March 2027 [Page 54] Internet-Draft coreconf-m2m September 2026 relative to this reference epoch."; } leaf uptime { type uint64; units "seconds"; mandatory true; description "Time elapsed since the last boot."; } leaf minimal-step { type uint32; units "seconds"; description "Minimum interval at which the underlying system refreshes transducer values, i.e. the smallest meaningful value for history/step. Determined by the hardware/firmware and not configurable (e.g. an atmospheric station may have a minimal-step of 120 seconds)."; } list inventory { key "type"; description "List of transducers known to the device, with their per-instance configuration overrides. Determined once at bootstrap and not expected to change afterwards."; leaf type { type identityref { base transducer-type; } description "The type of measurement."; } leaf unit-override { type string; description "Unit of measurement (e.g., 'Cel', 'm/s', '%'), overriding the default-unit extension declared on the transducer's type identity (if any). When absent, clients should use that identity's default-unit; if the identity declares no default-unit, the unit is undefined."; } leaf precision-override { type uint8; description Toutain Expires 20 March 2027 [Page 55] Internet-Draft coreconf-m2m September 2026 "Number of decimal places for the measurement value (real value = raw_value * 10^-precision), overriding the default-precision extension declared on the transducer's type identity (if any). Applies to the current measurement value (polling/iPATCH), not to the time-series encoding in notifications. When absent, clients should use that identity's default-precision; if the identity declares no default-precision, the precision is undefined."; } leaf category-override { type enumeration { enum sensor { description "The transducer represents an observed property."; } enum actuator { description "The transducer represents a property acted upon."; } enum sensor-actuator { description "The transducer both observes and can be acted upon (e.g. a setpoint that also reports the measured value)."; } } description "Role of this transducer instance, overriding the default-category extension declared on the transducer's type identity (if any). When absent, clients should use that identity's default-category; if the identity declares no default-category, the role is undefined."; } } } /* ------------------------------------------------------------------ */ /* Device Characteristics */ /* ------------------------------------------------------------------ */ container characteristics { description "Static descriptive information about the device."; uses geo:geo-location { description "Fixed geographic position of the weather station. Populated once at deployment; not expected to change during normal operation."; refine "geo-location/reference-frame/geodetic-system/geodetic-datum" { Toutain Expires 20 March 2027 [Page 56] Internet-Draft coreconf-m2m September 2026 default "wgs-84"; } } leaf name { type string; description "Human-readable name of the device."; } leaf version { type string; description "Firmware or software version of the device."; } leaf identifier { type string; description "Unique identifier of the device (e.g., serial number or EUI)."; } leaf description { type string; description "Free-text description of the device, its purpose or its deployment context. For example, in SOSA/SSN this corresponds to rdfs:comment on the sosa:Sensor/sosa:Platform individual, and in SAREF to saref:hasDescription."; } leaf manufacturer { type string; description "Name of the device manufacturer. For example, in SAREF this corresponds to saref:hasManufacturer."; } leaf model { type string; description "Commercial model name/number of the device. For example, in SAREF this corresponds to saref:hasModel."; } leaf hosted-by { type string; description "Identifier of the platform hosting this device, when applicable. Left as an opaque string here; resolution to an actual platform resource is deployment-specific. For example, in SOSA this Toutain Expires 20 March 2027 [Page 57] Internet-Draft coreconf-m2m September 2026 corresponds to the sosa:isHostedBy relation (device -> sosa:Platform)."; } leaf installation-time { type uint64; units "seconds"; description "Absolute Unix epoch timestamp (UTC) at which the device was installed/commissioned. Unlike bootstrap/reference-epoch, this is an absolute epoch value, not a relative reference point for the device's internal clock."; } } /* ------------------------------------------------------------------ */ /* Measurements Configuration & Data */ /* ------------------------------------------------------------------ */ container transducers { // config true (default); description "Current measurement values accessible via polling or configuration."; list transducer { key "type"; description "List of available measurements."; leaf type { type identityref { base transducer-type; } description "The type of measurement."; } container quantity { config false; description "Operational state for this transducer."; leaf value { type int64; description "The current raw integer value of the transducer."; } leaf timestamp { type uint64; Toutain Expires 20 March 2027 [Page 58] Internet-Draft coreconf-m2m September 2026 units "seconds"; description "Epoch timestamp (seconds) of the last transducer update."; } leaf timestamp-source { type enumeration { enum source { value 0; description "The timestamp was generated by the sensor itself."; } enum receiver { value 1; description "The timestamp was applied by the receiver upon message arrival."; } } description "Indicates the origin of the timestamp associated with this measurement."; } } container statistics { config false; description "Read-only accumulated statistics for this measurement."; leaf min { type int64; description "Minimum value observed since last reset."; } leaf max { type int64; description "Maximum value observed since last reset."; } leaf mean { type int64; description "Mean value observed since last reset."; } leaf median { type int64; description "Estimated median value observed since last reset. This median is computed incrementally from the current stored statistics and the newest sample, without keeping full history."; } Toutain Expires 20 March 2027 [Page 59] Internet-Draft coreconf-m2m September 2026 leaf stdev { type uint64; description "Standard deviation of values observed since last reset. Scaled by same precision as value."; } leaf sample-count { type uint64; description "Number of samples used for statistics calculation."; } } container notification-parameters { description "Configuration parameters controlling how this transducer is reported in CoMI notification streams."; container history { description "Parameters for the history time-series stream."; leaf active { type boolean; config false; description "Read-only. True when a FETCH+Observe subscription is active on /s for this transducer history stream. False when no observer is registered."; } leaf step { type uint32; units "seconds"; must ". >= /bootstrap/minimal-step or not(/bootstrap/minimal-step)" { error-message "step must be greater than or equal to bootstrap/minimal-step."; } description "Time interval between samples in the notification stream. Must be at least bootstrap/minimal-step, the system's minimum refresh interval."; } leaf precision { type uint8; default 1; description "Number of decimal places for values encoded in time-series notifications. Real value = raw_value * 10^-precision."; Toutain Expires 20 March 2027 [Page 60] Internet-Draft coreconf-m2m September 2026 } leaf max-samples { type uint32; description "Maximum number of samples kept in the time-series buffer."; } leaf time-period { type uint32; units "seconds"; description "Duration of the time window covered by the history buffer."; } leaf encoding { type encoding-type; default "delta"; description "Encoding used for the values list in notifications."; } leaf max-payload { type uint32; units "bytes"; description "Maximum size in bytes of the encoded time-series payload in a single history notification. When the encoded buffer would exceed this limit, the notification is sent early (before max-samples or time-period is reached). 0 means no size limit."; } } container sensor-alert { description "Parameters for threshold-based sensor-alert notifications."; must "not(t-min and t-max) or t-min < t-max" { error-message "t-min must be strictly less than t-max."; } leaf active { type boolean; config false; description "Read-only. True when a FETCH+Observe subscription is active on /s for this transducer sensor-alert stream. False when no observer is registered."; } leaf t-min { type int32; Toutain Expires 20 March 2027 [Page 61] Internet-Draft coreconf-m2m September 2026 description "Minimum threshold value. A sensor-alert is raised when the transducer value falls below this value."; } leaf t-max { type int32; description "Maximum threshold value. A sensor-alert is raised when the transducer value exceeds this value."; } leaf hysteresis { type uint8 { range "0..100"; } default 5; units "percent"; description "Hysteresis applied to threshold crossings, expressed as a percentage of the threshold value."; } leaf dampening { type uint32; default 0; units "milliseconds"; description "Minimum time that must elapse between two consecutive sensor-alert notifications for the same transducer. A new alert is suppressed until the dampening period has expired since the last sent alert. 0 (default) means no dampening."; } } leaf check-interval { type uint16; default 0; description "Controls how often a CON (confirmable) notification is sent instead of NON (non-confirmable), for both the history and sensor-alert streams of this transducer. 0 = disabled, all notifications are NON. 1 = every notification is CON. N = one CON every N notifications, all others are NON."; } } Toutain Expires 20 March 2027 [Page 62] Internet-Draft coreconf-m2m September 2026 action reset-stats { description "Reset the accumulated statistics (min, max, mean, median, stdev) for this measurement. Counters restart from the next sample received."; } } } /* ------------------------------------------------------------------ */ /* RPCs */ /* ------------------------------------------------------------------ */ rpc reset-stats { description "Reset the accumulated statistics for all measurements. The counters restart from the next sample received after the call."; } /* ------------------------------------------------------------------ */ /* Notifications */ /* ------------------------------------------------------------------ */ notification history { description "Measurement event sent to observers of the notification stream. To receive this, a CoLA/CoMI client must Observe the stream resource."; leaf last { type boolean; default "false"; description "True if this is the last notification for the current series."; } uses transducers-list { augment "time-series" { container internal { description "Internal operational state for this time-series entry."; leaf last-update { type uint64; units "seconds"; description "Epoch timestamp of the last sample appended to this time-series."; } leaf start-time { type uint64; units "seconds"; description "Epoch timestamp of the first sample; set when the Observe subscription is created."; } leaf messages-sent { Toutain Expires 20 March 2027 [Page 63] Internet-Draft coreconf-m2m September 2026 type uint64; description "Number of notification messages sent for this time-series since the Observe subscription was created."; } } } } } notification sensor-alert { description "Alert notification when a value exceeds a threshold."; list target { key "type"; description "Measurement instances that triggered this alert."; leaf type { type identityref { base transducer-type; } } leaf value { type int64; description "The measurement value that triggered this alert."; } } } } Figure 29: Complete coreconf-m2m YANG module Appendix C. SID File (CSV) The following table lists the SID assignments for the coreconf-m2m module (assignment range: 62000-62399, revision 2026-09-01). The transducer-type identities defined by manufacturer modules such as atmos are assigned separately and are not yet included in this table. SID,Namespace,Identifier 62000,module,coreconf-m2m 62001,identity,transducer-type 62002,data,/coreconf-m2m:bootstrap 62003,data,/coreconf-m2m:bootstrap/inventory 62004,data,/coreconf-m2m:bootstrap/inventory/category-override 62005,data,/coreconf-m2m:bootstrap/inventory/precision-override 62006,data,/coreconf-m2m:bootstrap/inventory/type Toutain Expires 20 March 2027 [Page 64] Internet-Draft coreconf-m2m September 2026 62007,data,/coreconf-m2m:bootstrap/inventory/unit-override 62008,data,/coreconf-m2m:bootstrap/minimal-step 62009,data,/coreconf-m2m:bootstrap/reference-epoch 62010,data,/coreconf-m2m:bootstrap/uptime 62011,data,/coreconf-m2m:characteristics 62012,data,/coreconf-m2m:characteristics/description 62013,data,/coreconf-m2m:characteristics/geo-location 62014,data,/coreconf-m2m:characteristics/geo-location/height 62015,data,/coreconf-m2m:characteristics/geo-location/latitude 62016,data,/coreconf-m2m:characteristics/geo-location/longitude 62017,data,/coreconf-m2m:characteristics/geo-location/reference-frame 62018,data,/coreconf-m2m:characteristics/geo-location/reference-frame/alternate-system 62019,data,/coreconf-m2m:characteristics/geo-location/reference-frame/astronomical-body 62020,data,/coreconf-m2m:characteristics/geo-location/reference-frame/geodetic-system 62021,data,/coreconf-m2m:characteristics/geo-location/reference-frame/geodetic-system/coord-accuracy 62022,data,/coreconf-m2m:characteristics/geo-location/reference-frame/geodetic-system/geodetic-datum 62023,data,/coreconf-m2m:characteristics/geo-location/reference-frame/geodetic-system/height-accuracy 62024,data,/coreconf-m2m:characteristics/geo-location/timestamp 62025,data,/coreconf-m2m:characteristics/geo-location/valid-until 62026,data,/coreconf-m2m:characteristics/geo-location/velocity 62027,data,/coreconf-m2m:characteristics/geo-location/velocity/v-east 62028,data,/coreconf-m2m:characteristics/geo-location/velocity/v-north 62029,data,/coreconf-m2m:characteristics/geo-location/velocity/v-up 62030,data,/coreconf-m2m:characteristics/geo-location/x 62031,data,/coreconf-m2m:characteristics/geo-location/y 62032,data,/coreconf-m2m:characteristics/geo-location/z 62033,data,/coreconf-m2m:characteristics/hosted-by 62034,data,/coreconf-m2m:characteristics/identifier 62035,data,/coreconf-m2m:characteristics/installation-time 62036,data,/coreconf-m2m:characteristics/manufacturer 62037,data,/coreconf-m2m:characteristics/model 62038,data,/coreconf-m2m:characteristics/name 62039,data,/coreconf-m2m:characteristics/version 62040,data,/coreconf-m2m:history 62041,data,/coreconf-m2m:history/last 62042,data,/coreconf-m2m:history/time-series 62043,data,/coreconf-m2m:history/time-series/internal 62044,data,/coreconf-m2m:history/time-series/internal/last-update 62045,data,/coreconf-m2m:history/time-series/internal/messages-sent 62046,data,/coreconf-m2m:history/time-series/internal/start-time 62047,data,/coreconf-m2m:history/time-series/type 62048,data,/coreconf-m2m:history/time-series/values 62049,data,/coreconf-m2m:reset-stats 62050,data,/coreconf-m2m:reset-stats/input 62051,data,/coreconf-m2m:reset-stats/output 62052,data,/coreconf-m2m:sensor-alert 62053,data,/coreconf-m2m:sensor-alert/target 62054,data,/coreconf-m2m:sensor-alert/target/type Toutain Expires 20 March 2027 [Page 65] Internet-Draft coreconf-m2m September 2026 62055,data,/coreconf-m2m:sensor-alert/target/value 62056,data,/coreconf-m2m:transducers 62057,data,/coreconf-m2m:transducers/transducer 62058,data,/coreconf-m2m:transducers/transducer/notification-parameters 62059,data,/coreconf-m2m:transducers/transducer/notification-parameters/check-interval 62060,data,/coreconf-m2m:transducers/transducer/notification-parameters/history 62061,data,/coreconf-m2m:transducers/transducer/notification-parameters/history/active 62062,data,/coreconf-m2m:transducers/transducer/notification-parameters/history/encoding 62063,data,/coreconf-m2m:transducers/transducer/notification-parameters/history/max-payload 62064,data,/coreconf-m2m:transducers/transducer/notification-parameters/history/max-samples 62065,data,/coreconf-m2m:transducers/transducer/notification-parameters/history/precision 62066,data,/coreconf-m2m:transducers/transducer/notification-parameters/history/step 62067,data,/coreconf-m2m:transducers/transducer/notification-parameters/history/time-period 62068,data,/coreconf-m2m:transducers/transducer/notification-parameters/sensor-alert 62069,data,/coreconf-m2m:transducers/transducer/notification-parameters/sensor-alert/active 62070,data,/coreconf-m2m:transducers/transducer/notification-parameters/sensor-alert/dampening 62071,data,/coreconf-m2m:transducers/transducer/notification-parameters/sensor-alert/hysteresis 62072,data,/coreconf-m2m:transducers/transducer/notification-parameters/sensor-alert/t-max 62073,data,/coreconf-m2m:transducers/transducer/notification-parameters/sensor-alert/t-min 62074,data,/coreconf-m2m:transducers/transducer/quantity 62075,data,/coreconf-m2m:transducers/transducer/quantity/timestamp 62076,data,/coreconf-m2m:transducers/transducer/quantity/timestamp-source 62077,data,/coreconf-m2m:transducers/transducer/quantity/value 62078,data,/coreconf-m2m:transducers/transducer/reset-stats 62079,data,/coreconf-m2m:transducers/transducer/reset-stats/input 62080,data,/coreconf-m2m:transducers/transducer/reset-stats/output 62081,data,/coreconf-m2m:transducers/transducer/statistics 62082,data,/coreconf-m2m:transducers/transducer/statistics/max 62083,data,/coreconf-m2m:transducers/transducer/statistics/mean 62084,data,/coreconf-m2m:transducers/transducer/statistics/median 62085,data,/coreconf-m2m:transducers/transducer/statistics/min 62086,data,/coreconf-m2m:transducers/transducer/statistics/sample-count 62087,data,/coreconf-m2m:transducers/transducer/statistics/stdev 62088,data,/coreconf-m2m:transducers/transducer/type Figure 30: SID assignments for coreconf-m2m (CSV format) Appendix D. atmos YANG Module file "atmos@2026-08-24.yang" module atmos { yang-version 1.1; namespace "urn:ietf:params:xml:ns:yang:atmos"; prefix atmos; import coreconf-m2m { prefix ccm2m; } Toutain Expires 20 March 2027 [Page 66] Internet-Draft coreconf-m2m September 2026 organization "METER Group, Inc."; contact "Technical Support https://www.metergroup.com/"; description "Atmospheric/weather transducer-type identities for use with the coreconf-m2m generic M2M CoMI data model."; revision 2026-08-24 { description "Initial revision. Extracted all concrete transducer-type identities from coreconf-m2m: atmospheric/weather (solar-radiation, precipitation, air-temperature, relative-humidity, barometric-pressure, vapor-pressure, wind-speed, wind-direction, wind-gust, north-wind-speed, east-wind-speed), lightning (strike-count, average-distance), orientation (tilt, x-orientation, y-orientation, compass-heading), and humidity-sensor-temperature. coreconf-m2m now only defines the base transducer-type identity; atmos is the product-specific module extending it. Applied the ccm2m:default-unit and ccm2m:default-precision extensions (defined in coreconf-m2m) to each identity, to advertise the recommended SenML (RFC 8428) unit and decimal precision for a transducer of that type."; } /* ------------------------------------------------------------------ */ /* Environmental */ /* ------------------------------------------------------------------ */ identity solar-radiation { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "W/m2"; ccm2m:default-precision "0"; description "Solar radiation measurement (W/m2)."; } identity precipitation { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "mm"; ccm2m:default-precision "1"; description "Precipitation measurement (mm)."; } identity air-temperature { base ccm2m:transducer-type; Toutain Expires 20 March 2027 [Page 67] Internet-Draft coreconf-m2m September 2026 ccm2m:default-category "sensor"; ccm2m:default-unit "Cel"; ccm2m:default-precision "2"; description "Air temperature measurement (°C)."; } identity relative-humidity { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "%RH"; ccm2m:default-precision "1"; description "Relative humidity measurement (%)."; } identity barometric-pressure { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "Pa"; ccm2m:default-precision "0"; description "Barometric pressure measurement (kPa)."; } identity vapor-pressure { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "Pa"; ccm2m:default-precision "0"; description "Vapor pressure measurement (kPa)."; } /* ------------------------------------------------------------------ */ /* Wind */ /* ------------------------------------------------------------------ */ identity wind-speed { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "m/s"; ccm2m:default-precision "1"; description "Horizontal wind speed measurement (m/s)."; } identity wind-direction { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "deg"; ccm2m:default-precision "0"; description "Wind direction measurement (degrees)."; Toutain Expires 20 March 2027 [Page 68] Internet-Draft coreconf-m2m September 2026 } identity wind-gust { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "m/s"; ccm2m:default-precision "1"; description "Wind gust measurement (m/s)."; } identity north-wind-speed { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "m/s"; ccm2m:default-precision "1"; description "North wind speed component (m/s)."; } identity east-wind-speed { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "m/s"; ccm2m:default-precision "1"; description "East wind speed component (m/s)."; } /* ------------------------------------------------------------------ */ /* Lightning */ /* ------------------------------------------------------------------ */ identity strike-count { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "count"; ccm2m:default-precision "0"; description "Lightning strike count."; } identity average-distance { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "km"; ccm2m:default-precision "1"; description "Average lightning distance (km)."; } /* ------------------------------------------------------------------ */ /* Orientation */ Toutain Expires 20 March 2027 [Page 69] Internet-Draft coreconf-m2m September 2026 /* ------------------------------------------------------------------ */ identity tilt { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "deg"; ccm2m:default-precision "1"; description "Sensor tilt measurement (degrees)."; } identity x-orientation { base ccm2m:transducer-type; ccm2m:default-category "sensor"; description "X-axis orientation (raw accelerometer data)."; } identity y-orientation { base ccm2m:transducer-type; ccm2m:default-category "sensor"; description "Y-axis orientation (raw accelerometer data)."; } identity compass-heading { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "deg"; ccm2m:default-precision "0"; description "Compass heading clockwise from north reference (degrees)."; } /* ------------------------------------------------------------------ */ /* Internal */ /* ------------------------------------------------------------------ */ identity humidity-sensor-temperature { base ccm2m:transducer-type; ccm2m:default-category "sensor"; ccm2m:default-unit "Cel"; ccm2m:default-precision "2"; description "Internal temperature of the humidity sensor (°C)."; } } Figure 31: atmos.yang module Toutain Expires 20 March 2027 [Page 70] Internet-Draft coreconf-m2m September 2026 Appendix E. atmos SID File (CSV) The following table illustrates the SID assignments for the atmos module, assuming a registrar-owned range with an illustrative entry point of 10000000 (out of a 10 million SID mega-range assumed for this example). These SIDs are commercial/vendor assignments, not IETF or SDO ones, and are provided here for illustration only. SID,Namespace,Identifier 10000000,module,atmos 10000001,identity,air-temperature 10000002,identity,average-distance 10000003,identity,barometric-pressure 10000004,identity,compass-heading 10000005,identity,east-wind-speed 10000006,identity,humidity-sensor-temperature 10000007,identity,north-wind-speed 10000008,identity,precipitation 10000009,identity,relative-humidity 10000010,identity,solar-radiation 10000011,identity,strike-count 10000012,identity,tilt 10000013,identity,vapor-pressure 10000014,identity,wind-direction 10000015,identity,wind-gust 10000016,identity,wind-speed 10000017,identity,x-orientation 10000018,identity,y-orientation Figure 32: SID assignments for atmos (CSV format, illustrative) Appendix F. ccm2m Ontology @prefix ccm2m: . @prefix owl: . @prefix rdf: . @prefix rdfs: . @prefix xsd: . @prefix sosa: . @prefix qudt: . @prefix dcterms: . # ── Ontology header ─────────────────────────────────────────────────────────── a owl:Ontology ; rdfs:label "CCM2M — CORECONF-M2M vocabulary for SOSA/SSN" ; rdfs:comment """Complementary vocabulary to SOSA/SSN for exposing Toutain Expires 20 March 2027 [Page 71] Internet-Draft coreconf-m2m September 2026 CORECONF/CoAP semantics (endpoints, applicative controls, bootstrap SIDs, sensor identity/id) that have no direct equivalent in SOSA.""" ; dcterms:created "2026-06-27"^^xsd:date ; owl:versionInfo "0.2" . # ── Datatype ────────────────────────────────────────────────────────────────── ccm2m:SID a rdfs:Datatype ; rdfs:label "SID" ; rdfs:comment """A CORECONF Schema Identifier (SID) — a non-negative integer that uniquely identifies a YANG node, identity, or feature within a SID file (RFC 9254). Using this datatype instead of xsd:nonNegativeInteger makes the nature of the value self-documenting.""" . # ── Classes ─────────────────────────────────────────────────────────────────── ccm2m:Control a owl:Class ; rdfs:label "Control" ; rdfs:comment """An applicative operation exposed by a Platform over CORECONF/CoAP: single-value read, history-buffer notification subscription, or threshold-alert notification subscription. Intentionally outside SOSA/SSN Sampling/Sensing semantics.""" . ccm2m:SetupNotification a owl:Class ; rdfs:subClassOf ccm2m:Control ; rdfs:label "SetupNotification" ; rdfs:comment """A Control that configures notification parameters on a transducer before subscribing (iPATCH /c). Carries the target SID of the notification-parameters container and the list of configurable parameters with their individual SIDs.""" . ccm2m:NotificationParam a owl:Class ; rdfs:label "NotificationParam" ; rdfs:comment """A single configurable parameter within a SetupNotification (e.g. 'step', 'encoding'). Carries the YANG leaf name and its SID.""" . # ── Object properties ───────────────────────────────────────────────────────── ccm2m:hasControl a owl:ObjectProperty ; rdfs:label "hasControl" ; rdfs:comment "Links a Platform or Sensor to a Control it exposes." ; rdfs:range ccm2m:Control . Toutain Expires 20 March 2027 [Page 72] Internet-Draft coreconf-m2m September 2026 ccm2m:hasParam a owl:ObjectProperty ; rdfs:label "hasParam" ; rdfs:comment "Links a SetupNotification to one of its configurable parameters." ; rdfs:domain ccm2m:SetupNotification ; rdfs:range ccm2m:NotificationParam . ccm2m:outputUnit a owl:ObjectProperty ; rdfs:label "outputUnit" ; rdfs:comment """Fixed output unit of a Sensor, declared once from the 'units' statement of the corresponding YANG leaf. Never repeated per Observation.""" ; rdfs:domain sosa:Sensor ; rdfs:range qudt:Unit . # ── Datatype properties — Platform ──────────────────────────────────────────── ccm2m:coapEndpoint a owl:DatatypeProperty ; rdfs:label "coapEndpoint" ; rdfs:comment "CoAP access address of the resource (e.g. coap://[::1])." ; rdfs:domain sosa:Platform ; rdfs:range xsd:anyURI . ccm2m:accessProtocol a owl:DatatypeProperty ; rdfs:label "accessProtocol" ; rdfs:comment "Default applicative protocol on this Platform (e.g. 'coreconf')." ; rdfs:domain sosa:Platform ; rdfs:range xsd:string . ccm2m:bootstrapSid a owl:DatatypeProperty ; rdfs:label "bootstrapSid" ; rdfs:comment """SID used at bootstrap to discover the YANG model exposed by the Platform. Multi-valued (several bootstrap SIDs are possible, unordered). Discovered via DNS TXT record.""" ; rdfs:domain sosa:Platform ; rdfs:range ccm2m:SID . # ── Datatype properties — shared (Platform and Control) ─────────────────────── ccm2m:coapMethod a owl:DatatypeProperty ; rdfs:label "coapMethod" ; rdfs:comment """CoAP method to use (FETCH, FETCH+Observe, GET, iPATCH…). Usable on a Platform (default) or on a Control (override). Toutain Expires 20 March 2027 [Page 73] Internet-Draft coreconf-m2m September 2026 Domain intentionally unconstrained.""" ; rdfs:range xsd:string . ccm2m:coapPath a owl:DatatypeProperty ; rdfs:label "coapPath" ; rdfs:comment """CoAP URI path of the resource targeted by this Control (e.g. '/c' for datastore, '/s' for stream/notification).""" ; rdfs:range xsd:string . ccm2m:contentFormat a owl:DatatypeProperty ; rdfs:label "contentFormat" ; rdfs:comment """CoAP Content-Format used (e.g. application/yang-data+cbor). Usable on a Platform (default) or on a Control (override). Domain intentionally unconstrained.""" ; rdfs:range xsd:string . # ── Datatype properties — Control ───────────────────────────────────────────── ccm2m:paramName a owl:DatatypeProperty ; rdfs:label "paramName" ; rdfs:comment "YANG leaf name of this notification parameter (e.g. 'step', 'encoding')." ; rdfs:domain ccm2m:NotificationParam ; rdfs:range xsd:string . ccm2m:paramSid a owl:DatatypeProperty ; rdfs:label "paramSid" ; rdfs:comment "SID of this notification parameter's YANG leaf." ; rdfs:domain ccm2m:NotificationParam ; rdfs:range ccm2m:SID . ccm2m:controlType a owl:DatatypeProperty ; rdfs:label "controlType" ; rdfs:comment """Functional type of the Control. Current controlled values: 'instant-write' — single-value write (iPATCH /c, same SID as read-single), 'read-single' — single-value polling (FETCH /c), 'read-stat' — statistics polling (FETCH /c, statistics container), 'reset-stat' — reset statistics for one sensor (POST /c, per-sensor), 'reset-all-stat' — reset all sensors statistics (POST /c, platform-level), 'subscribe-history' — history-buffer notification subscription (Observe /s), 'subscribe-threshold' — threshold-alert notification subscription (Observe /s).""" ; rdfs:domain ccm2m:Control ; rdfs:range xsd:string . Toutain Expires 20 March 2027 [Page 74] Internet-Draft coreconf-m2m September 2026 ccm2m:targetSid a owl:DatatypeProperty ; rdfs:label "targetSid" ; rdfs:comment "SID of the YANG leaf/container targeted by this Control." ; rdfs:domain ccm2m:Control ; rdfs:range ccm2m:SID . # ── Datatype properties — Sensor ────────────────────────────────────────────── ccm2m:type a owl:DatatypeProperty ; rdfs:label "type" ; rdfs:comment """SID of the YANG identity describing the sensor type (e.g. 100001 for air-temperature). Named 'type' to match the YANG leaf name. Looked up from the device's .sid file.""" ; rdfs:domain sosa:Sensor ; rdfs:range ccm2m:SID . ccm2m:id a owl:DatatypeProperty ; rdfs:label "id" ; rdfs:comment """Instance identifier of the sensor on its Platform. Distinguishes multiple sensors of the same type (default 0).""" ; rdfs:domain sosa:Sensor ; rdfs:range xsd:nonNegativeInteger . ccm2m:precision a owl:DatatypeProperty ; rdfs:label "precision" ; rdfs:comment """Number of decimal places for the raw integer value. Real value = raw_value × 10^(-precision). Declared once on the Sensor; not repeated per Observation.""" ; rdfs:domain sosa:Sensor ; rdfs:range xsd:integer . Figure 33: The ccm2m: extension vocabulary, in Turtle/OWL Appendix G. SCHC Rule Set The following SCHC [RFC8724] Rule Set compresses the IPv6/UDP/CoAP traffic exchanged with the ATMOS41 weather station used throughout this document. These rules are just examples that can be adapted to other scenarios. It is not the final version of this rule set and is expected to change as the model evolves. Toutain Expires 20 March 2027 [Page 75] Internet-Draft coreconf-m2m September 2026 The compression of IPv6 and UDP results in the port number being sent as residue. Traffic Class and Flow Label are elided, and the application and device IPv6 addresses are supposed to be known (aaaa::2/64 and dddd::6/64, respectively). Field names (FID) are the identities defined by the "ietf-schc" YANG module [RFC9363] [SCHC-TOWARD-9363BIS], without their common "fid-" prefix (e.g. "ipv6-version" for "fid-ipv6-version"), rather than the plain-text FID names of [RFC8724] itself. CoAP options use the Universal Option identity "coap-option" [SCHC-TOWARD-9363BIS], common to every option, with the actual option number given in parentheses, rather than the twenty per-option FIDs deprecated by that identity. Matching operators (MO) and compression/decompression actions (CDA) are as defined in [RFC8724]; FL is the Field Length, DI the Direction Indicator, and TV the Target Value (the Field Position, FP, is omitted from the tables below for compactness; it defaults to 1 unless a field is repeated, which does not happen in this Rule Set). Below each rule table, the resulting residue format is given for the Down (network to device) and Up (device to network) directions: the ordered list of fields that still carry a residue after compression — i.e. those whose CDA is not "not-sent", "compute-length", or "compute-checksum" — together with the number of bits sent for that field ("var" when the size is not fixed), followed by the total residue size for that direction. G.1. Rule 0: Used to fetch a single value (bidirect) Toutain Expires 20 March 2027 [Page 76] Internet-Draft coreconf-m2m September 2026 /---------------------+----------+----+-----------+---------+------------\ | FID | FL | DI | TV | MO | CDA | +=====================+==========+====+===========+=========+============+ | ipv6-version | 4 | bi | 6 | equal | not-sent | | ipv6-trafficclass | 8 | bi | 0 | ignore | not-sent | | ipv6-flowlabel | 20 | bi | 0 | ignore | not-sent | | ipv6-payload-length | 16 | bi | | ignore | compute | | ipv6-nextheader | 8 | bi | 17 | equal | not-sent | | ipv6-hoplimit | 8 | bi | 255 | ignore | not-sent | | ipv6-devprefix | 64 | bi | dddd::/64 | equal | not-sent | | ipv6-deviid | 64 | bi | ::6/64 | equal | not-sent | | ipv6-appprefix | 64 | bi | aaaa::/64 | equal | not-sent | | ipv6-appiid | 64 | bi | ::2/64 | equal | not-sent | | udp-dev-port | 16 | bi | 5683 | equal | not-sent | | udp-app-port | 16 | bi | | ignore | value-sent | | udp-length | 16 | bi | 0 | ignore | compute | | udp-checksum | 16 | bi | 0 | ignore | compute | | coap-version | 2 | bi | 1 | equal | not-sent | | coap-type | 2 | bi | 1 | equal | not-sent | | coap-tkl | 4 | bi | 0 | ignore | value-sent | | coap-code | 8 | bi | 5,69 | match- | mapping- | | | | | | mapping | sent | | coap-mid | 16 | bi | 0 | ignore | value-sent | | coap-token | length- | bi | | ignore | value-sent | | | byte(16) | | | | | | coap-option(11) | var | dw | "c" | equal | not-sent | | coap-option(12) | var | bi | 140 | equal | not-sent | | coap-option(17) | var | dw | 140 | equal | not-sent | \---------------------+----------+----+-----------+---------+------------/ Residue (Down): udp-app-port(16b) | coap-tkl(4b) | coap-code(1b) | coap-mid(16b) | coap-token(var) Total: 37b+var Residue (Up): udp-app-port(16b) | coap-tkl(4b) | coap-code(1b) | coap-mid(16b) | coap-token(var) Total: 37b+var Figure 34: SCHC Rule 0 (RuleIDLength=5), with residue format This rule is used for FETCH: the client sends one or more SID values, potentially with keys, and receives a CORECONF structure in return. Errors are handled by Rule 3 (empty message) and Rule 4 (ICMPv6 destination unreachable), not by this rule. The Content-Format is always 140 (application/yang-data+cbor;id=sid [RFC9254]). Messages are Non-Confirmable (NON), and the Token is mandatory to associate the response with its query. Toutain Expires 20 March 2027 [Page 77] Internet-Draft coreconf-m2m September 2026 Figure 35 applies Rule 0 to two of the exchanges shown earlier: the bootstrap discovery of Figure 6 and the air-temperature query of Figure 8. Each message crosses two SCHC instances: a compressor/ decompressor at the constrained device and its peer at the network edge, next to the application. Only the residue fields of Figure 34 (app-port, coap-tkl, coap-code, coap-mid, coap-token — 53 bits, plus the 5-bit RuleID) cross the constrained link between the two SCHC instances; the full IPv6/UDP/CoAP message, shown here with its CoAP method, MID, Token, Content-Format, and payload (when small enough to display), is exchanged unchanged on the Device-SCHC and SCHC-App segments. The application port (app-port) is an arbitrary ephemeral port, chosen here as 52344 for illustration. Device SCHC SCHC App Bootstrap discovery -- request (Down): | | | | | | |<---- Pkt 64B -----| | | Rule 0/5 | | | | residue: 53b | | | | payload: 3B | | | |<- 11B (pad 6b) ---| | |<--- Pkt 64B ----| | | IPv6(40B)+UDP(8B)+CoAP(16B) = 64 B FETCH /bootstrap MID=39919 Token=2aaf Payload: 19 F2 32 (3 B) Bootstrap discovery -- response (Up): | | | | |--- Pkt 175B --->| | | | | Rule 0/5 | | | | residue: 53b | | | | payload: 118B | | | |-- 126B (pad 6b) ->| | | | |---- Pkt 175B ---->| IPv6(40B)+UDP(8B)+CoAP(127B) = 175 B 2.05 Content MID=39919 Token=2aaf Payload: 118 B (not shown) Air-temperature query -- request (Down): | | | | | | |<---- Pkt 70B -----| | | Rule 0/5 | | | | residue: 53b | | | | payload: 9B | | | |<- 17B (pad 6b) ---| | |<--- Pkt 70B ----| | | IPv6(40B)+UDP(8B)+CoAP(22B) = 70 B Toutain Expires 20 March 2027 [Page 78] Internet-Draft coreconf-m2m September 2026 FETCH /c MID=12229 Token=2dae Payload: [62077, 10000001] (9 B) Air-temperature query -- response (Up): | | | | |---- Pkt 63B --->| | | | | Rule 0/5 | | | | residue: 53b | | | | payload: 6B | | | |-- 14B (pad 6b) -->| | | | |----- Pkt 63B ---->| IPv6(40B)+UDP(8B)+CoAP(15B) = 63 B 2.05 Content MID=12229 Token=2dae Payload: {62077: 196} (6 B) Figure 35: Rule 0 applied to a bootstrap discovery and an air- temperature query, across the two SCHC instances The compression ratio is best on small responses (bootstrap discovery request: 64 -> 11 bytes, 83%) and degrades as the payload grows, since SCHC only compresses the fixed IPv6/UDP/CoAP header fields, not the CoAP payload (bootstrap response: 175 -> 126 bytes, 28%, dominated by the 118-byte payload). Figure 36 shows the other side of Rule 0: a FETCH targeting a SID the device does not have. The 4.04 Not Found response carries no payload and no Content-Format option, so it does not match Rule 0's CODE mapping or its fixed Up-direction options; it falls through to Rule 3 instead, where TYPE, TKL, CODE and MID are all left uncompressed. Toutain Expires 20 March 2027 [Page 79] Internet-Draft coreconf-m2m September 2026 Device SCHC SCHC App FETCH on a non-existent SID -- request (Down): | | | | | | |<---- Pkt 64B -----| | | Rule 0/5 | | | | residue: 53b | | | | payload: 3B | | | |<- 11B (pad 6b) ---| | |<--- Pkt 64B ----| | | IPv6(40B)+UDP(8B)+CoAP(16B) = 64 B FETCH /c MID=12230 Token=2daf Payload: 19 F2 93 (SID 62099, 3 B) 4.04 Not Found, no options -- response (Up, Rule 3): | | | | |---- Pkt 54B --->| | | | | Rule 3/5 | | | | residue: 62b | | | | payload: 0B | | | |--- 9B (pad 5b) -->| | | | |----- Pkt 54B ---->| IPv6(40B)+UDP(8B)+CoAP(6B) = 54 B 4.04 Not Found MID=12230 Token=2daf Payload: (none) Figure 36: A FETCH error: Rule 0 for the request, Rule 3 for the 4.04 response G.2. Rule 1: Used to iPatch, ack with 7/3. Empty CoAP for notification in UP Toutain Expires 20 March 2027 [Page 80] Internet-Draft coreconf-m2m September 2026 /---------------------+----------+----+-----------+---------+------------\ | FID | FL | DI | TV | MO | CDA | +=====================+==========+====+===========+=========+============+ | ipv6-version | 4 | bi | 6 | equal | not-sent | | ipv6-trafficclass | 8 | bi | 0 | ignore | not-sent | | ipv6-flowlabel | 20 | bi | 0 | ignore | not-sent | | ipv6-payload-length | 16 | bi | | ignore | compute | | ipv6-nextheader | 8 | bi | 17 | equal | not-sent | | ipv6-hoplimit | 8 | bi | 255 | ignore | not-sent | | ipv6-devprefix | 64 | bi | dddd::/64 | equal | not-sent | | ipv6-deviid | 64 | bi | ::6/64 | equal | not-sent | | ipv6-appprefix | 64 | bi | aaaa::/64 | equal | not-sent | | ipv6-appiid | 64 | bi | ::2/64 | equal | not-sent | | udp-dev-port | 16 | bi | 5683 | equal | not-sent | | udp-app-port | 16 | bi | | ignore | value-sent | | udp-length | 16 | bi | 0 | ignore | compute | | udp-checksum | 16 | bi | 0 | ignore | compute | | coap-version | 2 | bi | 1 | equal | not-sent | | coap-type | 2 | bi | 1 | equal | not-sent | | coap-tkl | 4 | bi | 0 | ignore | value-sent | | coap-code | 8 | dw | 7 | equal | not-sent | | coap-code | 8 | up | | ignore | value-sent | | coap-mid | 16 | bi | 0 | ignore | value-sent | | coap-token | length- | bi | | ignore | value-sent | | | byte(16) | | | | | | coap-option(11) | var | dw | "c" | equal | not-sent | | coap-option(12) | var | dw | 140 | equal | not-sent | \---------------------+----------+----+-----------+---------+------------/ Residue (Down): udp-app-port(16b) | coap-tkl(4b) | coap-mid(16b) | coap-token(var) Total: 36b+var Residue (Up): udp-app-port(16b) | coap-tkl(4b) | coap-code(8b) | coap-mid(16b) | coap-token(var) Total: 44b+var Figure 37: SCHC Rule 1 (RuleIDLength=5), with residue format The request side of this rule does not change from Rule 0: the CoAP CODE is fixed to 7 (iPATCH), and the request carries the SID(s) being updated together with their new values, using the same Content-Format 140. The response, however, is simpler than a FETCH response: it is only a success/failure notification, with no CORECONF structure in the payload, so CODE is left uncompressed (value-sent) rather than mapped as in Rule 0 — it carries 2.04 Changed on success, or a CoAP error code (e.g. 4.00, 4.04) when the iPATCH itself fails; either way the message still has the same structure (a bare CODE, no payload), so this rule covers both cases. Rule 3, which is identical in both Toutain Expires 20 March 2027 [Page 81] Internet-Draft coreconf-m2m September 2026 directions (DI bi throughout, including CODE), is used instead when the message does not follow this structure at all — an empty/generic message such as an ACK with no code or an RST, in either direction. An unreachable device is signaled out-of-band by an ICMPv6 destination unreachable message, handled by Rule 4. Figure 38 applies Rule 1 to the sensor-alert configuration of Figure 12: the request, 83 bytes uncompressed, crosses the constrained link as a 32-byte compressed message (5-bit RuleID + 52-bit residue + the 24-byte iPATCH payload, padded to a byte boundary). The response — 2.04 Changed, with no payload — collapses to 9 bytes (5-bit RuleID + 60-bit residue, padded), against 54 bytes uncompressed. Device SCHC SCHC App Alert configuration -- request (Down): | | | | | | |<---- Pkt 83B -----| | | Rule 1/5 | | | | residue: 52b | | | | payload: 24B | | | |<- 32B (pad 7b) ---| | |<--- Pkt 83B ----| | | IPv6(40B)+UDP(8B)+CoAP(35B) = 83 B iPATCH /c MID=42312 Token=2490 Payload: {[62068,..]: {...}} (24 B) Alert configuration -- response (Up): | | | | |---- Pkt 54B --->| | | | | Rule 1/5 | | | | residue: 60b | | | | payload: 0B | | | |--- 9B (pad 7b) -->| | | | |----- Pkt 54B ---->| IPv6(40B)+UDP(8B)+CoAP(6B) = 54 B 2.04 Changed MID=42312 Token=2490 Payload: (none) Figure 38: Rule 1 applied to the sensor-alert configuration example G.3. Rule 2: Used for notitifications (observe) Toutain Expires 20 March 2027 [Page 82] Internet-Draft coreconf-m2m September 2026 /---------------------+--------+----+-----------+---------+------------\ | FID | FL | DI | TV | MO | CDA | +=====================+========+====+===========+=========+============+ | ipv6-version | 4 | bi | 6 | equal | not-sent | | ipv6-trafficclass | 8 | bi | 0 | ignore | not-sent | | ipv6-flowlabel | 20 | bi | 0 | ignore | not-sent | | ipv6-payload-length | 16 | bi | | ignore | compute | | ipv6-nextheader | 8 | bi | 17 | equal | not-sent | | ipv6-hoplimit | 8 | bi | 255 | ignore | not-sent | | ipv6-devprefix | 64 | bi | dddd::/64 | equal | not-sent | | ipv6-deviid | 64 | bi | ::6/64 | equal | not-sent | | ipv6-appprefix | 64 | bi | aaaa::/64 | equal | not-sent | | ipv6-appiid | 64 | bi | ::2/64 | equal | not-sent | | udp-dev-port | 16 | bi | 5683 | equal | not-sent | | udp-app-port | 16 | bi | | ignore | value-sent | | udp-length | 16 | bi | 0 | ignore | compute | | udp-checksum | 16 | bi | 0 | ignore | compute | | coap-version | 2 | bi | 1 | equal | not-sent | | coap-type | 2 | bi | 0,1 | match- | mapping- | | | | | | mapping | sent | | coap-tkl | 4 | bi | 0 | ignore | value-sent | | coap-code | 8 | dw | 5 | equal | not-sent | | coap-code | 8 | up | 69 | equal | not-sent | | coap-mid | 16 | bi | 0 | ignore | value-sent | | coap-token | length | bi | | ignore | value-sent | | | -byte( | | | | | | | 16) | | | | | | coap-option(6) | var | bi | | ignore | value-sent | | coap-option(11) | var | dw | "s" | equal | not-sent | | coap-option(12) | var | bi | 140 | equal | not-sent | | coap-option(17) | var | dw | 140 | equal | not-sent | \---------------------+--------+----+-----------+---------+------------/ Residue (Down): udp-app-port(16b) | coap-type(1b) | coap-tkl(4b) | coap-mid(16b) | coap-token(var) | coap-option(6)(var) Total: 37b+var Residue (Up): udp-app-port(16b) | coap-type(1b) | coap-tkl(4b) | coap-mid(16b) | coap-token(var) | coap-option(6)(var) Total: 37b+var Figure 39: SCHC Rule 2 (RuleIDLength=5), with residue format This rule is the same as Rule 0, except that the Uri-Path targets "/s" instead of "/c", and an Observe option (option 6) is present in both directions to carry the subscription/notification counter. CODE is fixed per direction, not mapped: FETCH (5) Down for the Toutain Expires 20 March 2027 [Page 83] Internet-Draft coreconf-m2m September 2026 subscription request, 2.05 Content (69) Up for the acknowledgment and every notification, so it contributes no residue at all. TYPE is restricted to a two-value mapping, CON (0) or NON (1): an ACK or RST — which carries no CODE and no Observe option — does not match this rule's fixed fields and falls through to Rule 3 instead. Figure 40 applies Rule 2 (and Rule 3 for the ACK) to an Observe subscription on "/s" with three notifications: the first two are Non- Confirmable, the third is Confirmable and is acknowledged by an empty ACK, which does not match Rule 2's fixed CODE/Observe structure and therefore falls through to Rule 3. Device SCHC SCHC App 1. Subscribe -- FETCH /s + Observe:0 (Down): | | | | | | |<---- Pkt 71B -----| | | Rule 2/5 | | | | residue: 53b | | | | payload: 9B | | | |<- 17B (pad 6b) ---| | |<--- Pkt 71B ----| | | IPv6(40B)+UDP(8B)+CoAP(23B) = 71 B FETCH MID=42311 Token=248f Observe:0 Payload: [62048, 10000001] (9 B) 2. Subscription ack -- Observe:0, NON (Up): | | | | |---- Pkt 59B --->| | | | | Rule 2/5 | | | | residue: 53b | | | | payload: 1B | | | |--- 9B (pad 6b) -->| | | | |----- Pkt 59B ---->| IPv6(40B)+UDP(8B)+CoAP(11B) = 59 B 2.05 Content MID=65148 Token=248f Observe:0 Payload: {} (1 B) 3. Notification #1 -- Observe:1, NON (Up): | | | | |---- Pkt 75B --->| | | | | Rule 2/5 | | | | residue: 61b | | | | payload: 16B | | | |-- 25B (pad 6b) -->| | | | |----- Pkt 75B ---->| IPv6(40B)+UDP(8B)+CoAP(27B) = 75 B 2.05 Content MID=65149 Token=248f Observe:1 Toutain Expires 20 March 2027 [Page 84] Internet-Draft coreconf-m2m September 2026 Payload: 16 B 4. Notification #2 -- Observe:2, NON (Up): | | | | |---- Pkt 75B --->| | | | | Rule 2/5 | | | | residue: 61b | | | | payload: 16B | | | |-- 25B (pad 6b) -->| | | | |----- Pkt 75B ---->| IPv6(40B)+UDP(8B)+CoAP(27B) = 75 B 2.05 Content MID=65150 Token=248f Observe:2 Payload: 16 B 5. Notification #3 -- Observe:3, CON (Up): | | | | |---- Pkt 75B --->| | | | | Rule 2/5 | | | | residue: 61b | | | | payload: 16B | | | |-- 25B (pad 6b) -->| | | | |----- Pkt 75B ---->| IPv6(40B)+UDP(8B)+CoAP(27B) = 75 B 2.05 Content MID=65151 Token=248f Observe:3 Payload: 16 B -- CON, needs an ACK 6. ACK for #3's CON, empty (Down, Rule 3): | | | | | | |<---- Pkt 52B -----| | | Rule 3/5 | | | | residue: 46b | | | | payload: 0B | | | |<-- 7B (pad 5b) ---| | |<--- Pkt 52B ----| | | IPv6(40B)+UDP(8B)+CoAP(4B) = 52 B Empty ACK MID=65151 TKL=0 Payload: (none) Figure 40: Rule 2 applied to an Observe subscription with two NON and one CON notification The notification stream ends when the client explicitly deregisters with a FETCH carrying the same token and an Observe option set to 1, when the client sends a RST, when a Confirmable notification receives no ACK after a number of retransmission attempts, or when an ICMPv6 destination unreachable message is received for the client — all of which the device interprets as a lost subscriber. Toutain Expires 20 March 2027 [Page 85] Internet-Draft coreconf-m2m September 2026 G.4. Rule 3: Empty messages (e.g., ACK with empty code, or RST) /---------------------+----------+----+-----------+---------+------------\ | FID | FL | DI | TV | MO | CDA | +=====================+==========+====+===========+=========+============+ | ipv6-version | 4 | bi | 6 | equal | not-sent | | ipv6-trafficclass | 8 | bi | 0 | ignore | not-sent | | ipv6-flowlabel | 20 | bi | 0 | ignore | not-sent | | ipv6-payload-length | 16 | bi | | ignore | compute | | ipv6-nextheader | 8 | bi | 17 | equal | not-sent | | ipv6-hoplimit | 8 | bi | 255 | ignore | not-sent | | ipv6-devprefix | 64 | bi | dddd::/64 | equal | not-sent | | ipv6-deviid | 64 | bi | ::6/64 | equal | not-sent | | ipv6-appprefix | 64 | bi | aaaa::/64 | equal | not-sent | | ipv6-appiid | 64 | bi | ::2/64 | equal | not-sent | | udp-dev-port | 16 | bi | 5683 | equal | not-sent | | udp-app-port | 16 | bi | | ignore | value-sent | | udp-length | 16 | bi | 0 | ignore | compute | | udp-checksum | 16 | bi | 0 | ignore | compute | | coap-version | 2 | bi | 1 | equal | not-sent | | coap-type | 2 | bi | | ignore | value-sent | | coap-tkl | 4 | bi | | ignore | value-sent | | coap-code | 8 | bi | | ignore | value-sent | | coap-mid | 16 | bi | | ignore | value-sent | | coap-token | length- | bi | | ignore | value-sent | | | byte(16) | | | | | \---------------------+----------+----+-----------+---------+------------/ Residue (Down): udp-app-port(16b) | coap-type(2b) | coap-tkl(4b) | coap-code(8b) | coap-mid(16b) | coap-token(var) Total: 46b+var Residue (Up): udp-app-port(16b) | coap-type(2b) | coap-tkl(4b) | coap-code(8b) | coap-mid(16b) | coap-token(var) Total: 46b+var Figure 41: SCHC Rule 3 (RuleIDLength=5), with residue format Beyond empty ACKs and RSTs, this rule is also the fallback for an error response to a FETCH (Rule 0) or an Observe exchange (Rule 2) whose CODE is not 2.05 Content: since TYPE, TKL, CODE and MID are all left uncompressed here, any CoAP error code (e.g. 4.04, 4.05, 5.00) matches, and any diagnostic payload that may follow the header is carried unchanged, exactly as for a normal FETCH response. G.5. Rule 4: ICMPv6 destination unreachable (any code) Toutain Expires 20 March 2027 [Page 86] Internet-Draft coreconf-m2m September 2026 /---------------------+--------+----+-----------+---------+------------\ | FID | FL | DI | TV | MO | CDA | +=====================+========+====+===========+=========+============+ | ipv6-version | 4 | bi | 6 | equal | not-sent | | ipv6-trafficclass | 8 | bi | 0 | ignore | not-sent | | ipv6-flowlabel | 20 | bi | 0 | ignore | not-sent | | ipv6-payload-length | 16 | bi | | ignore | compute | | ipv6-nextheader | 8 | bi | 58 | equal | not-sent | | ipv6-hoplimit | 8 | bi | 255 | ignore | not-sent | | ipv6-devprefix | 64 | bi | dddd::/64 | equal | not-sent | | ipv6-deviid | 64 | bi | ::6/64 | equal | not-sent | | ipv6-appprefix | 64 | bi | aaaa::/64 | equal | not-sent | | ipv6-appiid | 64 | bi | ::2/64 | equal | not-sent | | icmpv6-type | 8 | bi | 1 | equal | not-sent | | icmpv6-code | 8 | bi | | ignore | value-sent | | icmpv6-checksum | 16 | bi | 0 | ignore | compute | | unused | 32 | bi | | ignore | not-sent | | ipv6-version | 4 | bi | 6 | equal | not-sent | | ipv6-trafficclass | 8 | bi | 0 | ignore | not-sent | | ipv6-flowlabel | 20 | bi | 0 | ignore | not-sent | | ipv6-payload-length | 16 | bi | | ignore | compute | | ipv6-nextheader | 8 | bi | 17 | equal | not-sent | | ipv6-hoplimit | 8 | bi | 255 | ignore | not-sent | | ipv6-devprefix | 64 | bi | dddd::/64 | equal | not-sent | | ipv6-deviid | 64 | bi | ::6/64 | equal | not-sent | | ipv6-appprefix | 64 | bi | aaaa::/64 | equal | not-sent | | ipv6-appiid | 64 | bi | ::2/64 | equal | not-sent | | udp-dev-port | 16 | bi | 5683 | equal | not-sent | | udp-app-port | 16 | bi | | ignore | value-sent | | udp-length | 16 | bi | 0 | ignore | compute | | udp-checksum | 16 | bi | 0 | ignore | compute | | payload | var | bi | | ignore | not-sent | \---------------------+--------+----+-----------+---------+------------/ Residue (Down): icmpv6-code(8b) | udp-app-port(16b) Total: 24b Residue (Up): icmpv6-code(8b) | udp-app-port(16b) Total: 24b Figure 42: SCHC Rule 4 (RuleIDLength=5), with residue format ICMPv6 Type is fixed to 1 (Destination Unreachable), but Code is left uncompressed so that this rule covers every Destination Unreachable reason (0: no route, 1: administratively prohibited, 3: address unreachable, 4: port unreachable), not just the port-unreachable case that triggers when the CORECONF UDP endpoint itself is down. Toutain Expires 20 March 2027 [Page 87] Internet-Draft coreconf-m2m September 2026 Appendix H. Private SID Translation [I-D.toutain-core-private-sid-translation] defines a mechanism for translating official YANG SIDs into small negative integers ("private SIDs"), each of which SHOULD end up encoding in a single CBOR byte (range -1 to -24). Two modules are in use in this document: coreconf-m2m (entry_point = 62000, official range of 400 SIDs) and atmos (entry_point = 10000000, official range of 100 SIDs). Each module is assigned a translation offset: the first module uses offset = 0, and the second uses offset equal to the negative of the first module's official range size, so that the two private ranges never overlap. Which module goes first matters: the first module gets the deepest, single-byte-encoding range, so it should be the one whose SIDs appear most often on the wire. Applying the allocation strategy in [I-D.toutain-core-private-sid-translation] to the resource discovery exchange of Figure 6 — which references fourteen distinct atmos identityref values (one per discovered transducer) against a single coreconf-m2m absolute SID (62002, the "/bootstrap" node, appearing twice — once in the request, once as the response's outer key) — the module with the higher count of on-wire absolute-SID occurrences, atmos, is given offset = 0, and coreconf-m2m is shifted by offset = -100. This is a property of the traffic pattern, not of the modules themselves: a session dominated by coreconf-m2m structural exchanges (e.g. repeated FETCH/iPATCH on notification-parameters) would favor the opposite ordering. For SCHC to actually perform this compression, Rules 0, 1, and 2 (Appendix G) each need an additional entry covering the CoAP payload, using the sid-translation CDA defined in [I-D.toutain-core-private-sid-translation] together with the "fl- remaining" Field Length function [SCHC-TOWARD-9363BIS] — which consumes whatever bytes are left in the packet, since the payload has no fixed length. Since the Function Arguments MAY be repeated, both models are covered by a single entry, shown in Figure 43: entry_point = 10000000 (atmos) with offset = 0, followed by entry_point = 62000 (coreconf-m2m) with offset = -100. /------------+--------------+----+-----+---------+-------------------\ | FID | FL | DI | TV | MO | CDA | +============+==============+====+=====+=========+===================+ | payload | fl-remaining | bi | | ignore | sid-translation( | | | | | | | 10000000, 0, | | | | | | | 62000, -100) | \------------+--------------+----+-----+---------+-------------------/ Toutain Expires 20 March 2027 [Page 88] Internet-Draft coreconf-m2m September 2026 Figure 43: Payload entry added to Rules 0, 1 and 2 for private SID translation of both models H.1. Worked Example (atmos first) Figure 44 shows Figure 6 translated with atmos offset = 0 and coreconf-m2m offset = -100. Delta keys (the structural fields 7, 8, 6, 1, and 3 relative to their parent) keep their magnitude but flip sign, per p(child) - p(parent) = -(child - parent); the coreconf-m2m absolute SID 62002 becomes -103; and every atmos identityref value becomes its private SID in the -2 to -17 range. Request payload, original (3 bytes): 19 F2 32 # unsigned(62002) Request payload, translated (2 bytes): 38 66 # negative(-103) Response payload, original (118 bytes): {62002: {7: 1788334280, 8: 30172, 6: 120, 1: [{3: 10000010}, {3: 10000008}, {3: 10000011}, {3: 10000002}, {3: 10000014}, {3: 10000016}, {3: 10000015}, {3: 10000012}, {3: 10000001}, {3: 10000013}, {3: 10000003}, {3: 10000009}, {3: 10000006}, {3: 10000004}]}} Response payload, translated (61 bytes): {-103: {-7: 1788334280, -8: 30172, -6: 120, -1: [{-3: -11}, {-3: -9}, {-3: -12}, {-3: -3}, {-3: -15}, {-3: -17}, {-3: -16}, {-3: -13}, {-3: -2}, {-3: -14}, {-3: -4}, {-3: -10}, {-3: -7}, {-3: -5}]}} Figure 44: Resource discovery of fig-resource-discovery, translated with atmos offset=0 and coreconf-m2m offset=-100 reference-epoch (1788334280), uptime (30172), and minimal-step (120) are plain integers, not SIDs, and are therefore left untranslated. Overall, this exchange shrinks from 121 bytes (3 + 118) to 63 bytes (2 + 61), a reduction of 48%, entirely attributable to the fourteen atmos identityref values collapsing from 5 bytes to 1 byte each. Toutain Expires 20 March 2027 [Page 89] Internet-Draft coreconf-m2m September 2026 H.2. Second Example: Time-Series Subscription and Notification Figure 13 exercises the opposite balance: it references coreconf-m2m absolute SID 62048 ("/history/time-series/values") twice (once in the FETCH+Observe request, once as the notification's outer key) against a single atmos identityref value (10000001, air-temperature) in the request. The maximum delta any coreconf-m2m SID currently reaches from its entry_point is 88 (Appendix C), so shifting coreconf-m2m from offset = 0 to offset = -100 changes its encoded deltas from 0-88 to 100-188 — both comfortably inside CBOR's single 2-byte bracket (24-255). Putting coreconf-m2m second therefore costs nothing here, while atmos still gains its full 5-to-1-byte improvement: Request payload, original (9 bytes): 82 19 F2 60 1A 00 98 96 81 # [62048, 10000001] Request payload, translated (4 bytes, atmos offset=0, coreconf-m2m offset=-100): 82 38 94 21 # [-149, -2] Subscription ack, original and translated (1 byte, unchanged): A0 # {} Notification payload, original (16 bytes): {62048: [189, 14, -3, 1, 5, 7, 3, 2, 1, 2]} Notification payload, translated (15 bytes): {-149: [189, 14, -3, 1, 5, 7, 3, 2, 1, 2]} Figure 45: Time-series subscription and notification, translated with atmos offset=0 and coreconf-m2m offset=-100 The history values themselves (189, 14, -3, 1, 5, 7, ...) are a delta-encoded time series, not SIDs, and are left untranslated. This exchange shrinks from 26 bytes (9 + 1 + 16) to 20 bytes (4 + 1 + 15), a 23% reduction — smaller than the first example's 48%, since only one atmos SID is involved here, but still a clear net gain, and with coreconf-m2m paying no penalty for going second. Across both examples, putting atmos first is never worse and sometimes substantially better, confirming it as the right default ordering for this document's traffic mix. Acknowledgments This work has been supported by the SCHC Chair from IMT Atlantique and Afnic. Toutain Expires 20 March 2027 [Page 90] Internet-Draft coreconf-m2m September 2026 Claude (Anthropic) assisted with editing this document. Author's Address Laurent Toutain IMT Atlantique Email: laurent.toutain@imt-atlantique.fr Toutain Expires 20 March 2027 [Page 91]