Subject: [Cbor] PR for improving epoch time (tag 1)

From: Laurence Lundblade <[email-masked]>
Date: Mon, 2 Jul 2018 11:29:22 -0700

I think that the more we can reduce implementation / encoding options and variability in CBOR the better. Seems this is also what a lot of the drive for canonicalization is about.

Here is a PR <https://github.com/cbor-wg/CBORbis/pull/27> for new text for epoch time (tag 1).  

I don’t know what the philosophy is for compatibility with RFC 7049. This proposal breaks it. Maybe it should be a different tag value or such because of that.

The big break is disallowing floating point values because you can do better in a number of ways by defining a new tag for time expressed in micro or nano seconds from the epoch in a 64-bit integer (perhaps as suggested here <https://tools.ietf.org/html/draft-bormann-cbor-time-tag-01>).

The general decoder implementor and protocol designer is left with only two choices:
   - Support 64-bit time values or not
   - Support negative time values or not

The protocol designer should of course make a call on these choices so there aren’t interop problems.

There’s more detailed rationale in the PR comments.

I’m curious what you think. :-)

LL

---

From: Carsten Bormann <[email-masked]>
Date: Mon, 2 Jul 2018 21:10:58 +0200

Hi Laurence,

the representation of time is indeed one of those eternal issues in representation formats.

Tag 1 is relatively well-defined as it is, and I don’t think we want to change that.
Instead, new tags have been defined for time (and there, of course, also has been tag 0).

Not all tags need to be defined in the CBOR base document.
In particular, in this round we are aiming to collect the stable parts of CBOR, as opposed to putting in more bells and whistles.
We are *not* defining a new version of CBOR (there are no versions in CBOR).

New bells and whistles can be added by just registering tags.
The set of registered tags can at any time be examined at:

	https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml

Looking for “time”, we see (apart from 0 and 1):

1001	map	extended time	[draft-bormann-cbor-time-tag-01]

This tag has been registered a while ago and already has been implemented in some environments that care about precise time (e.g., Haskell with its picosecond-based time).

On to the specific changes that you propose:

— getting rid of floating point time — I would expect that is in active use, but I haven’t done a survey. It definitely is allowed by RFC 8392 (which uses Tag 1 in an indirect way).  Floating point time has the weird property that its resolution gets lower the further away you get from the epoch.  But otherwise, it is fine.  Currently, of the 53 bits of resolution of a binary64, 31 bits are taken for the integer part, so 22 bits remain for the fractional part.  That will change to 32+21 in 2038 — a date that most people who work with Posix times are aware of, as the integer time_t no longer will fit in a signed 32-bit int then.  So I don’t see any deadly interoperability problems that would stop us from continuing to support floating point valuess in tag 1.  Any specific application can be more selective, if desired.

— being more explicit about negative values (int or float).  Good point.

- requiring support for “positive” (I think you mean unsigned) integer values.  Just as an application can rule out floats in its usage of Tag 1, it could do so for integers.  A generic CBOR implementation that doesn’t support integer values here could be considered not so bright, though.  (CBOR is more about interoperability than about conformance, anyway.)

— comments about serialization (encoding).  I don’t think a Tag should define that level of requirement.  If an application wants to use minimal-size encoding, so be it, but that’s none of the business of a Tag.

So, in summary, I’d say let’s pick a good way to handle negative numbers (being aware that there is no really good way).  Probably MJD-based interpretations.  But let’s talk to astronomers here…

Grüße, Carsten

> On Jul 2, 2018, at 20:29, Laurence Lundblade <[email-masked]> wrote:
> 
> Here is a PR for new text for epoch time (tag 1).  
> 
> The big break is disallowing floating point values because you can do better in a number of ways by defining a new tag for time expressed in micro or nano seconds from the epoch in a 64-bit integer (perhaps as suggested here).
> 
> _______________________________________________
> CBOR mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/cbor

---

From: Laurence Lundblade <[email-masked]>
Date: Thu, 5 Jul 2018 14:23:31 -0700

Hi Carsten,

I’m definitely after tightening up tag 1 here (and exploring as an example around canonicalization, variation and options in CBOR).  I’m not a time geek, nor do I have any use cases other than tag 1. I think tag 1 time probably covers the vast majority of use cases for time in CBOR protocols.

I’ve updated the PR <https://github.com/cbor-wg/CBORbis/pull/27> so floating point is no longer removed, but still discourage its use unless greater than 1 second precision is needed. The interop problems I see with floating point are:
 - Small CPUs like ARM Cortex M0 and ATmega16/32U4 do not support it
 - Floating-point is extra work for a CBOR implementor (It was for me anyway)

There should be as few choices for the implementor as possible and those there are should be clear. So the choices in the PR <https://github.com/cbor-wg/CBORbis/pull/27> are mostly a) 64 or 32-bit integer support, b) support negative time (to sort your Jimi Hendrix albums), c) support double if you need microsecond time.

I do think there should be clear requirements for each tag, maybe even canonicalization requirements per tag, especially for a tag that will be widely implemented and used like tag 1 and especially for something as problematic as time.

You’ll probably say I have way too much time on my hands, but there’s a tag 1 implementor FAQ below.

LL

Tag 1 Implementator’s FAQ

Q: I just want to implement the minimum, what should I do?
A: You should support 64-bit unsigned encoding. This will cover just about every use case because it works from 1970 until over 500 billion years in the future and 1 second resolution is enough for most human activity. Note that time values up to 2106 will be encoded as 32-bit integers even though 64-bit integers are supported because only 32-bits are needed to count seconds up to the year 2106.

Q: I’m implementing on an 8-bit CPU and 64-bit integers are really a problem.
A: You can support just 32-bit integers in that case, but they will stop working in 2106.

Q: Why 2106 and not 2038? 
A: Because CBOR encodes positive and negative integers with different major types and thus is able to use the full 32-bits for positive integers.

Q: What if I need time values before 1970? 
A: Implement 64 or 32-bit negative time values, but note that there is no clear standard for this as POSIX and UTC time are not defined for this time period. If your implementation assumes every days is 86,400 seconds and follow the rules for leap years, you should have accuracy to within hours, if not minutes.

Q: Is Tag 1 better than Tag 0 for time values?
A: In a lot of ways it is, because it is just a simple integer. It takes up a lot less space. It is a lot simpler to parse. Most OS’s have the ability to turn POSIX time into a structure of month, day, year, hour, minute and second. Note however that POSIX time has a discontinuity of about once every year for leap second adjustment.

Q: What is a leap second?
A: It actually takes the earth about 1 year and 1 second to revolve around the sun, so 1 extra second has to be added almost every year. UTC Time handles this by counting the seconds from 0-60 (not 0-59) in the last minute of the year. This standard uses POSIX time which can be said to handle this by the clock stopping for 1 second in the last minute of the year. 

Q: Do I have to implement floating point time?
A: No. There are not many use cases that need it. However for maximal interoperability, it is good to support it.

Q: When should I use floating point?
A: Only if you need time resolution greater than one second. There is no benefit otherwise. 64-bit time can represent time +/-500 billion years in the same number of bits, so floating point time is unnecessary for very large times scales.

Q: What resolution to I get with floating point?
A: It varies over the years. For 1970 to 1971 you get almost nanosecond accuracy. For the current century, 2000-2099, you get microsecond accuracy.  285 million years from now, it will be less than a second and the 64-bit unsigned representation will have more resolution. This is because a double only has 52 bits of resolution.

Q: Should I implement single or double floating point?
A: If you are going to use floating point you should always implement double. Single has no advantage over 32-bit integers. It provides less range and less precision. It has only 23 bits of resolution. It is of course good to support decoding of single in case some one sends you one, but there no point to ever sending a tag 1 encoded time value as a single.

Q: Can I disallow floating point time in the definition of my protocol?
A: Yes. This is a good idea if you do not need resolution less than one second. It will make implementations simpler and more compact. Note that while most CPUs do support IEEE 754 floating point, particularly small ones do not.

Q: What I’m transmitting thousands of time stamps and space is a problem?
A: If you want to maintain 1 second resolution, there is really no more compact way to transmit time than tag 1 32-bit or 64-bit integer. If you wish reduce resolution, use a different time, perhaps one that counts days rather than seconds. 

> On Jul 2, 2018, at 12:10 PM, Carsten Bormann <[email-masked]> wrote:
> 
> Hi Laurence,
>

---

From: "Macieira, Thiago" <[email-masked]>
Date: Fri, 6 Jul 2018 00:10:18 +0000

Hello Laurence

I don't see why you need to talk about the unsigned width. It's encoded as a CBOR unsigned number (major type 0) and therefore uses as many bits as necessary. That is, it has needed 32 bits to encode since the second day of the epoch and will continue to need only that much until 2106. If someone wishes to represent dates beyond that, they'll need 64-bit width. But if someone wishes to encode only the epoch itself, they need only 1 byte.

Similarly for negative: any date prior to 1970 will require negative numbers.

So if you want to implement the minimum, you implement CBOR unsigned and negative, of all widths. Any implementation not supporting 64-bit width integers is not compliant. They may be able to get away with it, but if they fail to parse wider data, the bug is in them, not the sender.

PS: double has 53 bits of resolution, not 52.
________________________________
From: CBOR [[email-masked]] on behalf of Laurence Lundblade [[email-masked]]
Sent: Thursday, July 05, 2018 14:23
To: Carsten Bormann
Cc: [email-masked]
Subject: Re: [Cbor] PR for improving epoch time (tag 1)

Hi Carsten,

I’ve updated the PR<https://github.com/cbor-wg/CBORbis/pull/27> so floating point is no longer removed, but still discourage its use unless greater than 1 second precision is needed. The interop problems I see with floating point are:
 - Small CPUs like ARM Cortex M0 and ATmega16/32U4 do not support it
 - Floating-point is extra work for a CBOR implementor (It was for me anyway)

There should be as few choices for the implementor as possible and those there are should be clear. So the choices in the PR<https://github.com/cbor-wg/CBORbis/pull/27> are mostly a) 64 or 32-bit integer support, b) support negative time (to sort your Jimi Hendrix albums), c) support double if you need microsecond time.

LL

On Jul 2, 2018, at 12:10 PM, Carsten Bormann <[email-masked]<mailto:[email-masked]>> wrote:

Hi Laurence,

Grüße, Carsten

LL

---

From: Carsten Bormann <[email-masked]>
Date: Fri, 6 Jul 2018 08:02:09 +0200

Hi Laurence,

> On Jul 5, 2018, at 23:23, Laurence Lundblade <[email-masked]> wrote:
> 

I like the idea of collecting FAQs like that.  I don’t think that the normative document (RFC7049bis) should contain all of that material.  

I’m wondering what a good place to collect that material would be; a Wiki may be a good way to start it, but the consensus vetting inherent in publishing an RFC may actually be useful here.  

This is a bit along the line of the idea of doing a “commonly used tags” RFC, which would contain information about both standardized and otherwise registered tags.

Maybe that is a good thing to start now and complete after RFC7049bis is done.

Grüße, Carsten

---

From: Carsten Bormann <[email-masked]>
Date: Fri, 6 Jul 2018 08:46:29 +0200

On Jul 5, 2018, at 23:23, Laurence Lundblade <[email-masked]> wrote:
> microsecond time

If I am not mistaken, the range for which a binary64 float gives microsecond resolution is approximately 1697-10-18 to 2242-03-16.

Obviously, Unix (“Posix”) time is somewhat questionable before 1972 (and certainly before 1958), and it does not give microsecond resolution during (added) leap seconds.

If better resolution is important, and/or a monotonic scale is desirable, tag 1001 is useful and probably should be mentioned in that FAQ as an alternative.  (We haven’t done the work to actually give 1001 a monotonic time scale, or any way to go beyond civil time — doing that would probably usefully include a discussion of proleptic time scales as well.)

Grüße, Carsten

---

From: Laurence Lundblade <[email-masked]>
Date: Fri, 6 Jul 2018 09:01:35 -0700

Hi Carsten,

Agreed that it doesn’t belong in the RFC. Maybe on cbor.io? I have a site I could publish it on too.  The vetting by discussion here is probably enough.

After some review here, I’ll update it with any needed fixes plus some links to references I found useful.

Glad you like it (and didn’t find too many errors). :-)

LL

> On Jul 5, 2018, at 11:02 PM, Carsten Bormann <[email-masked]> wrote:
> 
> Hi Laurence,
>

---

From: Laurence Lundblade <[email-masked]>
Date: Fri, 6 Jul 2018 09:20:06 -0700

Hi Thiago,

Correct me if I’m wrong, but it is OK to pick and choose bits of CBOR to implement. So, for a chip like the AtMega32U4 <https://www.microchip.com/wwwproducts/en/ATmega32U4>, RAM is so tight (2.5KB) that you might not use or want 64-bit unsigned for anything. It’s also an 8-bit CPU so just moving 64-bit quantities around, byte-swapping them and such is going to use a lot of instructions. 

As I understand the CBOR philosophy, it is a design goal to allow designs of protocols that explicitly don’t use parts of CBOR and to even error out on valid CBOR because it is outside of what is allowed for the protocol. So a protocol designed for super tiny devices like the AtMega could disallow unsigned 64 entirely and error out if it receives them.

The issue with negative is less about the integer encoding. It’s about the lack of a proper standard for time before 1970. Also, you might save some object code by not implementing negative dates as the need for them will be rare.

LL

> On Jul 5, 2018, at 5:10 PM, Macieira, Thiago <[email-masked]> wrote:
> 
> Hello Laurence
> 
>> On Jul 2, 2018, at 12:10 PM, Carsten Bormann <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> Hi Laurence,
>> 
>> https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml <https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml>
>> 
>> 1001 map
>> extended time  [draft-bormann-cbor-time-tag-01]
>>

---

From: Thiago Macieira <[email-masked]>
Date: Fri, 6 Jul 2018 10:53:26 -0700

On Friday, 6 July 2018 09:20:06 PDT Laurence Lundblade wrote:
> Hi Thiago,
> 
> Correct me if I’m wrong, but it is OK to pick and choose bits of CBOR to
> implement. So, for a chip like the AtMega32U4
> <https://www.microchip.com/wwwproducts/en/ATmega32U4>, RAM is so tight
> (2.5KB) that you might not use or want 64-bit unsigned for anything. It’s
> also an 8-bit CPU so just moving 64-bit quantities around, byte-swapping
> them and such is going to use a lot of instructions.

It's ok to pick and choose core features, but only if you don't care about 
interoperability. A non-canonical sender could send an 8-bit value in a 64-
bit-wide field for some reason, like simplification of the encoding procedure. 
The receiver must be able to handle that. Ditto for half-precision floating 
point: the canonical representation of infinity and NaN are in half-precision, 
so implementations really should implement those to make sure they can parse 
data coming from others.

Tags are a different story, since one really expects that a tag be sent only 
when the receiver is expected to know it. Replacing a core data type with a 
tagged type (bigint, bigfloat, etc.) is very different from replacing an 8-bit 
number with a 64-bit one.

This is especially true after a protocol schema is defined (e.g., via CDDL). 
The schema only says "int" or "uint" or "int / float", but never the width for 
either.

> As I understand the CBOR philosophy, it is a design goal to allow designs of
> protocols that explicitly don’t use parts of CBOR and to even error out on
> valid CBOR because it is outside of what is allowed for the protocol. So a
> protocol designed for super tiny devices like the AtMega could disallow
> unsigned 64 entirely and error out if it receives them.

If the number is out of range for the data in question, this is probably ok. 
But the protocol then needs to emphasise the need for canonical encoding, so a 
number less than 255 is never encoded with more than 1+1 bytes. Note how 
canonical encoding then turns around and requires half-precision floating 
point.

In specific for times, I don't think you need to mention anything. If I want 
to send a date in the 2200s, there's nothing wrong with my code. The receiver 
could decide to reject that because the date is meaningless, but that's an 
implementation detail based on the data, not the format.

> The issue with negative is less about the integer encoding. It’s about the
> lack of a proper standard for time before 1970. Also, you might save some
> object code by not implementing negative dates as the need for them will be
> rare.

Lots of people alive today were born before 1970. I'd think they would want 
their birth dates to be representable.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

---

From: Laurence Lundblade <[email-masked]>
Date: Fri, 6 Jul 2018 21:13:46 -0700

Hmm, seems like interoperability should be for every protocol that uses CBOR no matter what types they use and whether or not canonicalization is used.

Take a really dumb cheap sensor that sends a lot of data to a smart capable server, perhaps a camera of some sort. The CBOR protocol uses indefinite lengths for both bstr and unsorted maps because the data is too large to buffer in the small sensor’s memory.  The sensor may be dumb, but it is trusted to never duplicate map entries. The sensor only receives integer acks and command from the server so it doesn’t have to parse much at all. 

I’m thinking canonicalization should not be the only path to excellent interoperability.

LL

> On Jul 6, 2018, at 10:53 AM, Thiago Macieira <[email-masked]> wrote:
>

---

From: Thiago Macieira <[email-masked]>
Date: Sun, 8 Jul 2018 22:05:51 -0700

Which is why supporting all core types should be a requirement. If the 
protocol calls for an integer at a given position, then any encoding from 1 to 
9 bytes should be accepted. Floating point isn't required if the protocol 
requires an integer there.

The alternative is that different implementations support different aspects of 
the encoding.

On Friday, 6 July 2018 21:13:46 PDT Laurence Lundblade wrote:
> Hmm, seems like interoperability should be for every protocol that uses CBOR
> no matter what types they use and whether or not canonicalization is used.
> 
> Take a really dumb cheap sensor that sends a lot of data to a smart capable
> server, perhaps a camera of some sort. The CBOR protocol uses indefinite
> lengths for both bstr and unsorted maps because the data is too large to
> buffer in the small sensor’s memory.  The sensor may be dumb, but it is
> trusted to never duplicate map entries. The sensor only receives integer
> acks and command from the server so it doesn’t have to parse much at all.
> 
> > On Jul 6, 2018, at 10:53 AM, Thiago Macieira <[email-masked]>
> > wrote:> 
> > bit-wide field for some reason, like simplification of the encoding
> > procedure. The receiver must be able to handle that. Ditto for
> > half-precision floating point: the canonical representation of infinity
> > and NaN are in half-precision, so implementations really should implement
> > those to make sure they can parse data coming from others.
> > 
> > Tags are a different story, since one really expects that a tag be sent
> > only when the receiver is expected to know it. Replacing a core data type
> > with a tagged type (bigint, bigfloat, etc.) is very different from
> > replacing an 8-bit number with a 64-bit one.
> > 
> > This is especially true after a protocol schema is defined (e.g., via
> > CDDL). The schema only says "int" or "uint" or "int / float", but never
> > the width for either.
> > 
> >> As I understand the CBOR philosophy, it is a design goal to allow designs
> >> of protocols that explicitly don’t use parts of CBOR and to even error
> >> out on valid CBOR because it is outside of what is allowed for the
> >> protocol. So a protocol designed for super tiny devices like the AtMega
> >> could disallow unsigned 64 entirely and error out if it receives them.
> > 
> > If the number is out of range for the data in question, this is probably
> > ok. But the protocol then needs to emphasise the need for canonical
> > encoding, so a number less than 255 is never encoded with more than 1+1
> > bytes. Note how canonical encoding then turns around and requires
> > half-precision floating point.
> > 
> > In specific for times, I don't think you need to mention anything. If I
> > want to send a date in the 2200s, there's nothing wrong with my code. The
> > receiver could decide to reject that because the date is meaningless, but
> > that's an implementation detail based on the data, not the format.
> >

---

From: Laurence Lundblade <[email-masked]>
Date: Mon, 9 Jul 2018 12:12:43 -0700

Hi Thiago,

Not sure I’m following what you are saying. 

To make the example more specific:
It is a dumb sensor that generates a lot of data — a camera/imager of some sort, a flow sensor...
It uses an 8-bit CPU with only a few KB of on-board RAM like the AtMega32U4 <https://www.microchip.com/wwwproducts/en/ATmega32U4>
It talks to a smart, much more capable server
The CBOR protocol involves the server sending integer commands to the device and the device sending back the data and not much more. 

The commands are indicated by integers from 0-20 so the device never will need to parse anything but the shortest integers. Writing code to parse 64-bit integers on the 8-bit CPU would be a huge waste of code. 

The device sends data back as maps of bstrs. There is no RAM for buffering the full maps and bstrs, so indefinite lengths are used. Maps are not sorted. 

The device implements only three CBOR things:
Decoding major type 0 only for values up to 24 (no other parsing!)
Encoding indefinite length maps
Encoding indefinite length bstrs

To require this use case to use canonicalization to achieve interoperability, would require a big jump in RAM and thus probably a more expensive CPU with more on-board RAM or adding a RAM part to the device. 

It seems like the frame-up here is more like this:

1) You define your CBOR protocol in writing, perhaps with CDDL. That defines what types and encoding are going to be used. This is pretty much what we do with all the ASN.1 protocol definitions in lots of different RFCs.

2) When you implement, use a CBOR library that does what is needed. It needs to support all the types needed, be small enough, be in the right language…

You have some thoughts on which formalism will make this example interop?

LL

> On Jul 8, 2018, at 10:05 PM, Thiago Macieira <[email-masked]> wrote:
>

---

From: Thiago Macieira <[email-masked]>
Date: Mon, 9 Jul 2018 13:59:09 -0700

On Monday, 9 July 2018 12:12:43 PDT Laurence Lundblade wrote:
> The commands are indicated by integers from 0-20 so the device never will
> need to parse anything but the shortest integers. Writing code to parse
> 64-bit integers on the 8-bit CPU would be a huge waste of code.

Now imagine that the controller device is a dumb 16-bit MCU that as a dumb 
encoder that always sends 16-bit values because it can simply encode as

	0x19 V1 V2 

for any integral value.

> To require this use case to use canonicalization to achieve
> interoperability, would require a big jump in RAM and thus probably a more
> expensive CPU with more on-board RAM or adding a RAM part to the device.

Agreed. This protocol should not require canonicalisation.

> 1) You define your CBOR protocol in writing, perhaps with CDDL. That defines
> what types and encoding are going to be used. This is pretty much what we
> do with all the ASN.1 protocol definitions in lots of different RFCs.
> 
> 2) When you implement, use a CBOR library that does what is needed. It needs
> to support all the types needed, be small enough, be in the right language…
> 
> 

Yes. Your 8-bit sensor needs to support 16-bit numbers to interoperate with 
that controller.

---

From: Laurence Lundblade <[email-masked]>
Date: Mon, 9 Jul 2018 15:39:47 -0700

Shouldn’t one be able to formally and fully define a CBOR-based protocol that only ever uses 8-bit integers? In such a protocol the 16-bit encoding from the 16-bit MCU would be quite clearly out of spec (it’s also not that hard for a 16-bit MCU to always encode in 8-bits especially if it never has to encode 16-bits). 

LL

> On Jul 9, 2018, at 1:59 PM, Thiago Macieira <[email-masked]> wrote:
>

---

From: Thiago Macieira <[email-masked]>
Date: Mon, 9 Jul 2018 16:16:17 -0700

On Monday, 9 July 2018 15:39:47 PDT Laurence Lundblade wrote:
> Shouldn’t one be able to formally and fully define a CBOR-based protocol
> that only ever uses 8-bit integers? 

In my opinion? No.

CDDL does not support that either. It supports specifying ranges (minimum & 
maximum values), but not the width of the payload.

But in your protocol, if you want this, you can explicitly say so. It won't be 
done with CDDL, but with extra wording in your spec.

> In such a protocol the 16-bit encoding
> from the 16-bit MCU would be quite clearly out of spec (it’s also not that
> hard for a 16-bit MCU to always encode in 8-bits especially if it never has
> to encode 16-bits).

Suppose it does, which is why it encodes as 16-bit. It may be rare, even. But 
it saves on one compare-and-branch, plus having a variable sized encoding. No 
doubt that this non-canonical encoding saves on code size.

---

From: Laurence Lundblade <[email-masked]>
Date: Mon, 9 Jul 2018 17:04:08 -0700

If CDDL let’s you define ranges and canonical encoding is required, then for the range of 0-20, a 16-bit encoding is clearly out of spec. The receiver could safely error out on 16-bit integers. Seems we do have a formal way to define a CBOR-based protocol that only uses 8-bit integers.

The notion of “formal specification” for CBOR-based protocols seems to be the issue here.  Seems like there’s two ways right now.

CDDL (plus canonicalization?) — Seems to limit some of the CBOR constructs that can be used. Might not be possible to describe my example protocol with it.

Prose — This allows any subset of types and encodings to be used. 

I suppose it is OK to say that CDDL is the official formal way to define CBOR-based protocols and really should be used whenever possible. But, it seems we might have to also say that protocols that work on small CPUs and in small RAM, might have to define their own protocols in prose as CDDL can’t do what they want.

(Pardon, if I’m missing things about CDDL. I’m not up to speed on it yet).

LL

> On Jul 9, 2018, at 4:16 PM, Thiago Macieira <[email-masked]> wrote:
>