bluetooth --- Bluetooth cấp thấp¶
Mô-đun này cung cấp giao diện cho bộ điều khiển Bluetooth tích hợp. Nó hỗ trợ Bluetooth Low Energy (BLE) trong các vai trò Central, Peripheral, Broadcaster và Observer, cũng như GATT Server và Client và các kênh hướng kết nối L2CAP. Một thiết bị có thể hoạt động đồng thời ở nhiều vai trò. Ghép đôi và liên kết cũng được hỗ trợ.
API này nhằm khớp với giao thức Bluetooth cấp thấp và cung cấp các thành phần cơ bản cho các lớp trừu tượng cấp cao hơn, chẳng hạn như các loại thiết bị cụ thể.
Mẹo
Đối với hầu hết các ứng dụng, hãy ưu tiên sử dụng thư viện cấp cao hơn aioble, cung cấp trình bao bọc dựa trên asyncio xung quanh mô-đun này. Xem aioble --- Async BLE.
class BLE¶
- class bluetooth.BLE¶
Trả về đối tượng BLE singleton.
Cấu hình
- active(active: bool | None = None, /) bool¶
Tùy chọn thay đổi trạng thái hoạt động của radio BLE và trả về trạng thái hiện tại.
Radio phải được kích hoạt trước khi sử dụng bất kỳ phương thức nào khác trong lớp này.
- config(param: str, /) Any¶
- config(*, **kwargs: Any) None
Lấy hoặc đặt các giá trị cấu hình của giao diện BLE. Để lấy một giá trị, tên tham số phải được trích dẫn dưới dạng chuỗi và chỉ một tham số được truy vấn tại một thời điểm. Để đặt các giá trị, hãy sử dụng cú pháp từ khóa, và có thể đặt một hoặc nhiều tham số cùng lúc.
Các giá trị hiện được hỗ trợ là:
'mac': Địa chỉ hiện đang sử dụng, tùy thuộc vào chế độ địa chỉ hiện tại. Trả về một tuple(addr_type, addr).Xem
gap_scanđể biết chi tiết về loại địa chỉ.Chỉ có thể truy vấn khi giao diện đang hoạt động.
'addr_mode': Đặt chế độ địa chỉ. Các giá trị là:Giá trị
Tên
Hành vi
0x00PUBLIC
Sử dụng địa chỉ công khai của bộ điều khiển.
0x01RANDOM
Sử dụng địa chỉ tĩnh được tạo ra.
0x02RPA
Sử dụng địa chỉ riêng tư có thể phân giải.
0x03NRPA
Sử dụng địa chỉ riêng tư không thể phân giải.
Theo mặc định, giao diện sẽ sử dụng địa chỉ PUBLIC nếu có, ngược lại sẽ sử dụng địa chỉ RANDOM.
'gap_name': Lấy/đặt tên thiết bị GAP được sử dụng bởi dịch vụ Generic Access (UUID0x1800), đặc trưng Device Name (UUID0x2a00). Có thể đặt bất cứ lúc nào và thay đổi nhiều lần.'rxbuf': Lấy/đặt kích thước tính bằng byte của bộ đệm nội bộ được dùng để lưu trữ các sự kiện đến. Bộ đệm này là toàn cục cho toàn bộ trình điều khiển BLE và xử lý dữ liệu đến cho tất cả các sự kiện, bao gồm tất cả các đặc trưng. Tăng giá trị này cho phép xử lý tốt hơn dữ liệu đến theo từng đợt (ví dụ: kết quả quét) và khả năng nhận các giá trị đặc trưng lớn hơn.'mtu': Lấy/đặt MTU sẽ được sử dụng trong quá trình trao đổi ATT MTU. MTU kết quả sẽ là giá trị nhỏ nhất giữa giá trị này và MTU của thiết bị từ xa. Trao đổi ATT MTU sẽ không tự động diễn ra (trừ khi thiết bị từ xa khởi tạo), và phải được khởi tạo thủ công bằnggattc_exchange_mtu. Sử dụng sự kiện_IRQ_MTU_EXCHANGEDđể phát hiện MTU cho một kết nối cụ thể.'bond': Đặt xem liên kết có được bật trong quá trình ghép đôi hay không. Khi được bật, các yêu cầu ghép đôi sẽ đặt cờ "bond" và các khóa sẽ được cả hai thiết bị lưu trữ.'mitm': Đặt xem bảo vệ MITM có được yêu cầu cho việc ghép đôi hay không.'io': Đặt khả năng I/O của thiết bị này.Các tùy chọn có sẵn là:
Hằng số
Giá trị
Khả năng
_IO_CAPABILITY_DISPLAY_ONLY0
Chỉ hiển thị
_IO_CAPABILITY_DISPLAY_YESNO1
Hiển thị với đầu vào có/không
_IO_CAPABILITY_KEYBOARD_ONLY2
Chỉ bàn phím
_IO_CAPABILITY_NO_INPUT_OUTPUT3
Không có đầu vào hoặc đầu ra
_IO_CAPABILITY_KEYBOARD_DISPLAY4
Bàn phím và màn hình hiển thị
'le_secure': Đặt xem ghép đôi "LE Secure" có được yêu cầu hay không. Mặc định là false (tức là cho phép "Legacy Pairing").
Xử lý sự kiện
- irq(handler: Callable[[int, Tuple], Any | None], /) None¶
Đăng ký hàm gọi lại cho các sự kiện từ BLE stack. handler nhận hai đối số:
event(sẽ là một trong các mã bên dưới) vàdata(là một tuple các giá trị theo từng sự kiện cụ thể).Lưu ý: Để tối ưu hóa ngăn phân bổ bộ nhớ không cần thiết, các mục
addr,adv_data,char_data,notify_datavàuuidtrong các tuple là các thực thể memoryview chỉ đọc trỏ đến ringbuffer nội bộ củabluetooth, và chỉ hợp lệ trong thời gian gọi hàm xử lý IRQ. Nếu chương trình cần lưu một trong các giá trị này để truy cập sau khi hàm xử lý IRQ đã trả về (ví dụ: bằng cách lưu vào một thực thể lớp hoặc biến toàn cục), thì cần tạo bản sao dữ liệu, bằng cách sử dụngbytes()hoặcbluetooth.UUID(), như thế này:connected_addr = bytes(addr) # equivalently: adv_data, char_data, or notify_data matched_uuid = bluetooth.UUID(uuid)
Ví dụ, hàm xử lý IRQ cho kết quả quét có thể kiểm tra
adv_datađể xác định xem đó có phải là thiết bị đúng không, và chỉ khi đó mới sao chép dữ liệu địa chỉ để sử dụng ở nơi khác trong chương trình. Và để in dữ liệu từ bên trong hàm xử lý IRQ, cần dùngprint(bytes(addr)).Một hàm xử lý thường phân nhánh theo mã sự kiện và giải nén tuple tải trọng theo từng sự kiện:
def bt_irq(event, data): if event == _IRQ_CENTRAL_CONNECT: conn_handle, addr_type, addr = data ... elif event == _IRQ_SCAN_RESULT: addr_type, addr, adv_type, rssi, adv_data = data ...
Mọi mã sự kiện, tải trọng mà nó cung cấp và mô tả ngắn gọn đều được liệt kê bên dưới. Đối với các sự kiện có trường
statusđược đề cập,statuslà0khi thành công và giá trị khác không theo từng triển khai cụ thể khi thất bại.Hằng số
Giá trị
Sự kiện
Tuple tải trọng
_IRQ_CENTRAL_CONNECT1
Một central đã kết nối với peripheral này.
(conn_handle, addr_type, addr)_IRQ_CENTRAL_DISCONNECT2
Một central đã ngắt kết nối khỏi peripheral này.
(conn_handle, addr_type, addr)_IRQ_GATTS_WRITE3
Một client đã kết nối đã ghi vào một đặc trưng hoặc bộ mô tả cục bộ. Sử dụng
gatts_readđể lấy giá trị mới.(conn_handle, attr_handle)_IRQ_GATTS_READ_REQUEST4
Một client đã kết nối đã phát hành yêu cầu đọc. Trả về mã lỗi khác không từ bảng bên dưới để từ chối đọc, hoặc
0/Noneđể chấp nhận.(conn_handle, attr_handle)_IRQ_SCAN_RESULT5
Một gói quảng bá duy nhất đã được nhận trong quá trình quét chủ động.
(addr_type, addr, adv_type, rssi, adv_data)_IRQ_SCAN_DONE6
Lần quét hiện tại đã kết thúc, hoặc vì thời gian đã cấu hình đã trôi qua hoặc vì
gap_scan(None)đã được gọi.()_IRQ_PERIPHERAL_CONNECT7
Một
gap_connectđã phát hành trước đó đã thành công.(conn_handle, addr_type, addr)_IRQ_PERIPHERAL_DISCONNECT8
Một peripheral đã kết nối đã ngắt kết nối.
(conn_handle, addr_type, addr)_IRQ_GATTC_SERVICE_RESULT9
Một dịch vụ đã được tìm thấy bởi
gattc_discover_services.(conn_handle, start_handle, end_handle, uuid)_IRQ_GATTC_SERVICE_DONE10
Khám phá dịch vụ đã hoàn thành.
(conn_handle, status)_IRQ_GATTC_CHARACTERISTIC_RESULT11
Một đặc trưng đã được tìm thấy bởi
gattc_discover_characteristics.(conn_handle, end_handle, value_handle, properties, uuid)_IRQ_GATTC_CHARACTERISTIC_DONE12
Khám phá đặc trưng đã hoàn thành.
(conn_handle, status)_IRQ_GATTC_DESCRIPTOR_RESULT13
Một bộ mô tả đã được tìm thấy bởi
gattc_discover_descriptors.(conn_handle, dsc_handle, uuid)_IRQ_GATTC_DESCRIPTOR_DONE14
Khám phá bộ mô tả đã hoàn thành.
(conn_handle, status)_IRQ_GATTC_READ_RESULT15
Một
gattc_readđã phát hành trước đó đã trả về dữ liệu.(conn_handle, value_handle, char_data)_IRQ_GATTC_READ_DONE16
Một
gattc_readđã phát hành trước đó đã hoàn thành.(conn_handle, value_handle, status)_IRQ_GATTC_WRITE_DONE17
Một
gattc_writeđã phát hành trước đó đã được xác nhận.(conn_handle, value_handle, status)_IRQ_GATTC_NOTIFY18
Một máy chủ từ xa đã gửi thông báo (không được xác nhận).
(conn_handle, value_handle, notify_data)_IRQ_GATTC_INDICATE19
Một máy chủ từ xa đã gửi chỉ thị (được xác nhận).
(conn_handle, value_handle, notify_data)_IRQ_GATTS_INDICATE_DONE20
Một chỉ thị đã gửi trước đó đã được client xác nhận (hoặc đã hết thời gian chờ).
(conn_handle, value_handle, status)_IRQ_MTU_EXCHANGED21
Trao đổi ATT MTU đã hoàn thành (được khởi tạo bởi một trong hai bên).
(conn_handle, mtu)_IRQ_L2CAP_ACCEPT22
Một thiết bị từ xa đã yêu cầu kết nối L2CAP trên PSM mà thiết bị này đang lắng nghe. Trả về số nguyên khác không để từ chối, hoặc
0/Noneđể chấp nhận.(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_CONNECT23
Một kênh L2CAP hiện đã được thiết lập, bằng cách chấp nhận yêu cầu đến hoặc bằng cách hoàn thành
l2cap_connectđi.(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_DISCONNECT24
Một kênh L2CAP đã bị ngắt kết nối.
statuslà0cho ngắt kết nối sạch, hoặc khác không nếu một lần thử kết nối đi thất bại.(conn_handle, cid, psm, status)_IRQ_L2CAP_RECV25
Dữ liệu đã đến trên một kênh L2CAP. Gọi
l2cap_recvintođể đọc.(conn_handle, cid)_IRQ_L2CAP_SEND_READY26
Một
l2cap_sendtrước đó đã trả vềFalseđã được xả và kênh đã sẵn sàng trở lại.statuskhác không có nghĩa là bộ đệm truyền đã tràn và ứng dụng phải gửi lại dữ liệu.(conn_handle, cid, status)_IRQ_CONNECTION_UPDATE27
Thiết bị từ xa đã cập nhật các tham số kết nối (khoảng thời gian, độ trễ, thời gian chờ giám sát).
(conn_handle, conn_interval, conn_latency, supervision_timeout, status)_IRQ_ENCRYPTION_UPDATE28
Trạng thái mã hóa của kết nối đã thay đổi, thường là sau khi ghép đôi hoặc liên kết hoàn thành.
(conn_handle, encrypted, authenticated, bonded, key_size)_IRQ_GET_SECRET29
Stack đang yêu cầu một bí mật liên kết đã lưu. Nếu
keylàNone, trả về giá trị thứindexđã lưu củasec_type; ngược lại trả về giá trị liên quan đến(sec_type, key)đã cho. Trả vềNonenếu không có gì được lưu trữ.(sec_type, index, key)_IRQ_SET_SECRET30
Stack đang yêu cầu ứng dụng lưu trữ một bí mật liên kết. Trả về
Truesau khi đã lưu.(sec_type, key, value)_IRQ_PASSKEY_ACTION31
Một hành động passkey được yêu cầu như một phần của ghép đôi. Phản hồi bằng cách sử dụng
gap_passkey; xem bảng passkey-action bên dưới để biết các hành động có thể.(conn_handle, action, passkey)Đối với sự kiện
_IRQ_GATTS_READ_REQUEST, các mã trả về có sẵn là:Hằng số
Giá trị
Ý nghĩa
_GATTS_NO_ERROR0x00Chấp nhận yêu cầu đọc.
_GATTS_ERROR_READ_NOT_PERMITTED0x02Không được phép đọc.
_GATTS_ERROR_WRITE_NOT_PERMITTED0x03Không được phép ghi.
_GATTS_ERROR_INSUFFICIENT_AUTHENTICATION0x05Client chưa xác thực.
_GATTS_ERROR_INSUFFICIENT_AUTHORIZATION0x08Client không được ủy quyền.
_GATTS_ERROR_INSUFFICIENT_ENCRYPTION0x0fLiên kết không được mã hóa.
Đối với sự kiện
_IRQ_PASSKEY_ACTION, các hành động có sẵn là:Hằng số
Giá trị
Ý nghĩa
_PASSKEY_ACTION_NONE0
Không cần hành động.
_PASSKEY_ACTION_INPUT2
Nhắc người dùng nhập passkey được hiển thị trên thiết bị từ xa.
_PASSKEY_ACTION_DISPLAY3
Hiển thị passkey 6 chữ số để thiết bị từ xa nhập.
_PASSKEY_ACTION_NUMERIC_COMPARISON4
Xác nhận rằng passkey khớp với passkey được hiển thị trên thiết bị từ xa.
Để tiết kiệm không gian trong firmware, các hằng số này không được đưa vào mô-đun
bluetooth. Thêm những hằng số cần thiết từ danh sách trên vào chương trình của bạn.
Vai trò Broadcaster (Advertiser)
- gap_advertise(interval_us: int | None, adv_data: bytes | None = None, *, resp_data: bytes | None = None, connectable: bool = True) None¶
Bắt đầu quảng bá ở khoảng thời gian được chỉ định (tính bằng micro giây). Khoảng thời gian này sẽ được làm tròn xuống tới 625us gần nhất. Để dừng quảng bá, đặt interval_us thành
None.adv_data và resp_data có thể là bất kỳ kiểu nào triển khai giao thức bộ đệm (ví dụ:
bytes,bytearray,str). adv_data được đưa vào tất cả các lần phát quảng bá, và resp_data được gửi để trả lời một lần quét chủ động.Lưu ý: nếu adv_data (hoặc resp_data) là
None, thì dữ liệu được truyền trong lần gọi trước đó tớigap_advertisesẽ được tái sử dụng. Điều này cho phép broadcaster tiếp tục quảng bá chỉ vớigap_advertise(interval_us). Để xóa tải trọng quảng bá, hãy truyềnbytesrỗng, tức làb''.
Vai trò Observer (Scanner)
- gap_scan(duration_ms: int | None, interval_us: int = 1280000, window_us: int = 11250, active: bool = False, /) None¶
Chạy thao tác quét kéo dài trong thời gian được chỉ định (tính bằng mili giây).
Để quét vô thời hạn, đặt duration_ms thành
0.Để dừng quét, đặt duration_ms thành
None.Sử dụng interval_us và window_us để tùy chọn cấu hình chu kỳ làm việc. Scanner sẽ chạy trong window_us micro giây mỗi interval_us micro giây trong tổng cộng duration_ms mili giây. Khoảng thời gian và cửa sổ mặc định lần lượt là 1,28 giây và 11,25 mili giây (quét nền).
Đối với mỗi kết quả quét, sự kiện
_IRQ_SCAN_RESULTsẽ được kích hoạt, với dữ liệu sự kiện(addr_type, addr, adv_type, rssi, adv_data).Các giá trị
addr_typecho biết địa chỉ công khai hoặc ngẫu nhiên:Giá trị
Tên
Ý nghĩa
0x00PUBLIC
Địa chỉ thiết bị công khai.
0x01RANDOM
Địa chỉ ngẫu nhiên (tĩnh, RPA hoặc NRPA; loại được mã hóa trong chính địa chỉ).
Các giá trị
adv_typetương ứng với Bluetooth Specification:Giá trị
Tên
Ý nghĩa
0x00ADV_IND
Quảng bá không hướng có thể kết nối và quét.
0x01ADV_DIRECT_IND
Quảng bá có hướng có thể kết nối.
0x02ADV_SCAN_IND
Quảng bá không hướng có thể quét.
0x03ADV_NONCONN_IND
Quảng bá không hướng không thể kết nối.
0x04SCAN_RSP
Phản hồi quét.
activecó thể được đặtTruenếu bạn muốn nhận phản hồi quét trong kết quả.Khi quét dừng lại (do thời gian kết thúc hoặc bị dừng rõ ràng), sự kiện
_IRQ_SCAN_DONEsẽ được kích hoạt.
Vai trò Central
Thiết bị central có thể kết nối với các peripheral mà nó đã phát hiện bằng vai trò observer (xem
gap_scan) hoặc với địa chỉ đã biết.- gap_connect(addr_type: int | None, addr: bytes | None = None, scan_duration_ms: int = 2000, min_conn_interval_us: int | None = None, max_conn_interval_us: int | None = None, /) None¶
Kết nối với một peripheral.
Xem
gap_scanđể biết chi tiết về các loại địa chỉ.Để hủy sớm một lần thử kết nối đang chờ, hãy gọi
gap_connect(None).Khi thành công, sự kiện
_IRQ_PERIPHERAL_CONNECTsẽ được kích hoạt. Nếu hủy lần thử kết nối, sự kiện_IRQ_PERIPHERAL_DISCONNECTsẽ được kích hoạt.Thiết bị sẽ chờ tối đa scan_duration_ms để nhận tải trọng quảng bá từ thiết bị.
Khoảng thời gian kết nối có thể được cấu hình tính bằng micro giây bằng cách sử dụng min_conn_interval_us và/hoặc max_conn_interval_us. Ngược lại, một khoảng thời gian mặc định sẽ được chọn, thường từ 30000 đến 50000 micro giây. Khoảng thời gian ngắn hơn sẽ tăng thông lượng, nhưng tốn nhiều điện năng hơn.
Vai trò Peripheral
Thiết bị peripheral dự kiến gửi các quảng bá có thể kết nối (xem
gap_advertise). Thường sẽ hoạt động như GATT server, sau khi đã đăng ký các dịch vụ và đặc trưng bằnggatts_register_services.Khi central kết nối, sự kiện
_IRQ_CENTRAL_CONNECTsẽ được kích hoạt.Vai trò Central & Peripheral
- gap_disconnect(conn_handle: int, /) bool¶
Ngắt kết nối tay cầm kết nối được chỉ định. Đây có thể là central đã kết nối với thiết bị này (nếu đang hoạt động như peripheral) hoặc peripheral đã được kết nối trước đó bởi thiết bị này (nếu đang hoạt động như central).
Khi thành công, sự kiện
_IRQ_PERIPHERAL_DISCONNECThoặc_IRQ_CENTRAL_DISCONNECTsẽ được kích hoạt.Trả về
Falsenếu tay cầm kết nối không được kết nối, vàTruenếu không.
GATT Server
Một GATT server có một tập hợp các dịch vụ đã đăng ký. Mỗi dịch vụ có thể chứa các đặc trưng, mỗi đặc trưng có một giá trị. Các đặc trưng cũng có thể chứa các bộ mô tả, bản thân chúng có các giá trị.
Các giá trị này được lưu trữ cục bộ, và được truy cập bằng "value handle" được tạo ra trong quá trình đăng ký dịch vụ. Chúng cũng có thể được đọc hoặc ghi bởi một thiết bị client từ xa. Ngoài ra, server có thể "thông báo" một đặc trưng đến client đã kết nối qua tay cầm kết nối.
Thiết bị trong vai trò central hoặc peripheral đều có thể hoạt động như GATT server, tuy nhiên trong hầu hết các trường hợp, thiết bị peripheral thường là server hơn.
Các đặc trưng và bộ mô tả có kích thước tối đa mặc định là 20 byte (ATT MTU mặc định là 23 byte trừ đi 3-byte ATT header; MTU đã đàm phán lớn hơn không tự động nâng giới hạn này). Bất cứ điều gì được ghi vào chúng bởi client sẽ bị cắt ngắn đến độ dài này. Tuy nhiên, bất kỳ lần ghi cục bộ nào đều sẽ tăng kích thước tối đa, vì vậy nếu bạn muốn cho phép các lần ghi lớn hơn từ client đến một đặc trưng nhất định, hãy sử dụng
gatts_writesau khi đăng ký. Ví dụ:gatts_write(char_handle, bytes(100)).- gatts_register_services(services_definition: Sequence[Sequence], /) Sequence[Sequence[int]]¶
Cấu hình server với các dịch vụ được chỉ định, thay thế bất kỳ dịch vụ nào hiện có.
services_definition là một danh sách các dịch vụ, trong đó mỗi dịch vụ là một tuple hai phần tử chứa UUID và một danh sách các đặc trưng.
Mỗi đặc trưng là một tuple hai hoặc ba phần tử chứa UUID, giá trị flags và tùy chọn danh sách bộ mô tả.
Mỗi bộ mô tả là một tuple hai phần tử chứa UUID và giá trị flags.
flags là sự kết hợp bitwise-OR của các cờ được định nghĩa bên dưới. Chúng đặt cả hành vi của đặc trưng (hoặc bộ mô tả) cũng như các yêu cầu bảo mật và quyền riêng tư.
Giá trị trả về là một danh sách (một phần tử cho mỗi dịch vụ) các tuple (mỗi phần tử là value handle). Các handle đặc trưng và bộ mô tả được làm phẳng vào cùng một tuple, theo thứ tự chúng được định nghĩa.
Ví dụ sau đây đăng ký hai dịch vụ (Heart Rate và Nordic UART):
bt = bluetooth.BLE() bt.active(True) # Heart Rate service: one Heart Rate Measurement characteristic. HR_SERVICE = ( bluetooth.UUID(0x180D), ( (bluetooth.UUID(0x2A37), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY), ), ) # Nordic UART service: a TX characteristic the client subscribes # to for notifications, and an RX characteristic it writes to. UART_SERVICE = ( bluetooth.UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E'), ( (bluetooth.UUID('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY), (bluetooth.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_WRITE), ), ) ((hr,), (tx, rx)) = bt.gatts_register_services( (HR_SERVICE, UART_SERVICE), )
Ba value handle (
hr,tx,rx) có thể được sử dụng vớigatts_read,gatts_write,gatts_notifyvàgatts_indicate.Lưu ý: Phải dừng quảng bá trước khi đăng ký dịch vụ.
Các cờ có sẵn cho đặc trưng và bộ mô tả là:
Hằng số
Giá trị
Ý nghĩa
_FLAG_BROADCAST0x0001Đặc trưng có thể được phát quảng bá.
_FLAG_READ0x0002Client có thể đọc giá trị.
_FLAG_WRITE_NO_RESPONSE0x0004Client có thể ghi mà không cần phản hồi.
_FLAG_WRITE0x0008Client có thể ghi với phản hồi được xác nhận.
_FLAG_NOTIFY0x0010Server có thể gửi thông báo (không được xác nhận).
_FLAG_INDICATE0x0020Server có thể gửi chỉ thị (được xác nhận).
_FLAG_AUTHENTICATED_SIGNED_WRITE0x0040Client có thể phát hành ghi có ký xác thực.
_FLAG_AUX_WRITE0x0100Thuộc tính mở rộng: cho phép ghi xếp hàng/đáng tin cậy.
_FLAG_READ_ENCRYPTED0x0200Đọc yêu cầu liên kết được mã hóa.
_FLAG_READ_AUTHENTICATED0x0400Đọc yêu cầu liên kết đã xác thực (được bảo vệ MITM).
_FLAG_READ_AUTHORIZED0x0800Đọc yêu cầu ủy quyền cấp ứng dụng.
_FLAG_WRITE_ENCRYPTED0x1000Ghi yêu cầu liên kết được mã hóa.
_FLAG_WRITE_AUTHENTICATED0x2000Ghi yêu cầu liên kết đã xác thực (được bảo vệ MITM).
_FLAG_WRITE_AUTHORIZED0x4000Ghi yêu cầu ủy quyền cấp ứng dụng.
Giống như các hằng số sự kiện ở trên, các cờ này không được cung cấp bởi mô-đun
bluetooth; hãy sao chép những cờ bạn cần vào chương trình của bạn.
- gatts_read(value_handle: int, /) bytes¶
Đọc giá trị cục bộ cho handle này (đã được ghi bởi
gatts_writehoặc bởi client từ xa).
- gatts_write(value_handle: int, data: bytes, send_update: bool = False, /) None¶
Ghi giá trị cục bộ cho handle này, có thể được đọc bởi client.
Nếu send_update là
True, thì bất kỳ client nào đã đăng ký sẽ được thông báo (hoặc chỉ thị, tùy thuộc vào những gì họ đã đăng ký và các thao tác mà đặc trưng hỗ trợ) về lần ghi này.
- gatts_notify(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
Gửi yêu cầu thông báo đến client đã kết nối.
Nếu data là
None(mặc định), thì giá trị cục bộ hiện tại (như đã đặt vớigatts_write) sẽ được gửi.Ngược lại, nếu data không phải là
None, thì giá trị đó được gửi đến client như một phần của thông báo. Giá trị cục bộ sẽ không bị thay đổi.Lưu ý: Thông báo sẽ được gửi bất kể trạng thái đăng ký của client đối với đặc trưng này.
- gatts_indicate(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
Gửi yêu cầu chỉ thị đến client đã kết nối.
Nếu data là
None(mặc định), thì giá trị cục bộ hiện tại (như đã đặt vớigatts_write) sẽ được gửi.Ngược lại, nếu data không phải là
None, thì giá trị đó được gửi đến client như một phần của chỉ thị. Giá trị cục bộ sẽ không bị thay đổi.Khi xác nhận (hoặc thất bại, ví dụ: hết thời gian chờ), sự kiện
_IRQ_GATTS_INDICATE_DONEsẽ được kích hoạt.Lưu ý: Chỉ thị sẽ được gửi bất kể trạng thái đăng ký của client đối với đặc trưng này.
- gatts_set_buffer(value_handle: int, len: int, append: bool = False, /) None¶
Đặt kích thước bộ đệm nội bộ cho một giá trị tính bằng byte. Điều này sẽ giới hạn kích thước ghi lớn nhất có thể được nhận. Mặc định là 20 byte (ATT MTU mặc định là 23 trừ đi 3-byte ATT header).
Đặt append thành
Truesẽ làm cho tất cả các lần ghi từ xa thêm vào, thay vì thay thế, giá trị hiện tại. Tối đa len byte có thể được đệm theo cách này. Khi bạn sử dụnggatts_read, giá trị sẽ bị xóa sau khi đọc. Tính năng này hữu ích khi triển khai thứ gì đó như Nordic UART Service.
GATT Client
Một GATT client có thể khám phá và đọc/ghi các đặc trưng trên GATT server từ xa.
Thiết bị vai trò central thường đóng vai trò GATT client hơn, tuy nhiên peripheral cũng có thể đóng vai trò client để khám phá thông tin về central đã kết nối với nó (ví dụ: đọc tên thiết bị từ dịch vụ thông tin thiết bị).
- gattc_discover_services(conn_handle: int, uuid: UUID | None = None, /) None¶
Truy vấn server đã kết nối về các dịch vụ của nó.
Tùy chọn chỉ định uuid dịch vụ để chỉ truy vấn dịch vụ đó.
Đối với mỗi dịch vụ được phát hiện, sự kiện
_IRQ_GATTC_SERVICE_RESULTsẽ được kích hoạt, tiếp theo là_IRQ_GATTC_SERVICE_DONEkhi hoàn thành.
- gattc_discover_characteristics(conn_handle: int, start_handle: int, end_handle: int, uuid: UUID | None = None, /) None¶
Truy vấn server đã kết nối về các đặc trưng trong phạm vi được chỉ định.
Tùy chọn chỉ định uuid đặc trưng để chỉ truy vấn đặc trưng đó.
Truyền
start_handle=1vàend_handle=0xffffbao phủ toàn bộ phạm vi attribute-handle GATT, vì vậy sự kết hợp này thực sự tìm kiếm mọi dịch vụ trên thiết bị từ xa.Đối với mỗi đặc trưng được phát hiện, sự kiện
_IRQ_GATTC_CHARACTERISTIC_RESULTsẽ được kích hoạt, tiếp theo là_IRQ_GATTC_CHARACTERISTIC_DONEkhi hoàn thành.
- gattc_discover_descriptors(conn_handle: int, start_handle: int, end_handle: int, /) None¶
Truy vấn server đã kết nối về các bộ mô tả trong phạm vi được chỉ định.
Đối với mỗi bộ mô tả được phát hiện, sự kiện
_IRQ_GATTC_DESCRIPTOR_RESULTsẽ được kích hoạt, tiếp theo là_IRQ_GATTC_DESCRIPTOR_DONEkhi hoàn thành.
- gattc_read(conn_handle: int, value_handle: int, /) None¶
Phát hành lệnh đọc từ xa đến server đã kết nối cho handle đặc trưng hoặc bộ mô tả được chỉ định.
Khi có giá trị, sự kiện
_IRQ_GATTC_READ_RESULTsẽ được kích hoạt, tiếp theo là_IRQ_GATTC_READ_DONEkhi hoàn thành.
- gattc_write(conn_handle: int, value_handle: int, data: bytes, mode: int = 0, /) None¶
Phát hành lệnh ghi từ xa đến server đã kết nối cho handle đặc trưng hoặc bộ mô tả được chỉ định.
Đối số mode chỉ định hành vi ghi, với các giá trị hiện được hỗ trợ là:
mode=0(mặc định) là ghi không có phản hồi: lệnh ghi sẽ được gửi đến server từ xa nhưng không có xác nhận nào được trả về, và không có sự kiện nào được kích hoạt.mode=1là ghi có phản hồi: server từ xa được yêu cầu gửi phản hồi/xác nhận rằng nó đã nhận được dữ liệu.
Nếu nhận được phản hồi từ server từ xa, sự kiện
_IRQ_GATTC_WRITE_DONEsẽ được kích hoạt.
- gattc_exchange_mtu(conn_handle: int, /) None¶
Khởi tạo trao đổi MTU với server đã kết nối, sử dụng MTU ưu tiên được đặt bằng
BLE.config(mtu=value).Sự kiện
_IRQ_MTU_EXCHANGEDsẽ được kích hoạt khi trao đổi MTU hoàn thành.Trao đổi MTU thường được khởi tạo bởi central; NimBLE hỗ trợ cả hai vai trò.
Kênh hướng kết nối L2CAP
Tính năng này cho phép trao đổi dữ liệu dạng socket giữa hai thiết bị BLE. Khi các thiết bị đã kết nối qua GAP, một trong hai thiết bị có thể lắng nghe thiết bị kia kết nối trên PSM (Protocol/Service Multiplexer) dạng số.
Chỉ có thể có một kênh L2CAP hoạt động tại một thời điểm (tức là không thể kết nối trong khi đang lắng nghe).
Các kênh L2CAP đang hoạt động được xác định bởi tay cầm kết nối mà chúng được thiết lập và CID (channel ID).
Các kênh hướng kết nối có kiểm soát luồng dựa trên tín dụng tích hợp. Không giống như ATT, nơi các thiết bị đàm phán MTU chia sẻ, cả thiết bị lắng nghe và kết nối đều đặt MTU độc lập riêng, giới hạn lượng dữ liệu tối đa đang chờ xử lý mà thiết bị từ xa có thể gửi trước khi được tiêu thụ hoàn toàn trong
l2cap_recvinto.- l2cap_listen(psm: int, mtu: int, /) None¶
Bắt đầu lắng nghe các yêu cầu kênh L2CAP đến trên psm được chỉ định với MTU cục bộ được đặt thành mtu.
Khi thiết bị từ xa khởi tạo kết nối, sự kiện
_IRQ_L2CAP_ACCEPTsẽ được kích hoạt, cho phép server lắng nghe có cơ hội từ chối kết nối đến (bằng cách trả về số nguyên khác không).Sau khi kết nối được chấp nhận, sự kiện
_IRQ_L2CAP_CONNECTsẽ được kích hoạt, cho phép server lấy CID và MTU cục bộ và từ xa.Lưu ý: Hiện tại không thể dừng lắng nghe.
- l2cap_connect(conn_handle: int, psm: int, mtu: int, /) None¶
Kết nối đến peer đang lắng nghe trên psm được chỉ định với MTU cục bộ được đặt thành mtu.
Khi kết nối thành công, sự kiện
_IRQ_L2CAP_CONNECTsẽ được kích hoạt, cho phép client lấy CID và MTU cục bộ và từ xa (peer).Kết nối không thành công sẽ kích hoạt sự kiện
_IRQ_L2CAP_DISCONNECTvới trạng thái khác không.
- l2cap_disconnect(conn_handle: int, cid: int, /) None¶
Ngắt kết nối kênh L2CAP đang hoạt động với conn_handle và cid được chỉ định.
- l2cap_send(conn_handle: int, cid: int, buf: bytes, /) bool¶
Gửi buf được chỉ định (phải hỗ trợ giao thức bộ đệm) trên kênh L2CAP được xác định bởi conn_handle và cid.
Bộ đệm phải thỏa mãn cả hai giới hạn: không được vượt quá MTU từ xa (peer) và không được vượt quá hai lần MTU cục bộ.
Điều này sẽ trả về
Falsenếu kênh hiện đang "bị trì hoãn", có nghĩa làl2cap_sendkhông được gọi lại cho đến khi nhận được sự kiện_IRQ_L2CAP_SEND_READY(điều này sẽ xảy ra khi thiết bị từ xa cấp thêm tín dụng, thường là sau khi nhận và xử lý dữ liệu).
- l2cap_recvinto(conn_handle: int, cid: int, buf: Any | None, /) int¶
Nhận dữ liệu từ conn_handle và cid được chỉ định vào buf được cung cấp (phải hỗ trợ giao thức bộ đệm, ví dụ: bytearray hoặc memoryview).
Trả về số byte đọc từ kênh.
Nếu buf là
None, thì trả về số byte có sẵn.Lưu ý: Sau khi nhận sự kiện
_IRQ_L2CAP_RECV, ứng dụng nên tiếp tục gọil2cap_recvintocho đến khi không còn byte nào trong bộ đệm nhận (thường là tối đa kích thước MTU của thiết bị từ xa (peer)).Cho đến khi bộ đệm nhận trống, thiết bị từ xa sẽ không được cấp thêm tín dụng kênh và sẽ không thể gửi thêm dữ liệu.
Ghép đôi và liên kết
Ghép đôi cho phép kết nối được mã hóa và xác thực thông qua trao đổi bí mật (với bảo vệ MITM tùy chọn thông qua xác thực passkey).
Liên kết là quá trình lưu trữ các bí mật đó vào bộ nhớ không bay hơi. Khi đã liên kết, thiết bị có thể phân giải địa chỉ riêng tư có thể phân giải (RPA) từ thiết bị khác dựa trên khóa phân giải danh tính đã lưu trữ (IRK). Để hỗ trợ liên kết, ứng dụng phải triển khai các sự kiện
_IRQ_GET_SECRETvà_IRQ_SET_SECRET.- gap_pair(conn_handle: int, /) None¶
Khởi tạo ghép đôi với thiết bị từ xa.
Trước khi gọi hàm này, hãy đảm bảo rằng các tùy chọn cấu hình
io,mitm,le_securevàbondđã được đặt (quaconfig).Khi ghép đôi thành công, sự kiện
_IRQ_ENCRYPTION_UPDATEsẽ được kích hoạt.
- gap_passkey(conn_handle: int, action: int, passkey: int, /) None¶
Phản hồi sự kiện
_IRQ_PASSKEY_ACTIONcho conn_handle và action được chỉ định. Ý nghĩa của passkey phụ thuộc vào action (lần lượt phụ thuộc vào khả năng I/O đã cấu hình):Hành động
Phản hồi passkey yêu cầu
_PASSKEY_ACTION_INPUTPasskey mà người dùng đọc từ thiết bị từ xa.
_PASSKEY_ACTION_DISPLAYPasskey ngẫu nhiên 6 chữ số được tạo cục bộ hiển thị cho người dùng.
_PASSKEY_ACTION_NUMERIC_COMPARISON1để chấp nhận passkey được hiển thị trong sự kiện_IRQ_PASSKEY_ACTION, hoặc0để hủy ghép đôi.
class UUID¶
- class bluetooth.UUID(value: int | bytes | str, /)¶
Tạo một thực thể UUID với
valueđược chỉ định. Bluetooth sử dụng ba độ rộng UUID;UUIDchấp nhận bất kỳ trong số chúng:Độ rộng UUID
Các kiểu
valueđược chấp nhậnVí dụ
16-bit
inthoặc bộ đệm 2 byte (little-endian)UUID(0x2908)hoặcUUID(b'\x08\x29')32-bit
Bộ đệm 4 byte (little-endian)
UUID(b'\x08\x29\x00\x00')128-bit
Bộ đệm 16 byte hoặc chuỗi có dấu gạch ngang
UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')UUID 16-bit và 32-bit thường là các định danh được SIG phân bổ (xem Bluetooth assigned numbers); UUID 128-bit thường được định nghĩa bởi nhà cung cấp.