11.6. Dịch vụ và đặc trưng¶
Khi GAP đã kết nối hai thiết bị vào một kết nối mở, tầng ngay trên nó -- Generic Attribute Profile, GATT -- phải đưa ra ý nghĩa cho các byte truyền qua kết nối đó. Lựa chọn của BLE ở đây khá khác thường. Trong khi TCP hiển thị một luồng byte thô và để ứng dụng tự tạo khung dữ liệu, GATT hiển thị một cơ sở dữ liệu khóa/giá trị nhỏ mà một bên lưu trữ và bên kia đọc, ghi hoặc đăng ký.
Cơ sở dữ liệu đó là thứ mà các nhà thiết kế ứng dụng dành phần lớn thời gian BLE của họ để suy nghĩ. Những gì camera công bố cho điện thoại, những gì nó theo dõi trên một cảm biến từ xa, cách bàn phím Bluetooth báo cho máy chủ biết phím nào được nhấn -- tất cả đều là các giá trị đặc trưng trong một cơ sở dữ liệu GATT nào đó.
11.6.1. Hai trục vai trò, không phải một¶
Một nguồn gây nhầm lẫn thường gặp: ngoại vi / trung tâm và máy chủ / máy khách là hai trục độc lập, không phải từ đồng nghĩa.
Peripheral và central là các vai trò GAP, được thiết lập trong quá trình kết nối. Peripheral quảng bá và được kết nối tới; central quét và khởi tạo kết nối. Điều này được xác định ngay khi liên kết được thiết lập và không thay đổi.
Server và client là các vai trò GATT, được thiết lập theo từng thao tác đặc trưng. Server lưu trữ đặc trưng; client đọc, ghi hoặc đăng ký đặc trưng đó.
Hai trục này được tách biệt theo đặc tả. Một peripheral thường là server (dây đai nhịp tim công bố các số đo của nó) và một central thường là client (điện thoại đọc chúng), nhưng BLE cho phép bất kỳ sự kết hợp nào -- một peripheral có thể khám phá một đặc trưng trên central mà nó vừa kết nối, hoặc một kết nối duy nhất có thể lưu trữ các dịch vụ ở cả hai phía cùng một lúc.
Hầu hết các ứng dụng camera đều tuân theo cặp kết hợp thông thường (peripheral + server, hoặc central + client), do đó phần còn lại của phần này coi chúng như một trục khi trường hợp thông thường đang được mô tả. Khi sự phân biệt là quan trọng, cả hai thuật ngữ đều được viết rõ ràng.
11.6.2. Bên trong cơ sở dữ liệu¶
Một cơ sở dữ liệu GATT là một cây. Các lá chứa các byte thực tế. Các nhánh nhóm các lá liên quan thành các đơn vị có ý nghĩa với con người.
Một cơ sở dữ liệu GATT. Các dịch vụ nhóm các đặc trưng; các đặc trưng mang các byte của ứng dụng; các bộ mô tả mang siêu dữ liệu về đặc trưng.¶
Có ba loại nút:
Một service là một nhóm logic các giá trị liên quan. Bluetooth SIG công bố các định nghĩa dịch vụ tiêu chuẩn cho các trường hợp sử dụng phổ biến -- Battery Service cho mức pin, Environmental Sensing cho nhiệt độ / độ ẩm / áp suất, Heart Rate cho các màn hình nhịp tim -- do đó một ứng dụng chung trên điện thoại có thể nhận ra một dịch vụ mà nó chưa từng thấy trước đây. Một ứng dụng cũng có thể tự do định nghĩa các dịch vụ của riêng mình cho những thứ mà SIG chưa chuẩn hóa.
Một characteristic là một giá trị có tên bên trong một dịch vụ. Dịch vụ Battery có một đặc trưng duy nhất -- Battery Level, một phần trăm một byte. Environmental Sensing có các đặc trưng riêng biệt cho nhiệt độ, độ ẩm, áp suất, v.v. Một đặc trưng là đơn vị của các thao tác GATT -- bạn đọc một đặc trưng, bạn ghi một đặc trưng, bạn đăng ký một đặc trưng.
Một descriptor là siêu dữ liệu đính kèm với một đặc trưng. Một số bộ mô tả được chuẩn hóa -- Client Characteristic Configuration Descriptor (CCCD) là cái nổi tiếng nhất, vì ghi vào nó là cách một client báo cho server "gửi cho tôi thông báo về đặc trưng này". Các bộ mô tả khác do người dùng định nghĩa và mang các thứ như định dạng trình bày hoặc thuộc tính mở rộng.
Một GATT server (thường là peripheral) khai báo cơ sở dữ liệu của nó một lần khi khởi động và cơ sở dữ liệu không thay đổi khi đang chạy. Một GATT client (thường là central) khám phá những gì có trong cơ sở dữ liệu sau khi kết nối -- duyệt qua cây, đọc UUID của các dịch vụ tìm thấy, sau đó các đặc trưng bên trong mỗi dịch vụ.
11.6.3. UUID¶
Mỗi dịch vụ, đặc trưng và bộ mô tả đều có một UUID (Universally Unique IDentifier) xác định loại thứ gì đó. UUID có ba độ rộng:
16-bit. Dành riêng cho các tiêu chuẩn được định nghĩa bởi Bluetooth SIG. Battery Service là
0x180F. Battery Level (một đặc trưng) là0x2A19. Danh sách đầy đủ được công bố trên trang assigned-numbers của Bluetooth SIG tại https://www.bluetooth.com/specifications/assigned-numbers/.32-bit. Một mức trung gian ít được sử dụng.
128-bit. Những gì tất cả mọi người khác sử dụng -- một nhà cung cấp hoặc ứng dụng tạo ngẫu nhiên một UUID và sử dụng nó cho dịch vụ hoặc đặc trưng tùy chỉnh của họ. Các camera định nghĩa giao thức riêng của mình nằm ở đây.
Lớp bluetooth.UUID chấp nhận bất kỳ trong ba độ rộng:
import bluetooth
BATTERY_SERVICE = bluetooth.UUID(0x180F)
CUSTOM_SERVICE = bluetooth.UUID("12345678-1234-5678-9abc-def012345678")
Một UUID 16-bit mã hóa thành một payload quảng bá nhỏ, đó là một lý do tại sao các dịch vụ tiêu chuẩn được ưa thích khi có một dịch vụ tồn tại -- một dây đai nhịp tim quảng bá 0x180D (Heart Rate) tốn hai byte; một UUID tùy chỉnh tốn mười sáu byte. Đối với các ứng dụng không cần khả năng tương tác tiêu chuẩn, một UUID 128-bit được tạo là câu trả lời đúng.
11.6.4. Những gì các dịch vụ được SIG chuẩn hóa mang lại cho bạn¶
Lý do sử dụng dịch vụ tiêu chuẩn rất đơn giản: các ứng dụng hiện có đã biết cách nói chuyện với nó. Một thiết bị quảng bá dịch vụ Heart Rate (0x180D) và hiển thị đặc trưng Heart Rate Measurement (0x2A37) hoạt động với mọi ứng dụng thể dục trên thế giới mà không ai cần viết code mới. Một thiết bị triển khai lại cùng dữ liệu với UUID tùy chỉnh cần ứng dụng đồng hành riêng và tài liệu giao thức riêng.
Các tiêu chuẩn đi kèm với chi phí. Bố cục byte bên trong mỗi đặc trưng được chỉ định -- SIG quyết định rằng Heart Rate Measurement là một trường cờ một byte theo sau là giá trị nhịp tim 8-bit hoặc 16-bit, tùy chọn theo sau là các khoảng R-R -- và một thiết bị tuân thủ phải theo các bố cục đó. Các dịch vụ tùy chỉnh không bị ràng buộc đó.
Câu trả lời thực tế cho camera: sử dụng dịch vụ tiêu chuẩn khi có một dịch vụ tồn tại cho loại dữ liệu bạn có (Battery Service, Environmental Sensing), và định nghĩa một dịch vụ tùy chỉnh với UUID 128-bit cho bất kỳ thứ gì đặc thù cho ứng dụng của bạn.
11.6.5. Đối tượng phía server và phía client¶
Đối với cùng các khối xây dựng khái niệm (dịch vụ, đặc trưng, bộ mô tả), mọi thư viện GATT đều hiển thị hai tập đối tượng song song:
Đối tượng phía server -- những gì peripheral khai báo nó lưu trữ. Trong
aioble:aioble.Service,aioble.Characteristic,aioble.Descriptor. Chúng được khởi tạo trước khi bắt đầu quảng bá và được đăng ký vớiaioble.register_services().Đối tượng phía client -- những gì central khám phá trên peer sau khi kết nối. Trong
aioble:aioble.ClientService,aioble.ClientCharacteristic,aioble.ClientDescriptor. Chúng được duyệt quaaioble.DeviceConnection.service()/services()sau khi kết nối.