diff --git a/doc/eddystone/eddystone-tlm.md b/doc/eddystone/eddystone-tlm.md new file mode 100644 index 0000000..ca04e71 --- /dev/null +++ b/doc/eddystone/eddystone-tlm.md @@ -0,0 +1,8 @@ +# Eddystone-TLM + +Eddystone beacons may transmit data about their own operation to clients. This data is called _telemetry_ and is useful for monitoring the health and operation of a fleet of beacons. Since the Eddystone-TLM frame does not contain a beacon ID, it must be paired with an identifying frame which provides the ID, either of type Eddystone-UID or Eddystone-URL. See Interleaving Telemetry for details. + +TLM frames may be broadcast either in the clear, like UID and URL frames, or, when a beacon has been configured as Eddystone-EID, encrypted with the identity key set during the EID configuration. When broadcast in the clear there is no message integrity validation and you should design your applications to be tolerant of the open nature of such a broadcast. + +* [Unencrypted TLM specification](tlm-plain.md) +* [Encrypted TLM specification](tlm-encrypted.md) diff --git a/doc/eddystone/eddystone-uid.md b/doc/eddystone/eddystone-uid.md new file mode 100644 index 0000000..81acd3d --- /dev/null +++ b/doc/eddystone/eddystone-uid.md @@ -0,0 +1,63 @@ +# Eddystone-UID + +The Eddystone-UID frame broadcasts an opaque, unique 16-byte Beacon ID composed of a 10-byte namespace and a 6-byte instance. The Beacon ID may be useful in mapping a device to a record in external storage. The namespace portion of the ID may be used to group a particular set of beacons, while the instance portion of the ID identifies individual devices in the group. The division of the ID into namespace and instance components may also be used to optimize BLE scanning strategies, e.g. by filtering only on the namespace. + +## Frame Specification + +The UID frame is encoded in the advertisement as a Service Data block associated with the Eddystone service UUID. The layout is: + +Byte offset | Field | Description +------------|-------|------------ +0 | Frame Type | Value = `0x00` +1 | Ranging Data | Calibrated Tx power at 0 m +2 | NID[0] | 10-byte Namespace +3 | NID[1] +4 | NID[2] +5 | NID[3] +6 | NID[4] +7 | NID[5] +8 | NID[6] +9 | NID[7] +10 | NID[8] +11 | NID[9] +12 | BID[0] | 6-byte Instance +13 | BID[1] +14 | BID[2] +15 | BID[3] +16 | BID[4] +17 | BID[5] +18 | RFU | Reserved for future use, must be`0x00` +19 | RFU | Reserved for future use, must be`0x00` + +All multi-byte values are big-endian. + +## Field Notes + +- The length of this frame is fixed and takes up the full 31 bytes of the ADV packet. The value of the Service Data Length byte must be `0x17`. Existing UID implementations that truncate the frame to omit the RFU bytes will use `0x15`, but in future should include the RFU bytes and the full length. +- The Ranging Data is the Tx power in dBm emitted by the beacon at 0 meters. Note that this is different from other beacon protocol specifications that require the Tx power to be measured at 1 m. The value is an 8-bit integer as specified by the [Tx Power Level Characteristic](https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.tx_power_level.xml) and ranges from -100 dBm to +20 dBm to a resolution of 1 dBm. See Transmit Power below for more details. +- The 10-byte Namespace ID component is unique self-assigned beacon ID namespace. See UID Construction below for recommendations on generating this unique namespace. +- The 6-byte Instance ID component is unique within the namespace. See UID Construction below for recommendations on ensuring beacon ID uniqueness. + +## Tx Power + +Tx power is the received power at 0 meters measured in dBm. The value may range from -100 dBm to +20 dBm at a resolution of 1 dBm. + +Note to developers: the best way to determine the precise value to put into this field is to measure the actual output of your beacon from 1 meter away and then add 41 dBm to that. 41dBm is the signal loss that occurs over 1 meter. + +## UID Construction + +An Eddystone-UID beacon ID is 16 bytes long, consisting of a 10-byte namespace component and 6-byte instance component. The namespace is intended to ensure ID uniqueness across multiple Eddystone implementers and may be used to filter on-device scanning for beacons. We recommend two methods for generating a unique 10-byte namespace: a truncated hash of your FQDN, or an elided UUID. + +### Truncated Hash of FQDN + +Produce a SHA-1 hash of a fully-qualified domain name that you own. If you desire additional obscurity and/or additional namespaces, you may wish to use a random subdomain under this FQDN. Select the first 10 bytes from that hash. + +### Elided Version 4 UUID + +Generate a version 4 UUID then remove bytes 5 - 10 (inclusive). For example: from this UUID: 8b0ca750-_e7a7-4e14-bd99_-095477cb3e77 remove these bytes: e7a7-4e14-bd99. This produces the following namespace: 8b0ca750095477cb3e77. + +This option may be useful if you interleave Eddystone-UID with other UUID-based frame formats. It allows you to relate your Eddystone-UID namespace to the UUID in the other frames by deriving one from the other. + +### Instance ID + +The 6-byte instance portion of the Eddystone-UID beacon ID may be assigned via any method suitable for your application. They may be random, sequential, hierarchical, or any other scheme. diff --git a/doc/eddystone/eddystone-url.md b/doc/eddystone/eddystone-url.md new file mode 100644 index 0000000..eecc4a9 --- /dev/null +++ b/doc/eddystone/eddystone-url.md @@ -0,0 +1,80 @@ +# Eddystone-URL + +The Eddystone-URL frame broadcasts a URL using a compressed encoding format in order to fit more within the limited advertisement packet. + +Once decoded, the URL can be used by any client with access to the internet. For example, if an Eddystone-URL beacon were to broadcast the URL `https://goo.gl/Aq18zF`, then any client that received this packet could choose to [visit that url](https://goo.gl/Aq18zF). + +The Eddystone-URL frame forms the backbone of the [Physical Web](http://physical-web.org), an effort to enable frictionless discovery of web content relating to one’s surroundings. Eddystone-URL incorporates all of the learnings from the [UriBeacon](http://uribeacon.org) format from which it evolved. + +## Frame Specification + +Byte offset | Field | Description +------------|-------|------------ +0 | Frame Type | Value = `0x10` +1 | TX Power | Calibrated Tx power at 0 m +2 | URL Scheme | Encoded Scheme Prefix +3+ | Encoded URL | Length 1-17 + +### Tx Power Level + +Tx power is the received power at 0 meters, in dBm, and the value ranges from -100 dBm to +20 dBm to a resolution of 1 dBm. + +Note to developers: the best way to determine the precise value to put into this field is to measure the actual output of your beacon from 1 meter away and then add 41dBm to that. 41dBm is the signal loss that occurs over 1 meter. + +The value is a signed 8 bit integer as specified by +[TX Power Level Bluetooth Characteristic](https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.tx_power_level.xml). + +#### Examples + +* The value 0x12 is interpreted as +18dBm +* The value 0xEE is interpreted as -18dBm + +### URL Scheme Prefix + +The URL Scheme Prefix byte defines the identifier scheme, an optional prefix and how the remainder of the URL is encoded. + +|Decimal | Hex | Expansion +|:------- | :--------- | :-------- +|0 | 0x00 | `http://www.` +|1 | 0x01 | `https://www.` +|2 | 0x02 | `http://` +|3 | 0x03 | `https://` + +### Eddystone-URL HTTP URL encoding + +The HTTP URL scheme is defined by RFC 1738, for example +`https://goo.gl/S6zT6P`, and is used to designate Internet resources +accessible using HTTP (HyperText Transfer Protocol). + +The encoding consists of a sequence of characters. Character codes +excluded from the URL encoding are used as text expansion codes. When +a user agent receives the Eddystone-URL the byte codes in the URL +identifier are replaced by the expansion text according to the table +below. + +|Decimal | Hex | Expansion +|:------- | :--------- | :-------- +|0 | 0x00 | .com/ +|1 | 0x01 | .org/ +|2 | 0x02 | .edu/ +|3 | 0x03 | .net/ +|4 | 0x04 | .info/ +|5 | 0x05 | .biz/ +|6 | 0x06 | .gov/ +|7 | 0x07 | .com +|8 | 0x08 | .org +|9 | 0x09 | .edu +|10 | 0x0a | .net +|11 | 0x0b | .info +|12 | 0x0c | .biz +|13 | 0x0d | .gov +|14..32 | 0x0e..0x20 | Reserved for Future Use +|127..255 | 0x7F..0xFF | Reserved for Future Use + +Note: +* URLs are written only with the graphic printable characters of the US-ASCII coded character set. The octets **00-20** and **7F-FF** hexadecimal are not used. See “Excluded US-ASCII Characters” in RFC 2936. +* Range **07-13** define the same top level domains as **00-06** without a /. + +## See Also + +* **[Configuration Service Specification](docs/config-service-spec.md)** — An optional GATT service for configuring the Eddystone-URL output of your beacon diff --git a/doc/eddystone/protocol-specification.md b/doc/eddystone/protocol-specification.md new file mode 100644 index 0000000..8cd035b --- /dev/null +++ b/doc/eddystone/protocol-specification.md @@ -0,0 +1,65 @@ +# Eddystone Protocol Specification + +## Common Elements + +Every Eddystone frame type must contain the following PDU data types: + +- The _Complete List of 16-bit Service UUIDs_ as defined in The Bluetooth Core Specification Supplement (CSS) v5, Part A, § 1.1. The _Complete List of 16-bit Service UUIDs_ must contain the Eddystone Service UUID of `0xFEAA`. This is included to allow background scanning on iOS devices. +- The _Service Data_ data type, _Ibid._, § 1.11. The _Service Data - 16 bit UUID_ data type must be the Eddystone Service UUID of `0xFEAA`. + +The specific type of Eddystone frame is encoded in the high-order four bits of the first octet in the Service Data associated with the Service UUID. Permissible values are: + +Frame Type | High-Order 4 bits | Byte Value +:----------|:-----------------:|:---------: +UID | `0000` | `0x00` +URL | `0001` | `0x10` +TLM | `0010` | `0x20` +EID | `0011` | `0x30` +RESERVED | `0100` | `0x40` + + +The four low-order bits are reserved for future use and must be `0000`. + +Note: although the core Bluetooth data type are defined in the standard as +little-endian, Eddystone's multi-value bytes defined in the Service Data are +all big-endian. + +An example frame type may look like: + +Byte offset | Value | Description | Data Type +-----|:-----:|-----------|------------ + 0 | `0x02` | Length | Flags. CSS v5, Part A, § 1.3 + 1 | `0x01` | Flags data type value + 2 | `0x06` | Flags data + 3 | `0x03` | Length | Complete list of 16-bit Service UUIDs. _Ibid._ § 1.1 + 4 | `0x03` | Complete list of 16-bit Service UUIDs data type value + 5 | `0xAA` | 16-bit Eddystone UUID + 6 | `0xFE` | ... + 7 | `0x??` | Length | Service Data. _Ibid._ § 1.11 + 8 | `0x16` | Service Data data type value + 9 | `0xAA` | 16-bit Eddystone UUID +10 | `0xFE` | ... + +With subsequent bytes comprising the frame-specific Service Data. + +The individual frame types are listed below. + +## [Eddystone-UID](eddystone-uid.md) + +The Eddystone-UID frame broadcasts an opaque, unique 16-byte Beacon ID composed of a 10-byte namespace and a 6-byte instance. The Beacon ID may be useful in mapping a device to a record in external storage. The namespace portion of the ID may be used to group a particular set of beacons, while the instance ID identifies individual devices in the group. The division of the ID into namespace and instance components may also be used to optimize BLE scanning strategies, e.g. by filtering only on the namespace. + +## [Eddystone-URL](eddystone-url.md) + +The Eddystone-URL frame broadcasts a URL using a compressed encoding format in order to fit more within the limited advertisement packet. + +Once decoded, the URL can be used by any client with access to the internet. For example, if an Eddystone-URL beacon were to broadcast the URL `https://goo.gl/Aq18zF`, then any client that received this packet could choose to [visit that url](https://goo.gl/Aq18zF). + +The Eddystone-URL frame forms the backbone of the [Physical Web](http://physical-web.org), an effort to enable frictionless discovery of web content relating to one’s surroundings. Eddystone-URL incorporates all of the learnings from the [UriBeacon](http://uribeacon.org) format from which it evolved. + +## [Eddystone-TLM](eddystone-tlm.md) + +The Eddystone-TLM frame broadcasts telemetry information about the beacon itself such as battery voltage, device temperature, and counts of broadcast packets. + +## [Eddystone-EID](eddystone-eid) + +The Eddystone-EID frame broadcasts an encrypted ephemeral identifier that changes periodically at a rate determined during the initial registration with a web service. The broadcast ephemeral ID can be resolved remotely by the service with which it was registered, but to other observers appears to be changing randomly. This frame type is intended for use in security and privacy-enhanced devices. diff --git a/doc/eddystone/tlm-encrypted.md b/doc/eddystone/tlm-encrypted.md new file mode 100644 index 0000000..3751f4f --- /dev/null +++ b/doc/eddystone/tlm-encrypted.md @@ -0,0 +1,57 @@ +# Encrypted TLM Frame Specification + +If an Eddystone compatible beacon has been configured as Eddystone-EID, then when asked to broadcast its telemetry it will use this encrypted frame type to avoid transmitting information that may make the device uniquely identifiable. + +As with the plain TLM frame, the data is encoded in the advertisement as a Service Data block associated with the Eddystone service UUID. The frame type remains `0x20` and the version is `0x01`. The layout is: + +Byte offset | Field | Description +------------|-------|------------ +0 | Frame Type | Value = `0x20` +1 | Version | TLM version, value = `0x01` +2 | ETLM[0] | 12 bytes of Encrypted TLM data +3 | ETLM[1] | +4 | ETLM[2] | +5 | ETLM[3] | +6 | ETLM[4] | +7 | ETLM[5] | +8 | ETLM[6] | +9 | ETLM[7] | +10 | ETLM[8] | +11 | ETLM[9] | +12 | ETLM[10] | +13 | ETLM[11] | +14 | SALT[0] | 16-bit Salt +15 | SALT[1] | +16 | MIC[0] | 16 bit Message Integrity Check +17 | MIC[1] | + +All multi-byte values are big-endian. + +## Computing the encrypted TLM data + +Since telemetry fields change on their own schedule, the encryption scheme needs to introduce additional variability when encrypting them, so that the opacity of the eTLM broadcast is independent of the variability of the underlying data. The ETLM generation process includes a time element for this purpose. + +1. Generate a 48-bit nonce, consisting of a concatenation of: + * The common time base (same used for EID broadcasts, truncated by the same factor as in the EID generation protocol). + * 16 random bits as a salt +1. Encrypt the state signal using AES-EAX, using the nonce computed in the first step and the Identity Key from the EID configuration process. This produces: + * Telemetry ciphertext of the same length as the cleartext input + * A 16-bit Message Integrity Check tag +1. Transmit a concatenation of: + * The encrypted telemetry + * The 16 bit random salt + * The 16-bit integrity check tag + +## Decrypting the encrypted TLM data + +Just as plain TLM depends on being paired with a UID to be useful, ETLM depends on being paired with an EID broadcast. To report the telemetry, the client pairs ETLM and EID broadcasts received from the same device address near the same time. + +Once the ETLM is paired with a resolved EID broadcast: + +1. Retrieve the Identity Key and clock offset for that beacon +1. Perform AES-EAX decryption operation using: + * The truncated time + * The "salt" from the broadcast, and + * The Identity Key from storage +1. Check the AES-EAX output against the integrity check tag in the ETLM broadcast. +1. Store/use the decrypted telemetry data output from the AES operation. diff --git a/doc/eddystone/tlm-plain.md b/doc/eddystone/tlm-plain.md new file mode 100644 index 0000000..ecaf579 --- /dev/null +++ b/doc/eddystone/tlm-plain.md @@ -0,0 +1,39 @@ +# Unencrypted TLM Frame Specification + +The TLM frame is encoded in the advertisement as a Service Data block associated with the Eddystone service UUID. The layout is: + +Byte offset | Field | Description +------------|-------|------------ +0 | Frame Type | Value = `0x20` +1 | Version | TLM version, value = `0x00` +2 | VBATT[0] | Battery voltage, 1 mV/bit +3 | VBATT[1] | +4 | TEMP[0] | Beacon temperature +5 | TEMP[1] | +6 | ADV_CNT[0] | Advertising PDU count +7 | ADV_CNT[1] | +8 | ADV_CNT[2] | +9 | ADV_CNT[3] | +10 | SEC_CNT[0] | Time since power-on or reboot +11 | SEC_CNT[1] | +12 | SEC_CNT[2] | +13 | SEC_CNT[3] | + +All multi-byte values are big-endian. + +## Field Notes + +- The length of this frame is fixed and must be truncated after the "time since power-on" bytes. The value of the Service Data Length byte must be `0x11`. +- TLM version allows for future development of this frame type. At present the value must be `0x00`. +- Battery voltage is the current battery charge in millivolts, expressed as 1 mV per bit. If not supported (for example in a USB-powered beacon) the value should be zeroed. +- Beacon temperature is the temperature in degrees Celsius sensed by the beacon and expressed in a signed [8.8 fixed-point notation](https://www.google.com/url?q=https%3A%2F%2Fcourses.cit.cornell.edu%2Fee476%2FMath%2F&sa=D&sntz=1&usg=AFQjCNG3AHS46J3FlyEoV5NY4lTYoSVOCA). If not supported the value should be set to 0x8000, -128 °C. +- ADV_CNT is the running count of advertisement frames of all types emitted by the beacon since power-up or reboot, useful for monitoring performance metrics that scale per broadcast frame. If this value is reset (e.g. on reboot), the current time field must also be reset. +- SEC_CNT is a 0.1 second resolution counter that represents time since beacon power-up or reboot. If this value is reset (e.g. on a reboot), the ADV count field must also be reset. + +## Interleaving Telemetry + +Telemetry frames should be interleaved with an identifying frame type (e.g. Eddystone-UID or Eddystone-URL). The TLM frame depends on the client to associate it with the identifying frames via the device address (since no beacon ID exists in the TLM frame). Thus it is important that a beacon that rotates or randomizes its device address uses the same device address for some period that allows for multiple ID frames and multiple TLM frames to be broadcast from the same device address. + +You may decide to interleave one TLM frame for each ID frame, or use some lower ratio depending on how critical the TLM data is for your application. For example, if your application is using the TLM for fleet management, it may be satisfied receiving one TLM frame per day, so your beacons deployed in a high traffic area may broadcast TLM only once per minute or longer, giving a high probability that a client receives the TLM frame and transmits it to your service once per day. In a low-traffic environment such an application may require a higher TLM rate. + +Finally, if your application uses TLM to (e.g.) supply up-to-the-minute runtime status information to an end user, you may wish to interleave TLM with ID frames 1 to 1.