16-bit Eddystone UUID what values should contain? - protocols

The eddystone prefix contains twice the 16-bit Eddystone UUID.
This value according the example on the protocol specification (https://github.com/google/eddystone/blob/master/protocol-specification.md) is:
0xFEAA
But I've seen beacons containing the value 0x3F3F. I didn't understand if the value 0xFEAA is not mandatory or can I put inside that field any value ?
Also I don't understand the reason why the protocol uses twice the 16-bit Eddystone UUID.
Once near the field:
"Complete list of 16-bit Service UUIDs data type value"
and another time near the field:
"Service Data data type value"

Related

Distinction Between Manufacturing Data, Service Data and Advertising Data in Bluetooth LE

In terms of BLE, I'm getting a little confused between the terms and their usage in BlueZ:
Manufacturer Data
Service Data
Advertising Data
I'm going to try to sum up what I understand and where that falls apart.
From here there is a payload in the Advertising Packet that is 31 bytes long that can be used for User Defined Data.
However, BlueZ in its advertising API have a different notion of data. It takes a dict which is of <type> <byte array> from the docs.
Looking a little more you can come across this table which seems to be of the same two byte type and data structure.
It has user defined payload in terms of:
0xFF «Manufacturer Specific Data» Bluetooth Core Specification:Vol. 3, Part C, section 8.1.4 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.4 and 18.11 (v4.0)Core Specification Supplement, Part A, section 1.4
So I downloaded the spec to try to read up on the distinction, which leads me to this sentence that I don't quite follow:
The data is sent in advertising or periodic advertising events. Host Advertising
data is placed in the AdvData field of ADV_IND, ADV_NONCONN_IND,
ADV_SCAN_IND, AUX_ADV_IND, and AUX_CHAIN_IND PDUs. Additional
Controller Advertising Data is placed in the ACAD field of AUX_ADV_IND,
AUX_SYNC_IND, and AUX_SCAN_RSP PDUs. Periodic Advertising data is
placed in the AdvData field of AUX_SYNC_IND and AUX_CHAIN_IND PDUs.
Scan Response data is sent in the ScanRspData field of SCAN_RSP PDUs or
the AdvData field of AUX_SCAN_RSP PDUs. If the complete data cannot fit in
the AdvData field of an AUX_ADV_IND, AUX_SYNC_IND, or
AUX_SCAN_RSP PDU, AUX_CHAIN_IND PDUs are used to send the
remaining fragments of the data. An AD Structure may be fragmented over two
or more PDUs
Also when I look in the BlueZ implementation of their own DBUS API, I see they provide a way to fill in manufacturing data but no way to change the type of advertising (ADV_NONCONN vs ADV_CONN)
.
They also do have an adv_data type but it's only 25 bytes? Why can I not get the full 31 bytes?
https://github.com/bluez/bluez/blob/cbbb0c2ead89ed19280ecd94e8a2fb0d22216bb6/client/advertising.c#L55
Actual Questions:
When implementing a BT peripheral using BlueZ do I have 31 or 25 bytes. Can I fill in both Service Data and Manufacturer Data for a total of 50 bytes??
Is Manufacturer Data an abstraction over Advertising Data? If so how can I access the underlying Advertising Data? If not, can I theoretically fill in both Advertising and Manufacturer data?
The image below created by Jos Ryke might be helpful to visualise what is happening.
As shown in the image, ADV FLAGS and Advertisement data make up the 31 bytes advertising payload, but there are only 26 bytes for data available. The image contains examples of Manufacturer Data (type = FF) and Service Data (type = 16)
In the D-Bus API, to change the type of advertising (ADV_NONCONN vs ADV_CONN) use the type property:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/advertising-api.txt#n37
broadcast = ADV_NONCONN
You can have both service and manufacturer data in the same advertisement (see example https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/example-advertisement#n141) but it cannot be longer than 31 bytes. With BlueZ, you can register (if I remember correctly) up to four advertisements that will be sent as different packets.
So in summary, service data and manufacturer data are sub elements types within advertising payload. BlueZ allows you to build up the different data types you want in your advertisement and then register it for broadcast.

BLE Clarifying the Read and Indicate Operations

I'm writing code for Pycom's Lopy4 board and have created a BLE service for environmental sensing which currently has one characteristic, temperature. I'm taking the temperature as a float and attempting to update the characteristic value every two seconds.
When I use a BLE scanner app, whenever I try to read, I read a value of "temperature10862," which is the characteristic's name and uuid. Yet when I press the indicate button, the value shows the correct temperature string, updating automatically every two seconds.
I'm a bit confused overall. Is this a problem with my code on the Pycom device or am I simply misunderstanding what a BLE read is supposed to be? Since the temperature values are obviously being updated on the device, but why does the client, the app, only show these values with an indication rather than a read?
I am sorry for any vagueness in the question, but any help or guidance would be appreciated.
Read Attempt
Indicate Attempt
Returning "temperature10862" as a read response is obviously incorrect. Sending the temperature as a string is in this case also incorrect, since you use the Bluetooth SIG-defined characteristic https://www.bluetooth.com/xml-viewer/?src=https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.temperature.xml. According to that the value should consist of a signed 16-bit integer in units of 0.01 degrees Celcius.
If you look at https://www.bluetooth.com/xml-viewer/?src=https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.environmental_sensing.xml, you will see that it's mandatory to support Read and optional to support Notifications. Indications, however are not permitted. So you should change your indicate property to notify instead.
The value sent should be the same regardless if the value is sent as a notification or read response.
Be sure you read the Environmental Sensing specs and follow the rest of the GATT service structure.

Decode weight in data packets from wireshark with bluetooth low energy

I've been working doing some reverse engineering to different BLE based devices and I have a weight scale where I can't find a pattern to find/decode/interpret the weight value that I can get from the android app. I was also able to get the services and characteristics of this device but did not found a SIG standard match with the UUIDs from the bluetooth site.
I'm using an nRF51 dongle to sniffing data packets between the android app and the weight scale and I can look the ble traffic, but there are several events during the communication that I can't really understand what's the relation and I can't be able to convert those values to readable weight in kg or pounds.
My target value is: 71.3kg readed from the weight scale app.
Let me show you what I get from the ble sniffer.
first I see that the master is sending notification/indication requests to the handles 0x0009(notify), 0x000c(indication) and 0x000f(notify) in each characteristic of one service.
Then I start to read notification/indications values mixed with write commands. At the end of the communication, I see some packets that I feel that they are the ones with the weight scale data and BMI.
Packets number 574, 672 and 674 in the image.
So that give us the following candidates:
1st. packet_number_574 = '000002c9070002
2nd. packet_number_672 = '420001000000005ed12059007f02c9011d01f101'
3rd. packet_number_674 = '42018c016b00070237057d001a01bc001d007c'
1st packet during the communication exchange looks more like a counter/RT/clock than a real measurement because of the data behavior, so I feel this one is not a real option.
2nd and 3rd looks more like real candidates, I have split them and convert them to decimal values and I have not found a relation, even combining bytes since this values are floating point data types. So my real question is, Am I missing something that you might see with this information? Do you know if there is a relation between this data packets and my target?
Thank you for taking your time reading me and any help could be good, thanks!
EDIT:
I have a python script that allows me to check the services and their characteristics hierarchy and some useful data like properties, their handles and descriptors.
Service 'fff0' (0000fff0-0000-1000-8000-00805f9b34fb):
Characteristic 'fff1' (0000fff1-0000-1000-8000-00805f9b34fb):
Handle: 8 (8)
Readable: False
Pro+perties: WRITE NOTIFY
Descriptor: Descriptor <Client Characteristic Configuration> (handle 0x9; uuid 00002902-0000-1000-8000-00805f9b34fb)
Characteristic 'fff2' (0000fff2-0000-1000-8000-00805f9b34fb):
Handle: 11 (b)
Readable: False
Properties: WRITE NO RESPONSE INDICATE
Descriptor: Descriptor <Client Characteristic Configuration> (handle 0xc; uuid 00002902-0000-1000-8000-00805f9b34fb)
Characteristic 'fff3' (0000fff3-0000-1000-8000-00805f9b34fb):
Handle: 14 (e)
Readable: False
Properties: NOTIFY
Descriptor: Descriptor <Client Characteristic Configuration> (handle 0xf; uuid 00002902-0000-1000-8000-00805f9b34fb)
This are the characteristics related to the notifications and indications that I see in wireshark. I think the packet number 574 (which characteristics has only a notifiy property) is more important than I think.
I solve it by myself.
This post gives me the idea to take the values (2 bytes) and multiply them by 0.1, that way I could get the weight.
In bytes I could look for my target value without decimals 713, which is in hex = 0x02c9
If we look at the packet number 574:
000002c9070002 and split it 00:00:02:c9:07:00:02
I could see that 2nd and 3rd bytes match with this pattern!
The only thing required to do is to group this bytes and multiply the decimal value 713 x 0.1 = 71.3. I made different tests and found that this pattern is constant so I feel is accurate for my solution. Hope this could help someone in the future.

How can I convert a Bluetooth 16 bit service UUID into a 128 bit UUID?

All assigned services only state the 16 bit UUID. How can I determine the 128 bit counterpart if I have to specify the service in that format?
From Service Discovery Protocol Overview I know that 128 bit UUIDs are based on a so called "BASE UUID" which is also stated there:
00000000-0000-1000-8000-00805F9B34FB
But how do I create a 128 bit UUID from the 16 bit counterpart? Probably some of the 0 digits have to be replaced, but which and how?
This can be found in the Bluetooth 4.0 Core spec Vol. 3 - Core System. See the list of adopted specs.
In Part B, covering the Service Discovery Protocol (SDP) under Chapter 2.5.1 "Searching for Services / UUID" will explain how to calculate the UUID.
The full 128-bit value of a 16-bit or 32-bit UUID may be computed by a simple arithmetic operation.
128_bit_value = 16_bit_value * 2^96 + Bluetooth_Base_UUID
128_bit_value = 32_bit_value * 2^96 + Bluetooth_Base_UUID
A 16-bit UUID may be converted to 32-bit UUID format by zero-extending the 16-bit value to 32-bits. An equivalent method is to add the 16-bit UUID value to a zero-valued 32-bit UUID.
Note that, in another section, there's a handy mnemonic:
Or, to put it more simply, the 16-bit Attribute UUID replaces the x’s in the follow-
ing:
0000xxxx-0000-1000-8000-00805F9B34FB
In addition, the 32-bit Attribute UUID replaces the x's in the following:
xxxxxxxx-0000-1000-8000-00805F9B34FB
The same equations go for attribute UUIDs. See Part F, covering the Attribute Protocol (ATT) under Chapter 3.2.1 "Protocol Requirements / Basic Concepts". 32 bit attribute UUIDs are first specified in the Bluetooth Core 4.1 spec.

MiFare - Difference between UID and Serial Number of MiFare Card

I need to read serial number of MiFare card usin WinSCard. I am able to read 7B UID from the MiFare card.
The confusion is that i dont know if the UID and the serial number of
MiFare card are same?!!
I have googled the issue but only could get partial success. I found a question on stackoverflow also but it did not help.
I found a document of NXP online which says UID and serial number are different. (on page number 3, line number 5)
There is an application of OmniKey that reads the serial number of the card, and it also returns UID only.
NXP documentation says UID <> Serial Number and a other standard OmniKey application returns UID as Serial Number.
I have started pulling my hair off on the issue. I'd greatly appreciate if anyone could help.
Each smart card contains an integrated chip with a unique permanent identification (UID) number burned-in during the manufacturing process. This UID is often referred to as the Card Serial Number (CSN). The card serial number is not encrypted and any reader that is ISO compliant can read the card serial number.
Edit 1:
Mifare Card Serial Number is the unique identifier defined in ISO 14443-3A. There are 3 types of UID defined in the standard - single (4 bytes), double (7 bytes) and triple (10 bytes). Only in first versions of the Mifare card, the UID was 4 bytes but now have migrated to 7 bytes.
EDIT 2:
It might be helpful to you...
What is the difference between a 4 byte UID and a 4 byte ID?
A 4 byte UID is an identifier which has been assigned by the card
manufacturer using a controlled database. This database ensures that a
single identifier is not used twice. In contradiction, a 4 byte ID is an
identifier which may be assigned to more then one contactless chip over
the production time of a product so that more then one card with the same
identified may be deployed into one particular contactless system.
The differentiation in this case comes from the fact that a "Serial Number" implies that the numbers are a series, thus sequentially assigned.
MIFARE cards have Unique Identification Numbers (or in short UID), which are generated by an internal rule which is not necessarily sequential. This means that if you see a card with UID 01020304050607 it does not mean that there are at least that many cards produced so far.
If you ever see someone referring to the Card Serial Number, they are in fact referring to the UID.
The only last confusion can come from the fact that MIFARE cards can be configured to return Random IDs during activation. If that is the case, you would get different "UID" each time you activate the card. In that scenario you need to read the data contained in Block 0 (for which you will need to know the key to sector 0) to get the real UID of the card.
For DesFire cards:
UID is analogous to ethernet MAC address. It is assigned by the chip
manufacturer from a database. Everyone who creates applications for
the card has access to the UID.
The Card Serial Number is specific
to the application loaded on to the card. It can only be accessed by
that application via an encryption key. If the card had several applications loaded on to
it (unlikely but possible), then each could have a different CSN.

Resources