참고 블로그:
https://zion830.tistory.com/38
https://softtone-someday.tistory.com/20
https://techzangi.tistory.com/5
esp ble hid example에서 아래와 같은 uuid128 코드가 있다.
static uint8_t hidd_service_uuid128[] = {
/* LSB <--------------------------------------------------------------------------------> MSB */
//first uuid, 16bit, [12],[13] is the value
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x12, 0x18, 0x00, 0x00,
};
static esp_ble_adv_data_t hidd_adv_data = {
.set_scan_rsp = false,
.include_name = true,
.include_txpower = true,
.min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec
.max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec
.appearance = HID_APPEARANCE_KEYBOARD,
.manufacturer_len = 0,
.p_manufacturer_data = NULL,
.service_data_len = 0,
.p_service_data = NULL,
.service_uuid_len = sizeof(hidd_service_uuid128),
.p_service_uuid = hidd_service_uuid128,
.flag = 0x6,
};
해당 bluetooth가 어떤 서비스인지를 설명하기 위해서 uuid를 정의한 내용인데,
LSB, MSB에 대한 의미와 함께, Little Endian, Big Endian 이라는 데이터 저장 방법에 대해서 알아야 한다.
* Little Endian
Little Endian 스타일은 byte를 메모리에 저장할 시에,
작은 단위의 바이트 (least significant byte) 부터 채워나가는 방식이다.
저장할 byte가 다음과 같은 2가지 예가 있다고 하자.
1) 0x0102
2) 0xFF1D
해당 값은 16진수로 표현되어 있고,
0 ~ F(F는 십진수 15에 해당)까지의 16진수를 표현하는 데는 4bit가 필요 (0000 ~ 1111)
1byte는 8bit이고, 1byte로는 0xFF 까지 표현 가능 (16진수 0xFF -> 비트 표현식: 1111 1111)
즉, 작은 단위 바이트부터 저장을 하더라도, 두자리 표현(00~FF)까지는 순서를 안뒤집어서 저장해도 되기 때문에,
Little Endian 스타일에서 역으로 저장되더라도 한자리가 아니라 두자리 씩 묶어서 역으로 저장 된다.
0x0102 -> 20, 10 순으로 저장 X -> 02, 01 순으로 저장 O
0xFF1D -> D1, FF 순으로 저장 X -> 1D, FF 순으로 저장 O
Big Endian 스타일은
앞 메모리부터 저장을 할 때, 큰 단위부터 저장한다. (사람이 읽는 순서와 동일하게 생각하면 됨)
* Bluetooth 는 Little Endian을 표준으로 한다.
위 코드의 예제를 해석하면
Bluetooth의 Standard base UUID는 아래와 같고,
00000000-0000-1000-8000-00805F9B34FB
HID UUID는 아래와 같다.
00001812-0000-1000-8000-00805F9B34FB
이를 Little Endian으로 표현하면
FB, 34, 9B, 5F, 80, 00, 00, 80, 00, 10, 00, 00, 12, 18, 00, 00
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x12, 0x18, 0x00, 0x00,
- Definition: The array hidd_service_uuid128[] is defined as a static uint8_t array. The exact UUID values are not shown in the lines I extracted, but these values are essential for defining a specific Bluetooth service, in this case, the HID (Human Interface Device) service.
- Usage:
- The UUID is used as part of a service structure configuration, which is typical in Bluetooth applications where services are identified by their UUIDs.
- .service_uuid_len indicates the length of the UUID, which is calculated as sizeof(hidd_service_uuid128). This length is crucial for Bluetooth protocols to correctly parse and understand the UUID.
- .p_service_uuid points to the hidd_service_uuid128 array, indicating that this UUID is being used to identify a particular service in the Bluetooth stack.
Role: The role of the hidd_service_uuid128[] array is to uniquely identify the Bluetooth HID service that the device provides. This UUID is fundamental for service discovery processes, where a client device can discover what services are offered by a server (in this case, the HID service). Each service on a Bluetooth device is uniquely identified using such UUIDs, enabling distinct and correct operation within the Bluetooth environment.
Let's clarify the structure of the Bluetooth UUID found in your code by comparing it more precisely against the standard base UUID and the specific part which identifies your service.
The standard base UUID for Bluetooth services is:
00000000-0000-1000-8000-00805F9B34FB
This can be dissected into segments:
- 00000000-0000-1000: This is often used to insert specific service IDs to create a full 128-bit UUID.
- 8000-00805F9B34FB: This is a fixed identifier used across all Bluetooth UUIDs to ensure uniqueness and conformity to the Bluetooth specification.
When you look at the UUID in your code:
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x12, 0x18, 0x00, 0x00,
It is formatted in a little-endian style (least significant byte first), so each segment should be read in reverse when trying to compare to the standard UUID format which is typically written in big-endian (most significant byte first).
Breaking it down:
- Bluetooth Base UUID in reverse:
- Standard Part: 00805F9B34FB when reversed byte by byte becomes 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00.
- Your code: 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00 matches this pattern exactly.
- Middle Section:
- Standard Part: 8000-0010 part of 0000-1000-8000 from the standard UUID:
- 8000 reversed is 0x00, 0x80
- 0010 reversed is 0x10, 0x00
- Your code: 0x00, 0x80, 0x00, 0x10 matches this segment as well.
- Standard Part: 8000-0010 part of 0000-1000-8000 from the standard UUID:
- Specific Service Part:
- The last segment in your UUID 0x00, 0x00, 0x12, 0x18 is specific to the HID service. The relevant part here is 0x1812 which identifies it as HID, reversed in your array to 0x12, 0x18.
Conclusion:
- The UUID in your code is built on the standard Bluetooth base UUID but includes specific bytes (0x12, 0x18) at the end, identifying the service as a Human Interface Device (HID) service.
- By using the standard base UUID and appending specific service identifiers, your UUID ensures global uniqueness and conforms to Bluetooth standards for device and service identification. This structure allows other Bluetooth devices to recognize the type of service your device provides, facilitating correct communication protocols.
Why Bluetooth Uses Little-Endian
- Consistency with Low-Level Hardware: Many microcontrollers and processors that support Bluetooth, especially those in the embedded domain, use little-endian architectures. Using little-endian in Bluetooth ensures a smoother and more efficient handling of data as it avoids the need for byte-order conversions when transmitting numbers between the Bluetooth stack and the hardware.
- Protocol Standardization: When Bluetooth standards were developed, the choice of little-endian could also stem from aiming to standardize around a common format that was prevalent among the chipsets and platforms expected to implement Bluetooth technology at the time.
Summary
The choice of endianess affects how data is serialized into bytes for transmission over a protocol or storage in memory. In systems where data frequently moves between different layers (from application logic down to physical transmission), having a consistent byte order helps reduce the overhead of conversions and can simplify the software design. Bluetooth's choice of little-endian helps align it closely with the architectures of common microcontrollers and processors that implement Bluetooth functionalities, facilitating more efficient data handling.
https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/class_u_u_i_d.html
Detailed Description
Representation of a Universally Unique Identifier (UUID).
UUIDs are 128-bit wide numbers used to identify data type and elements in many layers of the Bluetooth specification.
Two representations of UUIDS exist:
- 16-bit UUIDs: Shortened representation of the 128 bit UUID 0000xxxx-0000-1000-8000-00805F9B34FB where xxxx is the 16 bit UUID. Values of those UUIDs are defined by the Bluetooth body. The short representation saves bandwidth during protocol transactions.
- 128-bit UUIDs: Complete representation of a UUID. They are commonly used for user defined UUID.
This class acts as an adapter over these two kinds of UUIDs to allow indiscriminate use of both forms in Mbed BLE APIs.
Note32-bit UUID representation is not supported currently.Definition at line 76 of file common/UUID.h.
'MCU > Bluetooth' 카테고리의 다른 글
Bluetooth: ESP32 - examples - gatts_table_create_demo (1) | 2024.07.12 |
---|---|
Bluetooth: GAP, GATT # BLE (0) | 2024.04.14 |
Bluetooth: Protocol vs Profile (0) | 2024.04.14 |