Descriptor là một thuộc tính phụ trợ của đặc tính BLE cung cấp siêu dữ liệu hoặc cấu hình cho giá trị của nó. Bluetooth Core Specification 5.4 định nghĩa bộ mô tả là một phần không thể thiếu của hồ sơ GATT: chúng mô tả đơn vị đo lường, phạm vi giá trị, tên văn bản và quản lý đăng ký nhận thông báo. Bộ mô tả nổi tiếng nhất là Client Characteristic Configuration Descriptor (CCCD, 0x2902), cho phép Central đăng ký nhận thông báo từ đặc tính. Theo Bluetooth SIG, 8 bộ mô tả tiêu chuẩn được chỉ định và các bộ mô tả tùy chỉnh có thể được nhà phát triển tạo cho bất kỳ siêu dữ liệu bổ sung nào.
Những điểm chính
Descriptor là một thuộc tính của giao thức GATT được gắn với Characteristic và cung cấp thông tin bổ sung về giá trị hoặc cách sử dụng của nó. Trong thuật ngữ GATT, đặc tính là dữ liệu, còn bộ mô tả là siêu dữ liệu của dữ liệu đó.
Mỗi Characteristic có thể có không hoặc nhiều bộ mô tả. Các bộ mô tả được định nghĩa như các thuộc tính riêng biệt trong bảng GATT và có UUID 16 bit riêng trong không gian Bluetooth SIG. Các bộ mô tả không thể tồn tại độc lập — chúng luôn gắn liền với một đặc tính cụ thể.
Theo Bluetooth Core Specification 5.4 (2023), các bộ mô tả được chia thành hai loại: tiêu chuẩn (do Bluetooth SIG định nghĩa) và tùy chỉnh (do nhà phát triển định nghĩa). Các bộ mô tả tiêu chuẩn có UUID trong phạm vi 0x2900–0x2908 và thực hiện các chức năng được xác định chặt chẽ. Các bộ mô tả tùy chỉnh sử dụng UUID 128 bit, tương tự như các dịch vụ và đặc tính tùy chỉnh.
Các bộ mô tả là cơ chế chính để cấu hình hành vi của kết nối BLE. Không có CCCD (0x2902) thì không thể đăng ký nhận thông báo, không có Presentation Format (0x2904) thì Central sẽ không biết cách diễn giải các byte thô của đặc tính.
CCCD với UUID 0x2902 là bộ mô tả quan trọng nhất và được sử dụng rộng rãi nhất trong BLE. Nó quản lý việc đăng ký của Central đối với Notify và Indicate từ đặc tính. Nếu không ghi vào CCCD, đặc tính sẽ không gửi thông báo, ngay cả khi nó có thuộc tính Notify.
CCCD là một giá trị 16 bit trong đó bit có ý nghĩa nhỏ nhất (0x0001) bật Notify và bit thứ hai (0x0002) bật Indicate. Central ghi giá trị mong muốn vào CCCD, qua đó đăng ký nhận thông báo. Nếu Central ghi 0x0000 — việc đăng ký bị hủy.
Cơ chế CCCD hoạt động như sau: khi Central phát hiện một đặc tính hỗ trợ Notify, nó tìm bộ mô tả CCCD của đặc tính đó và ghi 0x0001. Sau đó, mỗi khi Peripheral cập nhật giá trị đặc tính, nó sẽ tự động được gửi đến Central đã đăng ký qua Handle Value Notification (không cần yêu cầu từ Central).
Theo Apple Core Bluetooth Programming Guide, CCCD được hệ thống tự động quản lý khi setNotifyValue được gọi cho một đặc tính. Nhà phát triển không cần phải tự tìm và ghi CCCD — Core Bluetooth thực hiện việc này tự động khi bật thông báo.
Trên iOS, việc đăng ký được thực hiện thông qua phương thức setNotifyValue trên đối tượng CBPeripheral.
import CoreBluetooth
// Đăng ký nhận thông báo đặc tính
peripheral.setNotifyValue(true, for: characteristic)
// Delegate nhận giá trị đã cập nhật
func peripheral(
_ peripheral: CBPeripheral,
didUpdateValueFor characteristic: CBCharacteristic,
error: Error?
) {
// characteristic.value có dữ liệu mới
guard let data = characteristic.value else { return }
}
Trên Android, việc đăng ký thông báo được thực hiện thông qua BluetoothGatt.setCharacteristicNotification. Nhà phát triển cũng phải tự ghi giá trị 0x0001 vào CCCD.
import android.bluetooth.*;
// Bật thông báo
bluetoothGatt.setCharacteristicNotification(characteristic, true);
// Ghi 0x0001 vào CCCD
BluetoothGattDescriptor descriptor = characteristic
.getDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);
Bluetooth SIG đã định nghĩa 8 bộ mô tả tiêu chuẩn cho các tác vụ cấu hình đặc tính phổ biến. Mỗi bộ mô tả có UUID và định dạng giá trị được xác định chặt chẽ.
| UUID | Tên bộ mô tả | Mục đích | Loại giá trị |
|---|---|---|---|
| 0x2900 | Characteristic Extended Properties | Thuộc tính bổ sung của đặc tính | uint16 (mặt nạ bit) |
| 0x2901 | Characteristic User Description | Tên văn bản của đặc tính | Chuỗi UTF-8 |
| 0x2902 | Client Characteristic Configuration | Quản lý thông báo | uint16 |
| 0x2903 | Server Characteristic Configuration | Cấu hình máy chủ cho phát sóng | uint16 |
| 0x2904 | Characteristic Presentation Format | Định dạng trình bày dữ liệu | Cấu trúc (7 byte) |
| 0x2905 | Characteristic Aggregate Format | Kết hợp nhiều đặc tính | Danh sách UUID |
| 0x2906 | Valid Range | Phạm vi giá trị hợp lệ | uint16 × 2 (tối thiểu, tối đa) |
| 0x2907 | External Report Reference | Tham chiếu báo cáo bên ngoài | uint16 |
| 0x2908 | Report Reference | Tham chiếu báo cáo nội bộ | uint8 + uint16 |
Characteristic User Description (0x2901) đặc biệt hữu ích cho giao diện người dùng: nó chứa tên dễ đọc của đặc tính có thể hiển thị trong giao diện ứng dụng. Ví dụ: đặc tính Battery Level có thể có bộ mô tả User Description với giá trị “Mức sạc pin”.
Characteristic Presentation Format (0x2904) chứa thông tin về cách diễn giải giá trị đặc tính: định dạng (uint8, uint16, float), số mũ, đơn vị đo lường (qua UUID từ sổ đăng ký Bluetooth SIG), không gian tên và mô tả. Ví dụ, nhiệt độ có thể là int16 với số mũ -2 (giá trị chia 0,01°C) và đơn vị đo lường “độ Celsius”.
Quyền truy cập vào bộ mô tả khác nhau trên iOS và Android. Core Bluetooth tự động quản lý CCCD khi bật thông báo, trong khi Android yêu cầu ghi thủ công giá trị vào bộ mô tả. Hãy xem xét cả hai cách tiếp cận.
Trên iOS, nhà phát triển thường không tương tác trực tiếp với các bộ mô tả. Core Bluetooth tự động tìm CCCD và ghi giá trị cần thiết khi setNotifyValue được gọi. Để đọc bộ mô tả, phương thức discoverDescriptors được sử dụng.
// Khám phá bộ mô tả
peripheral.discoverDescriptors(for: characteristic)
// Đọc giá trị User Description
func peripheral(
_ peripheral: CBPeripheral,
didDiscoverDescriptorsFor characteristic: CBCharacteristic,
error: Error?
) {
for descriptor in characteristic.descriptors ?? [] {
if descriptor.uuid == CBUUID("2901") {
peripheral.readValue(for: descriptor)
}
}
}
Trên Android, nhà phát triển phải tìm bộ mô tả CCCD của đặc tính và ghi giá trị để bật thông báo. Đây là một bước bổ sung so với iOS.
// Đọc giá trị bộ mô tả User Description
BluetoothGattDescriptor userDesc = characteristic
.getDescriptor(
UUID.fromString("00002901-0000-1000-8000-00805F9B34FB")
);
if (userDesc != null) {
bluetoothGatt.readDescriptor(userDesc);
}
Bộ mô tả tùy chỉnh được sử dụng khi các bộ mô tả tiêu chuẩn Bluetooth SIG không đủ. Ví dụ: nhà sản xuất cảm biến y tế có thể thêm bộ mô tả với thông tin hiệu chuẩn cảm biến hoặc bộ mô tả với nhật ký lỗi.
Bộ mô tả tùy chỉnh được tạo với UUID 128 bit, tương tự như đặc tính tùy chỉnh. Ở phía Peripheral, nhà phát triển thêm nó vào đặc tính thông qua API thích hợp. Ở phía Central, bộ mô tả được phát hiện tự động khi gọi discoverDescriptors.
Khi tạo bộ mô tả tùy chỉnh, hãy tuân theo các quy tắc sau: độ dài giá trị phải khớp với loại dữ liệu mong đợi và quyền truy cập (đọc/ghi) phải được chỉ định rõ ràng. Không sử dụng UUID từ phạm vi bộ mô tả tiêu chuẩn Bluetooth SIG (0x2900–0x2908) cho mục đích tùy chỉnh.
Đặc tính và bộ mô tả là các cấp độ khác nhau của thuộc tính GATT. Đặc tính là một điểm dữ liệu, trong khi bộ mô tả là siêu dữ liệu hoặc cấu hình của nó. Sự khác biệt thể hiện ở một số khía cạnh: mục đích, UUID và quy tắc truy cập.
Đặc tính có khai báo bắt buộc luôn có trong bảng GATT. Bộ mô tả là tùy chọn — một đặc tính có thể không có bộ mô tả. Đặc tính có thể được đọc, ghi hoặc gửi thông báo độc lập. Bộ mô tả luôn gắn liền với một đặc tính và không tồn tại riêng rẽ.
Theo Bluetooth Core Specification 5.4, thứ tự các thuộc tính trong bảng GATT như sau: khai báo dịch vụ, khai báo đặc tính, giá trị đặc tính, bộ mô tả đặc tính (nếu có), sau đó là dịch vụ tiếp theo. Thứ tự này là bắt buộc để GATT client hoạt động chính xác.
Câu hỏi thường gặp
CCCD cần thiết cho việc quản lý đăng ký: thuộc tính Notify chỉ cho biết đặc tính có thể gửi thông báo, nhưng không bật chúng. Central phải đăng ký rõ ràng bằng cách ghi 0x0001 vào CCCD. Điều này ngăn việc gửi dữ liệu không mong muốn đến Central chưa sẵn sàng.
Đặc tả kỹ thuật không giới hạn số lượng bộ mô tả. Trong thực tế, mỗi đặc tính thường có 1–3 bộ mô tả: CCCD (cho đặc tính có Notify/Indicate), tùy chọn User Description và Presentation Format. Quá nhiều bộ mô tả làm tăng kích thước bảng GATT.
Trong hầu hết các trường hợp, không. Core Bluetooth trên iOS và Android tự động thêm CCCD vào các đặc tính có thuộc tính Notify hoặc Indicate. Bộ mô tả tùy chỉnh chỉ được tạo thủ công cho siêu dữ liệu cụ thể.
Không, CCCD có định dạng (uint16) và mục đích được xác định chặt chẽ — quản lý thông báo. Ghi các giá trị khác vi phạm đặc tả Bluetooth và có thể khiến việc đăng ký ngừng hoạt động. Đối với dữ liệu tùy chỉnh, hãy sử dụng bộ mô tả tùy chỉnh với UUID 128 bit.
User Description chứa tên dễ đọc của đặc tính — ví dụ: “Nhiệt độ thiết bị” thay vì UUID 0x2A6E. Ứng dụng có thể hiển thị tên này trong giao diện, giúp người dùng tương tác với thiết bị BLE dễ hiểu mà không cần chuỗi mã cứng.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm