Bluetooth Application Layer development on Nexus Channel

Would this be the fc00::/7 space?

While fc00::/7 is intended for private/local use the Nexus CIDR block is actually a public, globally addressable /48 block. You can check out the registration details for the “Nexus” IPV6 block via a whois:

 whois 2620:89:6000:0:0:0:0:0

You should see something like:

NetRange: 2620:89:6000:: - 2620:89:6000:FFFF:FFFF:FFFF:FFFF:FFFF
CIDR: 2620:89:6000::/48
NetName: NEXUS
NetHandle: NET6-2620-89-6000-1

If devices choose to implement Nexus Channel Core, they can have globally unique Nexus IDs which are also able to be made into globally unique, completely legal IPV6 addresses, allowing global addressing of devices without any NAT (of course, assuming the devices are internet connected, which many devices are not at this stage).

Nexus IDs are composed of 6-bytes (48 bits) split into two parts (described more below), and can be converted into a valid IPV6 address using EUI-64 expansion (same as MAC address expansion, described in RFC 2373).

The ‘who sent it’ is answered by each device having a “Nexus ID”, generally a permanent ID which is burned in at time of production (doesn’t matter how, but it does need to be globally unique). The Nexus ID is 48-bits, split into the following format:

  • Upper 2 bytes: uint16_t value representing " authority id"
  • Lower 4 bytes: uint32_t value representing 'device_id"

The general concept is that an ‘authority ID’ maps back to some party which is guaranteeing there are ‘no collisions’ within that ID space, so there won’t be any two devices with the same authority ID and device ID globally (generally speaking, although see authority ID 0xFE80 below for a special exception which is not intended for universally unique use).

The ‘authority IDs’ that are defined so far are:

  • 0xFFFF = reserved for development/testing (anyone can use or make IDs in this space in a pre-production/testing context)

  • 0x0000-0x00FF = reserved for core ‘GOGLA related’ use cases currently, including a ‘globally unique’ PAYG ID scheme. Authority IDs in this range are authorized to translate their Nexus ID into a globally valid IPV6 address within the Nexus CIDR block.

  • 0xFE80 = reserved for dynamically assigned Nexus IDs (e.g. nexus IDs that aren’t globally unique, e.g. if your link layer has a scheme where it dynamically assigns identities to devices that have no factory assigned ID or outside world mapping to those device IDs, you can use this authority ID). Selected to be semantically

  • 0xFFxx = Currently reserved as a special ‘broadcast designator’, that is only used as a destination address when a Nexus Channel Core device is broadcasting. May be ignored (in most cases, it will just translate to whatever ‘broadcast’ address/scheme is used by the link layer). The bottom byte is variable ‘xx’ so that in the future, its possible to add some scope context to the multicast if required (right now, the reference implementation uses 0xFF02, assuming something similar to a ‘link local’ broadcast, so we chose to stay semantically similar to the IPV6 spec, even though a bare Nexus ID isn’t an IPV6 address…). But again, we’d expect most link layer implementations to just see ‘authority ID begins with 0xFF, ok, this is a broadcast’ and ignore the rest. (the API also includes a ‘broadcast flag’ so the dest address can just be completely ignored in that case, as well).

Further, is there value in maintaining a device registry specific to this interoperability initiative?

I suspect so! For the specific universal PAYG ID use case, we’re working with GOGLA to make the existing work around universal PAYG IDs more widely available. Its certainly possible there is value in another, non-PAYG related device registry also leveraging the Nexus ID scheme.

However, do you mean a device registry related to permanent Nexus IDs (/IPV6 addresses), or device as a model that collects a certain ‘set’ of ‘resource types’ (e.g. a ‘fridge’ is a device that implements the ‘temperature’ and ‘capacity’ resources, or something like that)?

This diagram from the documentation submitted to ARIN for the Nexus IPV6 block may be helpful as well - it explains how even though the devices on a local network might not speak ‘IPV6’, a gateway can still be “IPV6 aware” and translate the “Nexus ID” of devices on the local network (on a constrained link/transport layer) to “IPV6” for addressing by the outside world, by placing those 48-bit Nexus IDs into valid IPV6 addresses in the Nexus CIDR block.

(Of course, since the ARIN block wasn’t granted at this point, the diagram shows a nonsense “2001:db8:1234” space, the actual Nexus granted block is 2620:89:6000).

Thanks for this great set of information. What types of use cases are foreseen/in use for PAYG/IoT devices that require them to be on the global internet?

Hi Vaibhav,

Essentially, the representation of the Nexus ID in IPV6 its just a convenience to allow the devices to have an IPV6 if there are other use cases (perhaps unrelated to PAYG at all) on the device that a developer might want to have a unique address to identify a device by. Because there is already space purchased and allocated for the purpose, its possible to choose to just use the Nexus ID directly as an IPV6 address (rather than needing to purchase or otherwise obtain a separate block for the same end result).

In the drawing above, it should also show how the Nexus ID can be used as a link-local unique IPV6 as well (allowing use of the ID as a direct way to address devices for systems that are already connected in a way that supports IPV6 addressing, e.g. something like RFC 7668 IPV6 over BLE)

I don’t foresee any immediate uses of a globally unique IPV6 address for PAYG use cases (as most of what we’re seeing so far are devices either directly connected to a specific backend, or via a gateway to the same effect, and ‘accessing’ the device is typically through some interface on that backend/server).

Hi @jjmilburn @benjamin.david , we have a first-pass Bluetooth device resource model up at AirLink Devices

Your thoughts would be appreciated! Several questions:

  1. Does it look like we’ve understood the current interoperability work sufficiently?
  2. Do the Bluetooth characteristics/Resource properties make sense the way they’re shown?

Note that we decided to not use IPV6 but instead have a numeric device registry specific to each manufacturer since all Bluetooth sellers have to register anyway.

Thanks for sharing this, Vaibhav! I’ll try to make a few comments based on the interaction between Nexus Channel and AIrlink, and maybe ask a few questions along the way. In general, it looks like (correct me if I’m off here) that Airlink is built around sort of ‘bundled’ resources, that is, a number of distinct, conceptually separate resource types (client info, PAYG credit, device status, etc) are exposed together as ‘one’ Bluetooth service. That makes sense, if I’m reading the first part correctly here! I think it would be great to capture any new info/actions that can be shared between devices (client info related, or OpenPaygo Token Entry, for example) as distinct resource types, and add them to the resource type registry:

Then, they’d potentially be able to be used in multimode (a gateway supporting both Airlink devices and OpenPaygo Link devices simultaneously, for instance) or non-Airlink integrations (OpenPaygo Link only) as well. That might also simplify the Airlink spec a bit, by allowing you to specify what resource types (and what attributes of those resource types) are exposed on each service, rather than writing back out individual attributes in the spec.

I’m going to go a bit deeper on a few aspects of the spec here:

Advertising Packet

The constraint on size for this packet does make the ‘custom format’ pretty important - I understand the preference here to not publish the keys for resource properties in the packet each time (e.g. you’re able to parse the value of ‘adf’ by position only, no need to send the key ‘adf’ as well). The note about the gateway expanding this out into a ‘proper’ resource (with key names for each property value) makes sense in that context, to me at least. Related to this, I’m not sure that an ‘rtr’ is necessary in the advertising packet – this isn’t exposing a valid resource (or collection of resources), as there are only values, no property keys here (however, the ‘decompressed’ representation of the resource that the gateway creates might have an rtr?).

Without making ‘adf’ (or an equivalent version field) mandatory in the packet, it may become difficult to coordinate parser versions for the advertising packet over time. Specifically, if the ‘adf’ isn’t mandatory, it might be difficult to figure out what ‘version’ of the advertising packet that different devices using different iterations of Airlink are sending. Suggest making the ‘adf’ field mandatory, and maintaining an ‘official’ Airlink list of packet contents for each ‘adf’ version that you end up defining (e…g ‘adf=1 exposes these properties from resource type A, these properties from resource type B, etc).

Consider making this advertising packet a fully-compliant CBOR array, so that the data can be parsed with standard CBOR parsers. Consider restructuring the packet so that the version/format identifier (‘adf’) come first, so that a parser can always interpret the first two bytes as ‘adf’ version, and pass the remaining packet data to an ‘adf’ version-specific parser as needed. Related to this, you could consider using the integer representation of timestamps (based on the Linux epoch in UTC), which doesn’t introduce any MySQL dependence, and take up less space than the MySQL representation.

For example, here is an annotated version of the advertising packet that can be read by a CBOR parser directly, that has all of the information currently specified in the “PUE Advertisement”, and is 23 bytes long:

Diagnostic format:

[54321, 4210818301, 21, 55, 129, 1629830325, 65340, 15]

Raw Bytes/CBOR encoded (23 bytes):


88 # array(8)
19 D431 # unsigned(54321) - first element = adf
1A FAFBFCFD # unsigned(4210818301) - 'did' (4-byte/uint32 device ID
15 # unsigned(21) - 'err' device error
18 37 # unsigned(55) - 'ds' device status
18 81 # unsigned(129) - 'fv' firmware version
1A 61253CB5 # unsigned(1629830325) - 'pts' in seconds since the epoch
19 FF3C # unsigned(65340) - 're' (cr) PAYG credit remaining
0F # unsigned(15) - 'un' PAYG credit units

I understand the need to keep advertising packets as short as practical to keep power consumption lower - so the cost of having to write a custom parser for that is arguably worth it if it keeps from needing to use extended advertising packets. The above is just an attempt to see what it would take to use a ‘standard’ CBOR array of values, so the parser only needs to know how to read CBOR (and how to interpret the adf), but the spec might already be there and I’m misreading it.

Related Question: Can devices that are not using PAYG enforcement use AirLink, or is it required that AirLink devices have some form of PAYG enforcement? I’m trying to understand whether it would be permissible to have an AirLink device in an installation which has no PAYG metering, but simply reports its own usage data (but maybe there are other PAYG devices connected to the same gateway). Depending on what your vision is and how tightly you want to scope the protocol, you might want to consider making some of the PAYG attributes optional on this advertising resource.

Another way to ask that question is - in addition to the current ‘adf’ format (which makes the PAYG-related attributes ‘mandatory’), do you think its feasible to consider future development/expansion of a new ‘non-metered’ advertising packet ‘adf’ (which would tell the parser to not look for PAYG attributes in the advertising packet) that a non-metered, non-PAYG device could use to participate in the same AirLink network? Even for PAYG devices, do you feel that sending this info in every advertisement is necessary, compared to simply querying the non-gateway devices when needed to check their PAYG credit (assuming that the gateway can determine whether they support PAYG credit or not by looking at nx/res).

Services and resource models

Looking over the existing Bluetooth services (PUE Use Service, Device Config Service, Device Discovery Services), it looks like these are essentially composed of multiple Nexus Channel ‘resources’ put together in a single resource (as the AirLink spec mentions, the OCF bridging guidelines also suggest this).

To separate concerns, how do you feel about filing those individual resources for addition to the Nexus Channel resource registry (giving them “Resource Type” IDs/rtrs) as well as filing for new ‘combined’ Airlink specific resource types (that are special resources made up of 2 or more ‘individual’ resources?). I know that OCF also has Composite Resource Types (Section 5.7), but I don’t want to suggest adding more overhead than necessary to the AirLink system - and the ‘composite’ approach would likely lead to an additional round-trip of data (e.g. one round trip to “GET” the composite resource, then another round-trip to “GET” the subresource), whereas defining AirLink specific ‘combined’ resources that take on all of the attributes of separate ‘individual’ resources can reduce the roundtrips.

I am not proposing making different characteristics or services than what the spec currently defines, I’m just seeing how you feel about trying to capture some of the separate groups of properties here as individual Nexus Channel resource types, to improve reusability and allow other developers to compose the pieces they might want/need for other use cases in the future.

Specifically, I’d suggest considering the following as resource types that might be added to the Nexus Channel Core Resource Registry, and assigning individual new RTRs to each of these device resources. Note that only GET and POST are ‘supported’ by Nexus Channel (based on the fact that existing OCF resources appear to avoid PUT for idempotent updates), but that really only matters for the Nexus Channel resource model definitions here, I think.

Separate Resource Types currently in Use by Airlink (as far as I can tell)

  1. New resource type - “Client Provisioning”

  2. [Required for POST, required on GET] Customer name (‘cn’)

  3. [Required for POST, required on GET] Customer phone (‘cp’)

  4. Sidenote: Does this need to exist on the device as a resource? It seems like something a backend would manage, not something that is ever pushed down to the device (e.g. at registration, a backend associates device A with client B). You might be able to eliminate this entirely unless the non-gateway device itself needs to store this info to make some decisions (rather than a backend simply storing an association between that client and the device).

  5. New resource type - “Device Provisioning”

  6. [Required] 6-Byte Device ID

  7. [Required] Provisioning Status (‘pst’)

  8. [Optional] IoT Backend Type (int enum, e.g. ThingsBoard, etc)

  9. [Optional] IoT Backend Auth Token (‘sat’)

  10. New resource type -“OpenPaygo Token Entry”

  11. [Required] Token String

  12. [Required] Last token received - note, you might consider using ‘seconds since last token entered’, to avoid needing to keep track of / sync actual clock time across devices.

  13. (required) ‘lcr’ last added PAYG credit (this is not applicable to general PAYG use cases, as credit is not always added, it might be subtracted or directly ‘set’ to a value - but this might be a good property of this new ‘OpenPaygo Token Entry’ resource if its something you need)

  14. New resource type - “Device Health/Status” , to capture the error data mentioned in the spec.

  15. Device error (err)

  16. Device erd

  17. PAYG Credit Resource

  18. Consider using the existing draft PAYG resource type model, but further constrain it in AirLink to only certain units and ranges (e.g. AirLink will not report PAYG credit units > 65535, e.g.). Existing resource model draft has PAYG units and PAYG credit remaining as ‘required’ fields.

  19. If the existing draft resource model won’t work, consider extending it with AirLink specific optional properties, or creating a new resource model if the paradigm is too different

  20. Some fields in the Airlink spec are specific to OpenPaygo Token or token PAYG credit management in general, and would be better added to the new ‘OpenPaygo Token Entry” resource, rather than the general PAYG resource (e.g. starting code, last entered token, last entered token value, etc)

  21. Power Used/Consumed - Consider reusing or revising the energy consumption resource type to accommodate the relevant info provided by PUE timeseries resource

  22. Power Generated - Consider reusing or revising the energy generation resource type to accommodate the relevant info provided by PUE timeseries resource

  23. Productive Use Info - Consider a resource that provides this info, but also consider - would it be possible to separate this into something more specific, e.g. a ‘pump’ resource that indicates flow? If not, it might make sense for the productive use metric to include units/productive use machine type.

  24. Battery - Consider using the existing battery resource type fields besides ‘vb’ and ‘cp’. For example, if ‘ft’ (fault) is insufficient to meet the use case you see for ‘bh’ (battery health), suggest extending/improving the existing battery resource to have a new optional ‘bh’ field. Similar for ‘pmax’,‘pmin’, and ‘tchg’ (consider extending the existing battery model with these properties).

  25. Consider using ‘ss’ (‘seconds since’) instead of ‘ts’ (absolute/UTC timestamp): This might depend on the Airlink device capabilities, but as specified, the assumption appears to be that Airlink devices all have a fairly accurate notion of the global wall-clock time. More constrained devices won’t always have an accurate wall clock, but can generally keep track of elapsed real time (seconds) in smaller increments (minutes/hours at a time). By specifying sample times in ‘seconds since sampled’ rather than timestamps, you would reduce the transmitted size (from 6 bytes down to just 1 byte, for samples taken in the last few minutes), and also support more constrained devices. Of course, the gateway device could still easily convert the ‘seconds since sampled’ into a wall-clock sample time (assuming there is fairly small, e.g. under a few seconds latency, between gateway requesting data from a non-gateway device, and the non-gateway device responding).
    Related question - is the notion here that ‘ts’ represents the timestamp of all information in the PUE resource, so the measurements must all be taken at the exact same time?

  26. Location - consider introducing a new Nexus Channel resource type in the registry that has lat/long/accuracy, with room for that ‘array’ (for historical values?) mentioned in the Airlink spec.

  27. Historical time series data - There is an existing resource type draft (‘samplelog’) that provides one way to expose a series of sampled data as a Nexus Channel resource. However, its just a draft - I’d suggest we try to use it here, or update the resource type to meet your exact needs.

If the above understanding of ‘separate’ resource types is correct (check me on that), then is it correct to say that the PUE resources are composed as follows?

PUE Timeseries Resource Type, contained subtypes

  • (existing) Battery
  • (new) Location
  • (existing) Power Generation
  • (existing) Power Consumption
  • (new) Productive Use
  • (new) Device Health/Status

PUE PAYG Resource Type, contained subtypes

  • (new) OpenPaygo Token Resource

  • (new) Device Provisioning Resource

  • (Existing) PAYG credit resource

PUE Provisioning Resource Type, contained subtypes

  • (new) Client Provisioning
  • (new) Device Provisioning
  • (new) OpenPaygo Token resource

Security and PAYG Credit Management - Sidenote

The approach to transmit credit via tokens to each individual device is possible (e.g. OpenPaygo Token Entry resource type), but there is another approach that lets you push updates (PAYG or otherwise) to the devices without needing to send tokens, while still remaining secure against replay and MITM attacks. This is the functionality provided by Nexus Channel Links. Basically, these provide application layer security between devices by using a secure key negotiation mechanism (secure as in no keys or cryptographically sensitive data are transmitted between the devices), after which two devices have a derived shared secret ‘link’ key (unique to the link between those two specific devices). That key is used to secure request/response messages (by providing a monotonically increasing nonce, and generating/appending a MAC generated using that nonce, the message payload, and the CoAP type code). The secure link is established between two devices when a ‘controller’ device receives a specific ‘origin command’ (a token keyed specifically to that controller, with information that also lets it authenticate to the specific targeted ‘accessory’ to link to). The controller then initiates the link handshake process, and the target connected accessory to link either accepts/validates it, or does not. One the link is established, both devices use the newly derived (but never exposed on the wire) secret key to secure CoAP messages sent between them.

It doesn’t require any special manufacturer authorization/steps/process to set up the link compared to generating a PAYG keycode - the same 16-byte symmetric keys provisioned inside for token acceptance (OpenPaygo Token, Nexus Keycode, etc) can be used to enable accepting/validating origin commands to establish a link.

This security is independent of any lower-level transport security (or Bluetooth pairing), and ensures that two ‘linked’ devices can securely communicate regardless of their connectivity mode (OpenPaygo Link, AirLink, CAN, etc).

You can see this in action with two dev boards here: Nexus Channel Link Security Hardware Demo - YouTube , although the code shown there hasn’t been pushed to the public repository yet (we’re looking to coordinate it with another release).

That video (and the reference code) demonstrate using Nexus Channel links to send secured request messages from a controller device to accessory devices, and handle secured responses sent back - specifically, the accessory devices are configured to only accept secured POST requests to their PAYG credit resource (ignoring unsecured ones).

So, you might want to consider reusing that functionality, and only keeping the OpenPaygo Token entry on the gateway device if you need it for a backup to deliver credit if the gateway internet access is out - or just skipping PAYG credit token support entirely if you can rely on pushing credit updates for each device from the backend to the gateway. As long as the gateway has secure links established to each other Airlink device (which is done via interaction between the ‘link handshake’ resource of the gateway/controller and each downstream ‘accessory’ device), you can rely on MITM and replay-resistant control of PAYG credit to each downstream device with no token entry needed.

hmm, the numbering seems to be off on the resource types and their attributes…

Hi Josh, this is a great set of comments and suggestions and I made sure to first digest them within our team before posting here. I’ve already incorporated quite a few of the suggestions, so let’s keep this discussion going:

  1. "In general, it looks like (correct me if I’m off here) that Airlink is built around sort of ‘bundled’ resources, that is, a number of distinct, conceptually separate resource types (client info, PAYG credit, device status, etc) are exposed together as ‘one’ Bluetooth service. "
    This is true - in general for Bluetooth we’re considering ourselves link-poor i.e. we don’t reliably know if a connection will occur. We’re also considering inventory management cases e.g. where one gateway connects to many devices to update them, and hub cases where a central wireless GSM hub connects to and updates several device’s payg status. So we’re minimizing the number of characteristics and services and choosing to bundle similar items, as all 3 cases are different from wired connections (which are reliable and one-to-not-many).
    So although we reuse the terms from other resources e.g. battery voltage vb etc, we’ve bundled those with other use items, based on when we think the update will take place e.g. during provisioning, during timeseries updates, during payment etc. Splitting up the resource models would mean several Bluetooth interactions and we wanted to avoid the O(nxm) interactions if possible. Composite resource types seem onerous for a gateway to process so we’ll leave that out for now.
    So a new manufacturer with a modified PAYG resource would extend the base resource instead of defining their own smaller resource while reusing ours. Do you think this causes unnecessary resource proliferation?

  2. adf and advertising - this makes sense, we’ve put this to the top and also collapsed the entire packet into one regular CBOR array - we found that changing the timestamps to unix and removing rtr etc saved us a couple octets which we could then use for the additional CBOR headers.
    Also made the payg bits ‘optional’ - in that we have default values. We realized that none of the advt packet is really optional because it goes as one fixed width item. So optional items just need predefined defaults.
    Hope the new version looks cleaner.

  3. Services and resource models - We’re proposing that we use the nx/res discovery resource and extend each line to include the characteristic UUID as well as Bluetooth Service UUID where that resource is bundled. Do you think that’s a sufficient implementation? To reduce data size on the nx/res below the practical 100 byte BLE limit, we’re also thinking of using a base UUID and varying only a smaller section for each characteristic/service

  4. Client provisioning - this came as a request from our clients, some of our prototypes had a display and they want their name to be shown on it to discourage theft or to identify their devicess from a sea of others (e.g. our fishing lights are often lumped on a beach by several clients). of course this introduces additional server-device syncs. What do you think?

  5. your comment on payg product type being included is spot on, we’d need a registry for those too though.

  6. Combination of resource types and subtypes - This might be ok but it might make it harder to devices to comply if a subtype changes, any thoughts on that? Could we do this, but base them loosely and not lock them to the sub-types? Do you have any strong ideas one way or another?

  7. On security and credit management - we’re prototyping with a ‘thingsboard.io’ server, which registers each device with an auth token during provisioning. Both device and server have the auth token, and a gateway needs to know the auth token to register for the device. So there’s some potential for MITM there, and your additional device-pair links would help. But again those links work well for preset device pairs, whereas we’re thinking of more ad-hoc pairings. So authentication is always between server and end device (OpenPAYGO token), with gateway only transmitting data and being able to see use data. So the only protected resource in our case is PAYG credits (and provisioning via server auth token). This makes the one-gateway-to-hundreds-of-devices cases more tractable.

Do you see a specific advantage in an app-layer authenticated link for all data transfer? Do you see it working well for one-gateway-to-very-many-devices cases? Anything remiss there from my understanding?

I’ll post another doc update once I hear your thoughts on these.

1 Like

Updated numbering formatting for section: “Separate Resource Types currently in Use by Airlink (as far as I can tell)

  1. New resource type - “Client Provisioning”

    • [Required for POST, required on GET] Customer name (‘cn’)
    • [Required for POST, required on GET] Customer phone (‘cp’)
    • Sidenote: Does this need to exist on the device as a resource? It seems like something a backend would manage, not something that is ever pushed down to the device (e.g. at registration, a backend associates device A with client B). You might be able to eliminate this entirely unless the non-gateway device itself needs to store this info to make some decisions (rather than a backend simply storing an association between that client and the device). Edit - based on your comments, it sounds like you do want this stored on the devices so the name can be displayed in the field. Understood!
  2. New resource type - “Device Provisioning”

    • [Required] 6-Byte Device ID
    • [Required] Provisioning Status (‘pst’)
    • [Optional] IoT Backend Type (int enum, e.g. ThingsBoard, etc)
    • [Optional] IoT Backend Auth Token (‘sat’)
  3. New resource type -“OpenPaygo Token Entry”

    • [Required] Token String
    • [Required] Last token received - note, you might consider using ‘seconds since last token entered’, to avoid needing to keep track of / sync actual clock time across devices.
    • (required) ‘lcr’ last added PAYG credit (this is not applicable to general PAYG use cases, as credit is not always added, it might be subtracted or directly ‘set’ to a value - but this might be a good property of this new ‘OpenPaygo Token Entry’ resource if its something you need)
  4. New resource type - “Device Health/Status” , to capture the error data mentioned in the spec.

    • Device error (err)
    • Device erd
  5. PAYG Credit Resource

    • Consider using the existing draft PAYG resource type model , but further constrain it in AirLink to only certain units and ranges (e.g. AirLink will not report PAYG credit units > 65535, e.g.). Existing resource model draft has PAYG units and PAYG credit remaining as ‘required’ fields.
    • If the existing draft resource model won’t work, consider extending it with AirLink specific optional properties, or creating a new resource model if the paradigm is too different
    • Some fields in the Airlink spec are specific to OpenPaygo Token or token PAYG credit management in general, and would be better added to the new ‘OpenPaygo Token Entry” resource, rather than the general PAYG resource (e.g. starting code, last entered token, last entered token value, etc)
  6. Power Used/Consumed - Consider reusing or revising the [energy consumption resource type] (Nexus Channel Redoc Wrapper) to accommodate the relevant info provided by PUE timeseries resource

  7. Power Generated - Consider reusing or revising the energy generation resource type to accommodate the relevant info provided by PUE timeseries resource

  8. Productive Use Info - Consider a resource that provides this info, but also consider - would it be possible to separate this into something more specific, e.g. a ‘pump’ resource that indicates flow? If not, it might make sense for the productive use metric to include units/productive use machine type.

  9. Battery - Consider using the existing battery resource type fields besides ‘vb’ and ‘cp’. For example, if ‘ft’ (fault) is insufficient to meet the use case you see for ‘bh’ (battery health), suggest extending/improving the existing battery resource to have a new optional ‘bh’ field. Similar for ‘pmax’,‘pmin’, and ‘tchg’ (consider extending the existing battery model with these properties).

    • Consider using ‘ss’ (‘seconds since’) instead of ‘ts’ (absolute/UTC timestamp): This might depend on the Airlink device capabilities, but as specified, the assumption appears to be that Airlink devices all have a fairly accurate notion of the global wall-clock time. More constrained devices won’t always have an accurate wall clock, but can generally keep track of elapsed real time (seconds) in smaller increments (minutes/hours at a time). By specifying sample times in ‘seconds since sampled’ rather than timestamps, you would reduce the transmitted size (from 6 bytes down to just 1 byte, for samples taken in the last few minutes), and also support more constrained devices. Of course, the gateway device could still easily convert the ‘seconds since sampled’ into a wall-clock sample time (assuming there is fairly small, e.g. under a few seconds latency, between gateway requesting data from a non-gateway device, and the non-gateway device responding).
      Related question - is the notion here that ‘ts’ represents the timestamp of all information in the PUE resource, so the measurements must all be taken at the exact same time?
  10. Location - consider introducing a new Nexus Channel resource type in the registry that has lat/long/accuracy, with room for that ‘array’ (for historical values?) mentioned in the Airlink spec.

  11. Historical time series data - There is an existing resource type draft (‘samplelog’) that provides one way to expose a series of sampled data as a Nexus Channel resource. However, its just a draft - I’d suggest we try to use it here, or update the resource type to meet your exact needs.

The above are my current best attempt to pull out the atomic ‘resource types’ that we’d be adding to the Nexus Channel Resource Type Registry - with the understanding that Airlink “Resources” simply pick and choose certain properties of each resource as needed. I think this is potentially easy to accomplish (?) by just specifying the following for each Airlink resource property:

  • What ‘core/atomic’ resource type model is this property mapped to?
  • What version of that resource type model was this based on (e.g. 0.7.1?)

Now, that info wouldn’t be part of the transmitted resource model, but you could include an ‘adf’ style field in each of your resources, allowing you to update/change them as needed for future expansion.

Regarding:

  1. Combination of resource types and subtypes - This might be ok but it might make it harder to devices to comply if a subtype changes, any thoughts on that? Could we do this, but base them loosely and not lock them to the sub-types? Do you have any strong ideas one way or another?

With the above, I’m not sure that there is any risk of falling out of compliance with the published subtypes, because (in the Airlink spec, not necessarily transmitted on the wire) you can pin to specific published versions of any resource type (which are all version controlled in Git anyhow).

Additionally, the Nexus Channel Resource Type Registry currently attempts to use semantic versioning. You’ll note that all of the resources there are pre-1.0. So, giving a solid ‘backwards compatible’ resource type model for subtypes used by Airlink would probably be a good enough reason to version-up to 1.0 (we’ll at that point have both in-progress wired implementations and future Airlink implementations able to match up to the same resource type models). Once we hit version 1.0 on a resource model, breaking changes (changing property key names, required values, etc) cannot be published without bumping the major version (e.g. 1.0->2.0).

Edit - I do want to respond to the other points - those are great! I want to talk a bit more with our team over here, but should have something back this week…

Thanks Josh. I had another question relating to the app-layer link- would the only needed enabler at the BLE level be a fully encrypted CBOR property called ‘command’ that accepts a longer token and that a nexus channel compatible device can use to interface with an app-layer link?

This way we could have the simpler BLE link as well as the BLE+App-layer link coexist. If there’s an app-layer link, it also makes it less important that the BLE characteristics/services map to resource models since those would be composed/transmitted within the encrypted app link. Am I understanding this correctly?

Hi Vaibhav,

These are great points. I will respond with the same numbering you used for organization:

  1. The goal of combining various properties from various resource types into a single Airlink resource (or resources) to reduce BLE transactions makes sense, I think we are aligned there. For lack of a better term, I’ll refer to those as ‘combined’ resources for now. My only comment is that it probably makes sense to define in the spec which resources and which properties from those resources are being used in each Airlink ‘combined’ resource so that its easy to refer back to the Nexus Channel Resource Type Registry and identify the same information being sent/received, rather than creating ad-hoc properties that aren’t tied to any registered resource.

I’m not sure that I understand the point about a new manufacturer with a modified PAYG resource - can you elaborate? We’d anticipate that the PAYG Credit Resource Type could be used, and a new manufacturer who had a need for new optional properties (beyond credit remaining and units of credit) could implement those as needed, without any proliferation of resources. For example, maybe a manufacturer needs to track a property ‘seconds since PAYG credit was last updated’, so they push a revision to the PAYG credit resource type model that adds a new optional ‘ss’ property (increasing the revision of the PAYG credit resource type), and they use that revision. If you chose to use that new property in Airlink, I’d anticipate an Airlink spec update that indicated the new property, and noted that the PAYG credit resource type version number being used was the newly updated version. Am I following your reasoning, or am I missing it?

  1. Regarding ADF, that makes sense. Thanks!

  2. Yes, for discovery on Airlink, providing the UUID makes a lot of sense (as you’re not handling CoAP messages, but using BLE services directly, per the bridging spec) if you know and can enforce the base UUID so that the discovery resource ‘nx/res’ can unambiguously determine what Airlink resource maps to what UUID. I’m not sure if its possible to ‘vary’ the last few bits of a characteristic UUID without registering it, though – my understanding is that BLE UUIDs must be completely regenerated for each new UUID unless registering, but I suspect you’ll have more knowledge on this point. Also, would the ‘nx/res’ resource basically be defined by a fixed/hardcoded UUID that all Airlink devices know? (that seems to make sense, I’m just checking my understanding).

Related to this point, does it make sense to include a version property in the Airlink resources, so that if you do version up a resource/service, someone can determine that? Or, will the advertised ‘adf’ be an ‘overall’ version that increases whenever the advertising packet changes or any Airlink resource version/format is updated?

  1. No objection from me - I was just curious as to whether it needed to live on the devices or not, and it sounds like it does. So, my suggestion to register this ‘client information’ as a new Nexus Channel resource type still stands. Is it just client name and phone number for now? I can help put a draft PR up (https://github.com/angaza/nexus-channel-models/pulls) or help you do it if you like! We can then get it assigned an RTR (even though its only being used in Airlink for now, just for future use - and it also lets you indicate in the Airlink spec that the client-related attributes are coming from the client information resource type, rtr=XYZ, etc)

  2. I think I may have confused myself here :). Can you help me understand what I proposed in this regard as you understand it?

  3. I think I mentioned this in the previous response, but since the resource types intentionally only have a very minimal number of ‘required’ fields, I think you are fairly safe from changes here. Additionally, once resource types are at 1.0, there cannot be breaking changes without changing the major version number (unlikely to happen without significant industry pressure, I’d think, plus, the Airlink spec can simply say ‘this Airlink resource is compatible with PAYG credit resource type version 1.X.X’, etc).

  4. That makes sense, and it was helpful to think about the hundreds-of-devices-to-one gateway you mentioned. Do you imagine many gateways connecting to one non-gateway device over its lifetime, or is it primarily one gateway to hundreds of non-gateway devices?
    The reason I ask is that there is nothing preventing the server/backend from dynamically creating ‘ad-hoc’ Nexus Channel links between a gateway (or multiple gateways) and non-gateway devices. Basically, it would just need to send an “Origin Command*” to the gateway device, which then validates it, and begins to initiate a link with the accessory devices nearby (e.g. advertising or otherwise), causing the appropriate device to validate the link and confirm it - allowing secured data to then move between the devices via the app-layer security. But nothing about that link makes it inherently long-lived, or prevents a non-gateway device from being linked to many gateways.

Note: The app-layer security operates on a resource/method pair, that is, the application code registers a resource/method as ‘secured’ or ‘unsecured’ with the app security, which then intercepts any incoming request/response messages and validates them before passing them on to the resource method handler. This is done so that its possible to, for example, secure the POST requests made to a PAYG credit resource, but leave the GET method unsecured, so no link is required to simply inquire how much credit is remaining (if desired). Similarly, you could leave the usage data collection requests as unsecured, allowing easy passage of data from non-gateway to gateway devices on the way to the server (depending on the sensitivity of the data).

One advantage of having app-layer security there is that you can easily add more ‘secured’ configuration updates or commands in the future without needing to generate special tokens for each device. E.g. once a gateway has a secured link to a non-gateway device, you can simply define a resource on the non-gateway device that has a secured method (in the Airlink case, I imagine it would be the PUT operation on a specific BLE service that hosts sensitive info that should only be changed by an authorized party). Then, data that is PUT to that resource is run through the app security handler which validates it before passing it on to the handler.

Before recommending for or against that approach, though, I’d want to understand more about the Airlink use cases and the number of round-trips via BLE that are currently required, how likely it is that a gateway will ever need to securely communicate to the same non-gateway device again in the future (are most gateway → non gateway interactions one-time only?), etc.

8.: that linked example carries an origin command in Nexus Keycode, but there is nothing preventing an origin command from being without Nexus Keycode involved at all.

App Layer Nexus Channel “Passthrough” on BLE

Regarding the app-layer link at the BLE level - yes, its possible to enable this by exposing a property that accepts opaque, binary messages up to 120 bytes. These are actually not only CBOR, but CoAP messages with either a CBOR or COSE payload (secured messages use a COSE payload, which the app security layer verifies and extracts).

So, yes, regardless of security or not, it would be possible to pass Nexus Channel messages over BLE by enabling a property that accepts up to 120 byte messages. Then, those can be passed to a CoAP parser, which then determines the content format (CBOR or COSE) based on the content-format element of the CoAP header. If it is CBOR, the payload is ‘unsecured’, and is passed directly to the relevant resource endpoint/method handler (if that resource method handler is registered as also unsecured). If the resource is secured, the CoAP parser will extract the payload and pass it to the app-security layer, which will verify/validate it, and extract and send on the payload to the appropriate resource method handler if needed.

It would also be necessary for the BLE layer to capture the Nexus ID of the sending device (so that the app security layer can look up links, which it does by looking for links by Nexus ID). Those are typically assigned in the factory, and are not the same as Bluetooth hardware IDs/MACs.

-this makes sense, I’ll rework the models to reflect and document

I think we’ll adopt your suggestion of versioning every resource, because that covers custom extensions per manufacturer without resource proliferation. An ‘adf’ for every property.

Yes exactly! On the other UUIDs, we’re wondering if they don’t need to be uniquely pre-registered per rtr, to reduce any data storage required by gateways. Each device would just report the internal combination of rtr and UUID within nx/res, that way the gateway can use the rtr value to access the same bluetooth service and not require a UUID registry.

I’ve split it out already in the uploaded airlink documentation as a ‘customer provisioning’ resource. I’m thinking it might also need a human-readable device serial number or payment reference added. Here’s the set proposed:

You had mentioned that the payg resource should include a product type e.g. water pump etc. That made sense.

So if I understand correctly, also relating to point #1, the overall suggestion would be to explicitly make the lumped bluetooth service a combination of the credit/generation/consumption etc nexus channel resources, and this would be ok as long as we move the spec of the component resources to 1.0. Coupled with the suggestion of versioning each airlink resource, yes I think this makes sense that we could have ‘Airlink 0.5 is compatible with A,B,C,D Nexus channel resources 1.0’ or such.
I think we should include this in nx/res itself, so that each resource’s version is known in case the gateway has some compatibility logic. Thoughts?

This is a potential use case for us to provide a gateway device as part of a package but also a cellphone which can cover situations when the gateway is not in cell-range. So each device could routinely be updated by two gateways. Other potential use cases are if we allow a local authority figure in a community to act as a backup in case someone’s phone is broken, to help update their credits. This is important in productive use cases since they don’t want to miss even a day of productivity and many of the customers are living hand to mouth.

I probably don’t understand enough about encryption to get how this works intuitively, and clearly you have given this some thought. Is there any documentation or example code available that you could point me to?

I could see where having example code for this kind of interaction would make this easier to adopt for someone designing a new device. Do you believe that this interaction is fairly optimal across different use cases and would become the de-facto standard? Or do you think manufacturers might develop their own application layer handshake (e.g. re-using the passthrough property in their own ways)?

We were thinking of using a uint_32 device ID per advertisement packet, would the Nexus IDs then be application layer IDs that are separate from the device ID?

1 Like

wanted to comment on this too - this makes sense. Although the device is not expected to know it’s own location but a gateway is expected to know the device’s location. Since a gateway may report on many devices (especially for the stolen device detection use case), in our calculus it made sense to include location along with an advertisement packet property posted to the server by a gateway. Interoperable gateways from other manufacturers as well as other client’s gateways from the same manufacturer would need to report this one combined property as part of enabling crowd-sourced stolen asset detection. All other properties e.g. PAYG commands could be optional to minimize data burden.

Even so, I don’t think it’s possible to mandate that an AirLink gateway always report any airlink device advertisement that it comes across, that would be too much to expect I think.

@jjmilburn I’m having some trouble understanding what the individual properties stand for in the documentation - Nexus Channel Redoc Wrapper

Specifically-
In PAYG Credit:
di = ?
In energy generation:
ft = only true/false? Can this be made into a full status so that we can use it for details?
eg, egs, egp = ?
Also, what are the units i.e. mA, mV or A, V etc?
In energy consumption:
ft = only true/false? Can this be made into a full status so that we can use it for details?
eo, eos, eop = ? in which units?
In battery:
ft = only true/false? Can this be made into a full status so that we can use it for details?
ca, ds, cg, lb = ? in which units?

Possibly this information is elsewhere?

Also, do you think we could extend the battery resource with optional properties for the 1.0 version that give the manufacturer some design feedback i.e.
LastChargeCycle BatPctMin “pmin”
LastChargeCycle BatPctMax “pmax”
LastChargeCycle ChgTime “tchg”
Bat Health “bh”
?

Hi Vaibhav,

Definitely, regarding the extension questions! Let me respond to the particular questions for each:

PAYG Credit

“di” (device IDs) is an optional list of Nexus IDs of devices that are being ‘controlled’ (typically ‘mirroring’) the credit of a controller/gateway. Based on what you’ve said about Airlink, I think this ‘di’ property would not be used/relevant in your case. Its basically exposed for diagnostics only anyway, but is used in some existing integration work).

(We can also edit the text for the optional di property description to make it more clear, if you have suggestions, but you can probably just ignore it here).

Energy Generation

Definitely! Again, these models pre 1.0 are essentially drafts. Would these changes capture your needs?

  • ‘ft’ becomes a uint8_t enum, which has at least ‘generic fault’ (fault but no description)and ‘OK’ (no faults present), or a number of different faults? Or, would it be preferable to have a bitmask-style where ft is a longer value (uint32_t, multi-byte string) and each bit maps to a specific fault (so multiple faults could be present at once in a compact way?)

  • Units are described on each of the properties, e.g.

  • eg, egs, egp: egs and egp define a time window over which ‘eg’ is computed:

(You can see the per-property details by expanding the ‘20x’ GET response, e.g. the 205 response for energy generation;
https://angaza.github.io/nexus-channel-models/resource_types/core/energy/102-generation/redoc_wrapper.html#/paths/~1ein/get

(right now, the resource only lists ‘vi’ and ‘ai’ as required).

Energy Consumption

  • Similar comment as ‘ft’ on energy generation - lets change it. Whats more flexible in your opinion, the enum, bitstring, or something else?

  • eo, eos, eop = eos and eop define a time window over which ‘eo’ is computed.

(right now, the resource only lists ‘vo’ and ‘ao’ as required).

Battery

Similar comment about ‘ft’ as the other two. I suspect we could just apply a change to all three resources here.

ca (capacity), ds (discharging status), cg (charging status), lb (t/f below low battery threshold):

100% agree that pmin, pmax, tchg, and bh could be added - I don’t see any properties on the battery resource currently that handle that information well. If you can specify some ranges for those, and enums if relevant (depending on how you model ‘bh’) I could either help put a PR up on your behalf or help you put one up.

Regarding the state of these resources - for the most part, these are derivations from the existing OCF resource models. For example, the OCF ‘battery’ resource: OCF oneIoTA

But, we intentionally spun off the Nexus Channel Core registry to allow changes like the ones you are proposing to be captured and used. I only mention this so you have an idea of where the ‘baseline draft’ models came from - we certainly expect and anticipate that these models will change based on industry needs (like the ones you are proposing!).

@Vaibhav , to get to the resource property definitions I took screenshots of above:

  1. Start at the Resource Type Registry
  2. Click on the relevant resource link (e.g. energygen.oas.yaml)
    image
  3. Click on the ‘205’ under ‘Responses’ to expand the content for a 205 response from this resource (to a GET request)

Oh I could swear I tried clicking everywhere on the page, apologies. I’ll reformat and update the Airlink manual with full details and changes per above. E.g. I’ve also created the COSE encrypted property to allow building of Nexus Channel app links above.

@jjmilburn I’ve updated the specs now, could you please take a look? I added a new column to show which resource each property is mapping to.
https://airlinkdocs.enaccess.org/AirLink%20Manual%2091fc0f59a1464a6bbb654b164ad4676f/AirLink%20Devices%204dfc27f9e47e452594ec42eafbb56154.html

Ah, I hadn’t responded to some of your questions from the above comment - let me try here.

An ‘adf’ for every property.

Sounds good. Do you think it would be possible (eventually) to navigate between different Airlink ‘adfs’ for a given Airlink resource on the website, so a developer could quickly look up what format they’d need to interface with a certain device (or, someone could just include multiple ADF handlers for a given resource if they plan to connect to devices with slightly different implementations, etc).

Each device would just report the internal combination of rtr and UUID within nx/res, that way the gateway can use the rtr value to access the same bluetooth service and not require a UUID registry.

That makes sense to me. So, as long as every Airlink device knows the fixed nx/res UUID, they can use that to determine every other UUID on a device they’re connecting to (the first connection just polls the nx/res UUID, and then makes further logic decisions based on whats available). Agreed that this eliminates the need for an offline UUID registry.

I’ve split it out already in the uploaded airlink documentation as a ‘customer provisioning’ resource. I’m thinking it might also need a human-readable device serial number or payment reference added. Here’s the set proposed:

Noted - the bit that confused me here was that the customer/client info was ‘optional’, which confused me a bit.

You had mentioned that the payg resource should include a product type e.g. water pump etc. That made sense.

I think I may have misspoken here. I’m not sure I see the use case (currently) for a product type on the PAYG credit resource. That resource currently does specify credit units (gallons, hours, minutes, etc), but that doesn’t require a product type. Can you elaborate on what the product type might be used for on that specific resource?

Other potential use cases are if we allow a local authority figure in a community to act as a backup in case someone’s phone is broken, to help update their credits. This is important in productive use cases since they don’t want to miss even a day of productivity and many of the customers are living hand to mouth.

Makes sense - thanks! It sounds like the typical non-gateway device might connect to a handful of gateways over its lifetime (usually), but not ‘dozens’. Correct me if thats wrong, I’m just building a mental model here.

I probably don’t understand enough about encryption to get how this works intuitively, and clearly you have given this some thought. Is there any documentation or example code available that you could point me to?

There is a bit, but there is a larger release pending some other gates currently. The code I want to share with you is the embedded-side code used by this demo. The code that I want to share demonstrates steps 2 and onwards (below). But, the general flow is:

  1. Backend (or some server that is aware of the secret keys of both the ‘controller’ and ‘accessory’ you wish to securely link) generates an “Origin Command” to link the devices. This is sent to the “Controller” (e.g. gateway device)
  2. The “Controller” validates it against its own secret key (ensures this command is valid for the controller to accept/has a valid MAC, hasn’t previously been used, etc), and if so, extracts information from the ‘origin command’ that can be used to send a link challenge to the specified “Accessory”. The link challenge is not equivalent to ‘a token’, its information from the server mixed with a random value from the controller/gateway… but functionally, its close enough to think of it as an ‘accessory specific one time use token’.
  • At this point, the controller has derived a ‘link security key’ that will be used to secure (generate authentication codes/MACS) for any secured messages sent to/from the accessory.
  1. The controller sends a ‘link challenge’ to the accessory, which is validated by the accessory (command has a valid MAC, is for this accessory, hasn’t been used before). The accessory uses the link challenge info and its own secret key to independently derive the same ‘link security key’ as the controller.
  2. The accessory sends back a response ‘proving’ that it knows the same link security key as the controller (without ever sending that key over the wire/air). The controller confirms this, and the link is established.
  3. All further communication between the Nexus Channel resources for these two devices can use the security layer, which will ensure that messages sent/received are not replayed (protection against MITM and replay attacks), prevents any payload tampering/modification, and protects against address spoofing (the sender has to provide their Nexus ID/some app ID which is used to look up the link security key on the receiver side)
  • The message CBOR payload is secured, as well as a nonce, and the CoAP code (GET, response code, etc).

I will share the link when the more useful code is released that has can more easily be followed with that demo…

I could see where having example code for this kind of interaction would make this easier to adopt for someone designing a new device. Do you believe that this interaction is fairly optimal across different use cases and would become the de-facto standard? Or do you think manufacturers might develop their own application layer handshake (e.g. re-using the passthrough property in their own ways)?

For the use cases encountered so far, I think the example showing use of the existing app layer link handshake (Nexus Channel Redoc Wrapper), which provides authentication/integrity is likely sufficient. Its definitely extensible, though - someone could add their own link handshake which supports multi-party/group keys (right now, links are one-to-one), encryption (secrecy) in addition to integrity/authentication, etc.

We were thinking of using a uint_32 device ID per advertisement packet, would the Nexus IDs then be application layer IDs that are separate from the device ID?

Currently, Angaza has been distributing ‘universal’ PAYG IDs freely via the Nexus API that can be converted into Nexus IDs by appending a fixed 2-byte ‘authority ID’ in front of them. These PAYG IDs are used for devices regardless of what PAYG CRM they are sold on (Angaza or otherwise), but its not clear if the Airlink “Device IDs” would be a good fit for generation from this same batch of numbers or not. If not, it might make sense to just assign a new “Authority ID” for Airlink “device IDs” (which are just the IDs as specified/in use now you are describing).

Interoperable gateways from other manufacturers as well as other client’s gateways from the same manufacturer would need to report this one combined property as part of enabling crowd-sourced stolen asset detection.

So it sounds like that you could (maybe in the future) have backend logic similar to ‘tell all gateways to be on the lookout for these reported stolen devices’, and when they pop up, you can geolocate them? That is pretty neat.

For a resource model related to location, would ‘lat/long’ be sufficient, or do you want an accuracy field as well (if available)?

Haven’t thought through this. Does any API doc system allow this? We could move to a system that does if available - do you plan to move hand-off documentation or maintain it? We could do that as a 1.0 and look for something that tracks API by version or even documents by version…

Possibly unit is sufficient, although it won’t be unique hence it seemed to make sense to have product type. Let’s take example of water flow - both a smart tap and pump would count that as a credit unit. Can you think of any other difference that needs to be captured between the two for the systems to work? If not we could remove it.

We’re trying to crowdsource the location detection, so many gateways could be authorized for a single device to aggregate ‘drive-by’ location. There wouldn’t be an actual connection, just downloading the advt packet. Although each of those gateways would need to be authorized to post that data to the device’s history on our server.

Ok as long as the Authority ID - universal PAYG ID conversion to Nexus IDs is done at the application layer this should inter-work I think?

That’s one potential selling point of interoperable systems in a region, sort of a ‘group insurance’ for interoperating distributors.

We do need this accuracy field, because we might be using basic GSM triangulation or cell-phone coordinates as a reference. Add to that BLE signal strength detection by the gateway and accuracy becomes important I think. Location is tricky!

I’m not familiar with a free tool that does this, but I believe that Redocly has some facility for this, they claim “Multiple versions supported with a version switcher”.

I’m not sure what hand-off documentation you are referring to - but we plan to keep all Nexus Channel Core models available in the registry, and would be happy to redirect any inquiries about AirLink to whatever site will store the adfs and relevant definitions for the current version if you like!

Possibly unit is sufficient, although it won’t be unique hence it seemed to make sense to have product type. Let’s take example of water flow - both a smart tap and pump would count that as a credit unit. Can you think of any other difference that needs to be captured between the two for the systems to work? If not we could remove it.

I’m a bit confused here - the PAYG credit resource makes no statement or claim about ‘what kind of device’ it is hosted on. In other words, it would be normal and expected for many different varieties of devices to have the same ‘units’ for their PAYG credit resource (e.g. seconds/hours for many time based devices). That resource simply stores / reports the remaining credit on the device (in whatever units the device uses for metering credit), and allows updating of the remaining value. Its certainly imaginable that a single device might have two different PAYG credit management schemes running simultaneously (e.g. a device that is both a metered pump and a SHS), but we’d anticipate seeing two different “PAYG credit” resources in that case on the device (as the credit for each separate ‘management scheme’ would be independent of one another).

Am I missing something? I suspect there is some other use case that might be implicitly overloaded onto the PAYG credit resource, and I’m trying to understand what it is.

We’re trying to crowdsource the location detection, so many gateways could be authorized for a single device to aggregate ‘drive-by’ location. There wouldn’t be an actual connection, just downloading the advt packet. Although each of those gateways would need to be authorized to post that data to the device’s history on our server.

That makes sense. If they are just picking up the advertising packet, and don’t need to securely message back and forth to that resource, it doesn’t sound like you’d be using Nexus Channel Security Links for that (since setting those up would imply at least one round-trip). Similarly, Nexus Channel security applies to security between the devices themselves, so the way the gateway authenticates with the cloud ‘on behalf of’ the accessory is a separate problem (one that I think you’ve solved/are solving with thingsboard, if I understand correctly?).

Ok as long as the Authority ID - universal PAYG ID conversion to Nexus IDs is done at the application layer this should inter-work I think?

I think so too.

We do need this accuracy field, because we might be using basic GSM triangulation or cell-phone coordinates as a reference. Add to that BLE signal strength detection by the gateway and accuracy becomes important I think. Location is tricky!

Sounds great! It might make sense to think about what the atomic ‘resources’ here are - is a geolocation resource fully defined by lat/long/accuracy, and how does a (separate?) bluetooth triangulation resource feed into that, etc.