# On Subject/Service ID ranges

**URL:** <https://forum.opencyphal.org/t/on-subject-service-id-ranges/195>\
**Category:** Development & Maintenance\
**Created:** [October 14, 2018, 2:47pm UTC](https://forum.opencyphal.org/t/on-subject-service-id-ranges/195 "2018-10-14T14:47:19Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [October 14, 2018, 2:47pm UTC](https://forum.opencyphal.org/t/on-subject-service-id-ranges/195/1 "2018-10-14T14:47:19Z")

</div>

The [standard data type set PR](https://github.com/UAVCAN/dsdl/pull/47) that I submitted several days ago might look like a chunk of data that is too big to swallow in one PR. The motivation for pooling all of the items of the new data type set together was to encourage holistic approaches and reduce possible internal inconsistencies.

What we need to agree upon right now is the general structure and not bit-level implementation details. I probably made a mistake by assigning the version number 1 to most of the new data types – @kjetilkjeka was right to point out that some of them should be reverted to v0 pending stabilization. I am going to fix that right away.

Spreading the design process thinly over multiple subsequent PR might cause unnecessary delays, and we know that our design process is a [soft real-time process, where delays can be harmful](https://forum.opencyphal.org/t/stockholm-summit-recap/170/2). I suggest we stick with that one PR unless we identified any particular blockers, in which case we can remove them from the PR and discuss separately later (although due to the above reasons that would be undesirable).

* * *

Seeing as my freshly coined term “vendor-specific public static” raised some eyebrows (justifiably), I should elaborate on that here.

As has been said elsewhere, the new standard UAVCAN data type set (can we call it “DTS”? yay another three-letter acronym) is not supposed to contain any domain-specific data types, rather it should be focused on very, very generic entities, such as physical quantities. Those should be sufficient to build very generic and flexible yet not very efficient interfaces.

Vendors and OEMs are encouraged to use the generic interfaces everywhere, resorting to vendor-specific data types where higher efficiency is desired. As I see it, there can be two kinds of vendor-specific DTS:

- Vendor-specific DTS designed for closed ecosystems. For instance, a vendor is building a vehicle or a combination of UAVCAN-interfaced modules which are tightly integrated and are not supposed to interface with any other UAVCAN hardware from any other vendor. This scenario means that the outside world does not care about the DTS defined by the vendor (or OEM, which are the same thing for the purposes of this scenario). I suggest calling such DTS a “vendor-specific private data type set”. It is said to be “private” because no one else is supposed to know or see these definitions because no one else needs to.
- Vendor-specific DTS designed for COTS equipment or open ecosystems. This is like the above, except that the equipment or vehicles designed by the vendor might need to be interfaced with third-party nodes. I suggest calling these “vendor-specific public data type set”, and I would like to further separate it into two sub-categories:
  - Data type definitions where the Subject or Service ID is assigned statically (i.e., in the name of the DSDL file, such as `123.GetCalibrationData.2.3.uavcan`). As the ID is assigned statically, we call them “static”.
  - Data type definitions where the Subject ID is not assigned statically but rather chosen by the integrator or the application designer when configuring the node (perhaps this can be done automatically at some point in a future UAVCAN v1.x). As the ID is chosen at run-time rather than statically, we call these “dynamic”.

Upon closer review of the new concept of Subject and Service ID one might see that the requirement that the static ID to be changeable at runtime becomes unnecessary if we were to avoid assigning static IDs to data types where it might require changing in the first place. Therefore it seems sensible to remove that requirement, thereby declaring that if an ID is assigned statically, it is there to stay as long as the current version of the data type definition is not deprecated. This marginally simplifies implementations and removes a certain degree of uncertainty as integrators will always be certain that all static data types are always assigned a predetermined Subject/Service ID and therefore are _always_ usable without the need for any pre-configuration.

The above has an implication that vendors can no longer define private DTS that contain static Subject/Service IDs, becase if that were the case, definitions from different vendors might conflict with each other and there would be no way of fixing that without modifying the DTS, because, see, the IDs are unchangeable. Public DTS, on the other hand, can rely on static ID as long as they are all centralized in one place, where the lack of collisions can be determined statically. Such centralized maintenance can be achieved by either assigning ID ranges to vendors (which seems wasteful, as the ID spaces are limited), or by keeping all vendor-specific definitions (in their respective namespaces) in one central repository, such as [https://github.com/UAVCAN/vendor-specific-dsdl](https://github.com/UAVCAN/vendor-specific-dsdl).

If the above reasoning is found sound, we are to end up with the following kinds of DTS:

- Standard DTS, where identifiers can be static (conflicts are not possible because the set is the same for everyone) or dynamic.
- Vendor-specific public DTS, where the identifiers can be static (conflicts are avoidable if we keep all definitions in one central repository or assign per-vendor ranges) or dynamic.
- Vendor-specific private DTS, where the identifiers can be only dynamic, because vendors wouldn’t be able to guarantee collision-free coexistence of their data types.

Extending the ideas towards the ID ranges, we might end up with the following. For Subjects:

| From | To | Purpose |
| --- | --- | --- |
| 0 | 0 | Reserved for convenience; e.g., to represent an invalid ID |
| 1 | 32767 | Dynamic (assigned by the integrator or the application designer) |
| 61440 | 62803 | Vendor-specific public static, centralized management to avoid conflicts |
| 62804 | 65535 | Standard static |

For Services is likewise:

| From | To | Purpose |
| --- | --- | --- |
| 0 | 0 | Reserved |
| 1 | 255 | Dynamic (assigned by the integrator or the application designer) |
| 256 | 383 | Vendor-specific public static, centralized management to avoid conflicts |
| 384 | 511 | Standard static |

Why standard definitions have been moved towards the end of the range: smaller numbers are easier to deal with, so by doing that we simplify the life of the integrator or application designer. The awkward looking range boundaries make more sense if viewed in base-16, e.g., 6144010 = F00016. The Subject ID 62805 used for `uavcan.node.Status` is of a particular interest, as it contains a long sequence of alternating bits: 6280510 = 11110101010101012 – this is important for automatic bit rate detection in CAN-based networks (I won’t elaborate on this further, that would be out of the scope of this post).

---

<div class="post-metadata">

**Author:** ![kjetilkjeka](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/kjetilkjeka/32/43_2.png) [@kjetilkjeka](https://forum.opencyphal.org/u/kjetilkjeka)\
**Post date:** [October 18, 2018, 11:23am UTC](https://forum.opencyphal.org/t/on-subject-service-id-ranges/195/2 "2018-10-18T11:23:04Z")

</div>

As previously mentioned I want to un-reserve 0 and make it a legal value for port.

Other than that I think we should start lower initially and expand when we have surveyed the user demands. I think more than 30k app specific ports wont be needed, while Vendor-specific is the space where we are going to need every ID we can get. My suggestion follows:

For Subjects:

| From | To | Purpose |
| --- | --- | --- |
| 0 | 4095 | Application-specific (dynamic) (assigned by the integrator or the application designer) |
| 4096 | 40959 | _Intended to grow into “app specific” or “vendor static” when usage patterns are better known_ |
| 40960 | 49151 | Vendor-specific public static, centralized management to avoid conflicts |
| 49152 | 62803 | _Intended to grow into “standard static” or “vendor static” when usage patterns are better known_ |
| 62804 | 65535 | Standard static |

For Services:

| From | To | Purpose |
| --- | --- | --- |
| 0 | 127 | Application-specific (dynamic) (assigned by the integrator or the application designer) |
| 128 | 255 | _Intended to grow into “dynamic” or “vendor static” when usage patterns are better known_ |
| 256 | 287 | Vendor-specific public static, centralized management to avoid conflicts |
| 288 | 383 | _Intended to grow into “standard static” or “vendor static” when usage patterns are better known_ |
| 384 | 511 | Standard static |

I think these ranges give us plenty of IDs to work with initially and allow us to grow all ranges as we see fit.

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [October 18, 2018, 2:10pm UTC](https://forum.opencyphal.org/t/on-subject-service-id-ranges/195/3 "2018-10-18T14:10:06Z")

</div>

After the discussion we had on GitHub, yesterday I updated [the PR](https://github.com/UAVCAN/dsdl/pull/47) to the following (copypasta):

| From | To | Purpose |
| --- | --- | --- |
| 0 | 32767 | Dynamic |
| 61440 | 62803 | Vendor-specific public static |
| 62804 | 65535 | Standard static |

| From | To | Purpose |
| --- | --- | --- |
| 0 | 127 | Dynamic |
| 256 | 383 | Vendor-specific public static |
| 384 | 511 | Standard static |

I agree with your suggestion except that I would like to keep the initial set of dynamic subject ID intentionally large (30k+ items) to support sophisticated application-specific ID distribution schemes. E.g., dedicated ranges for sensor data, actuator commands, per-subsystem division, and so on. Also 32 vendor-specific public static services might be too restrictive, considering that each new major version is supposed to consume a new static ID. Given that, I offer the following revised scheme:

| From | To | Size | Purpose |
| --- | --- | --- | --- |
| 0 | 32767 | 32768 | Dynamic |
| 32768 | 57343 | | Intended to grow into adjacent ranges |
| 57344 | 59391 | 2048 | Vendor-specific public static |
| 59392 | 62803 | | Intended to grow into adjacent ranges |
| 62804 | 65535 | 2731 | Standard static |

| From | To | Size | Purpose |
| --- | --- | --- | --- |
| 0 | 127 | 128 | Dynamic |
| 128 | 255 | | Intended to grow into adjacent ranges |
| 256 | 319 | 64 | Vendor-specific public static |
| 320 | 383 | | Intended to grow into adjacent ranges |
| 384 | 511 | 128 | Standard static |

---

<div class="post-metadata">

**Author:** ![scottdixon](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/scottdixon/32/39_2.png) [@scottdixon](https://forum.opencyphal.org/u/scottdixon)\
**Post date:** [October 19, 2018, 5:58am UTC](https://forum.opencyphal.org/t/on-subject-service-id-ranges/195/4 "2018-10-19T05:58:01Z")

</div>

One thing I’m struggling with is the term “dynamic”. We’re talking about determining “dynamic” identifiers at system definition time, not (necessarily) runtime; correct? If so then the term really is more used with things that happen at runtime and we should use a different term (e.g. we even have the dynamic node id assignment function). Perhaps static == regulated and dynamic == unregulated?

| From | To | Size | Regulated | Purpose |
| --- | --- | --- | --- | --- |
| 0 | 32767 | 32768 | | private use by systems and applications |
| 32768 | 57343 | | x | Intended to grow into adjacent ranges |
| 57344 | 59391 | 2048 | x | Vendor-specific public |
| 59392 | 62803 | | x | Intended to grow into adjacent ranges |
| 62804 | 65535 | 2731 | x | Standard |

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [October 19, 2018, 7:18am UTC](https://forum.opencyphal.org/t/on-subject-service-id-ranges/195/5 "2018-10-19T07:18:06Z")

</div>

> [@scottdixon](#):
>
> We’re talking about determining “dynamic” identifiers at system definition time, not (necessarily) runtime; correct?

Yes.

> [@scottdixon](#):
>
> e.g. we even have the dynamic node id assignment function

I am debating whether we should start saying “plug-and-play” instead.

> [@scottdixon](#):
>
> Perhaps static == regulated and dynamic == unregulated?

Makes sense to me.

---

<div class="post-metadata">

**Author:** ![kjetilkjeka](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/kjetilkjeka/32/43_2.png) [@kjetilkjeka](https://forum.opencyphal.org/u/kjetilkjeka)\
**Post date:** [October 19, 2018, 8:46am UTC](https://forum.opencyphal.org/t/on-subject-service-id-ranges/195/6 "2018-10-19T08:46:09Z")

</div>

I agree with Scott, we should change the name to something reflecting that these are really application specific (and may be static or dynamic).

Other than that I’m on board with your updated ranges. 👍
