当前位置:   article > 正文

MicroPython BLE低功耗蓝牙模块帮助中文文档_micropython中文文档

micropython中文文档

#蓝牙模块 bluetooth——底层蓝牙

说明

这篇文章是micropython帮助文档有关蓝牙部分的翻译(水平有限,难免有误,欢迎不吝指教)。对于刚开始做BLE开发来说,单看这个文档可能还是会有点云里雾里的感觉,要使用micropython进行BLE的开发还需要对蓝牙相关的协议和规范有一些基本的了解,特别是GAP、GATT等。回头会专门写文章把这部分说清楚。欢迎关注
原文链接:https://docs.micropython.org/en/latest/library/bluetooth.html

下面是正文

该模块给板载蓝牙模块提供了一个接口。目前该接口支持低功耗蓝牙的中心(Central)、外设(Peripheral)、广播(Broadcaster)和观察者(Observer)角色,包括通用属性配置文件(GATT)服务器和客户端以及逻辑链路控制与适配协议(L2CAP)通道。一个设备可以同时扮演多个角色,支持设备的配对和绑定。
这部分的API旨在匹配底层蓝牙协议和特定模块提供更高级别的抽象。

BLE 类

配置

BLE.active([active, ]/)

该方法可以设置蓝牙无线电的活动状态,并返回当前状态。在使用BLE类的其他方法之前,必须先激活无线电。

BLE.config('param',/)
BLE.config(*,param=value,...)

获取或设置蓝牙接口的配置值。获取参数值时,参数名要用字符串并且一次只能查询一个参数。设置参数的时候使用关键字语法“param=value”的形式,一次可以设置多个参数值。
当前支持的参数有:

  • mac:当前使用的地址,依赖于当前的地址模式。返回值一个元组tuple(addr_type, addr)
    有关地址类型的信息可以参考gatts_write方法。
    有可能只能在激活状态下调用
  • addr_mode:设置地址模式。允许的值有:
    • 0x00 - PUBLIC - 使用控制器的公共地址
    • 0x01 - RANDOM - 使用生成的静态地址
    • 0x02 - RPA - 使用可解析的私有地址
    • 0x03 - NRPA - 使用不可解析的私有地址

      默认情况下使用可用的PUBLIC地址模式,否则使用“随机”地址模式。
  • gap_name获取或设置服务0x1800(特征0x2a00)使用的GAP设备名,可以随时设置和更改。
  • rxbuf:获取或设置传入事件的缓存区大小的字节数。这个缓冲区是BLE驱动的全局缓冲区,可以处理所有传入事件的数据,包括所有特征值。增加缓冲区的大小可以更好的处理突发的传入数据(比如扫描结果),并能接收更大的特征值。
  • mtu:获取或设置ATT MTU交换时使用的MTU。返回的MTU是自身和远程设备MTU 的最小值。ATT MTU 交换不会自动进行(除非远程设备启动),必须使用 gattc_exchange_mtu 手动启动。可以利用 _IRQ_MTU_EXCHANGED 事件发现指定连接的 MTU。
  • bond:设置配对时是否启用绑定。启用后,在配对请求时将设置绑定标志,两个设备都会保存密码。
  • mitm:设置在配对时是否需要MITM保护。
  • io:设置设备的I/O功能。可用的选项有:
_IO__IO_CAPABILITY_DISPLAY_ONLY = const(0)
_IO_CAPABILITY_DISPLAY_YESNO = const(1)
_IO_CAPABILITY_KEYBOARD_ONLY = const(2)
_IO_CAPABILITY_NO_INPUT_OUTPUT = const(3)
_IO_CAPABILITY_KEYBOARD_DISPLAY = const(4)
  • 1
  • 2
  • 3
  • 4
  • 5
  • le_secure:设置在配对时是否需要LE安全,缺省为false(例如允许传统配对“Legacy Pairing”)

事件处理 Event Handling

BLE.irq(handler,/)

注册一个BLE协议栈事件的回调函数。handle回调函数有俩参数:event(参考下方的事件代码)和data(不同的事件有不同的元组)。<br/> **注意:**为了避免不必要的内存分配,addradv_datachar_datanotify_datauuid`都是只读的内存视图实例,指向bluetooth内部环形缓存。只在处理IRQ回调时有效。如果你需要在IRQ回调后保存他们的值(比如把他们存到全局变量的类中),那么你把他们复制一份,可以使用bytes或bluetooth.UUID(),就像这样:

connected_addr = bytes(addr)  # equivalently: adv_data, char_data, or notify_data
matched_uuid = bluetooth.UUID(uuid)
  • 1
  • 2

举个例子,IRQ处理先扫描adv_data,验证它是正确的设备后,拷贝地址数据才能被用于程序的其他地方。在IRQ处理程序内打印数据,需要这样:print(bytes(addr))

事件处理器可以处理的事件:

def bt_irq(event, data):
    if event == _IRQ_CENTRAL_CONNECT:
        # 中心设备连接到外围设备时触发.
        conn_handle, addr_type, addr = data
    elif event == _IRQ_CENTRAL_DISCONNECT:
        # 中心设备断开外设时触发.
        conn_handle, addr_type, addr = data
    elif event == _IRQ_GATTS_WRITE:
        # 客户端写入特征或描述符时触发。
        conn_handle, attr_handle = data
    elif event == _IRQ_GATTS_READ_REQUEST:
        # 客户端已发出读取。注意:只支持STM32
        # 返回一个非零的整数去拒绝读取(参考下面)或返回零(None)接受读取
        conn_handle, attr_handle = data
    elif event == _IRQ_SCAN_RESULT:
        # 返回单个扫描结果时触发
        addr_type, addr, adv_type, rssi, adv_data = data
    elif event == _IRQ_SCAN_DONE:
        # 完成扫描或手动结束扫描时触发
        pass
    elif event == _IRQ_PERIPHERAL_CONNECT:
        # gap_connection()成功
        conn_handle, addr_type, addr = data
    elif event == _IRQ_PERIPHERAL_DISCONNECT:
        # 当连接的外设已经断开时触发
        conn_handle, addr_type, addr = data
    elif event == _IRQ_GATTC_SERVICE_RESULT:
        # 调用gattc_discover_services()发现服务时触发
        conn_handle, start_handle, end_handle, uuid = data
    elif event == _IRQ_GATTC_SERVICE_DONE:
        # 查找服务完成时触发。
        # 注意:成功时status值为0,否则就为其他特定实现的值。
        conn_handle, status = data
    elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT:
        # 调用gattc_discover_services()发现特征characteristic时触发。
        conn_handle, end_handle, value_handle, properties, uuid = data
    elif event == _IRQ_GATTC_CHARACTERISTIC_DONE:
        # 当搜索服务完成时触发。
        # 注意:status值为0表示调用成功,否则就为其他特定实现的值。
        conn_handle, status = data
    elif event == _IRQ_GATTC_DESCRIPTOR_RESULT:
        # 调用gattc_discover_descriptors()发现descriptor时触发。
        conn_handle, dsc_handle, uuid = data
    elif event == _IRQ_GATTC_DESCRIPTOR_DONE:
        # 当服务搜索完成时触发。
        # 注意:调用成功时status为零,否则为其他特定实现的值。
        conn_handle, status = data
    elif event == _IRQ_GATTC_READ_RESULT:
        # gattc_read()调用完成后触发。
        conn_handle, value_handle, char_data = data
    elif event == _IRQ_GATTC_READ_DONE:
        # gattc_read()调用完成后触发。
        # 注意:调用成功时status为零,否则为其他特定实现的值。
        conn_handle, value_handle, status = data
    elif event == _IRQ_GATTC_WRITE_DONE:
        # gattc_write()调用完成后触发。
        # 注意:调用成功时status为零,否则为其他特定实现的值。
        conn_handle, value_handle, status = data
    elif event == _IRQ_GATTC_NOTIFY:
        # 服务端发送完成通知请求后触发。
        conn_handle, value_handle, notify_data = data
    elif event == _IRQ_GATTC_INDICATE:
        # 服务端发送指示请求后触发。
        conn_handle, value_handle, notify_data = data
    elif event == _IRQ_GATTS_INDICATE_DONE:
        # 客户端确认指示后触发。
        # 注意:确认成功后status为零,否则为其他特定实现的值。
        conn_handle, value_handle, status = data
    elif event == _IRQ_MTU_EXCHANGED:
        # ATT MTU 交换完成(由我方或远程设备发起)
        conn_handle, mtu = data
    elif event == _IRQ_L2CAP_ACCEPT:
        # 一个新通道被接受时触发。
        # 返回非零整数拒绝连接,返回0或者None接受连接。
        conn_handle, cid, psm, our_mtu, peer_mtu = data
    elif event == _IRQ_L2CAP_CONNECT:
        # 连接一个新通道时触发(作为连接或接受的结果)
        conn_handle, cid, psm, our_mtu, peer_mtu = data
    elif event == _IRQ_L2CAP_DISCONNECT:
        # 断开存在的通道(status为0)或尝试连接失败(status为非零)触发。
        conn_handle, cid, psm, status = data
    elif event == _IRQ_L2CAP_RECV:
        # 通道中有新数据时触发。使用l2cap_recvinto读取。
        conn_handle, cid = data
    elif event == _IRQ_L2CAP_SEND_READY:
        # 先前l2cap_send返回False,现在已完成并且通道已经为下次发送做好准备。
        # 如果status非零,则传输缓冲区溢出,应用应该重新发送数据。
        conn_handle, cid, status = data
    elif event == _IRQ_CONNECTION_UPDATE:
        # 远程设备已经更新连接参数。
        conn_handle, conn_interval, conn_latency, supervision_timeout, status = data
    elif event == _IRQ_ENCRYPTION_UPDATE:
        # 加密状态已经改变(可能是配对或绑定的结果)
        conn_handle, encrypted, authenticated, bonded, key_size = data
    elif event == _IRQ_GET_SECRET:
        # 返回存储的密码
        # 如果key为空,返回sec_type和index的值。
        # 否则,返回sec_type和密钥的相应值。
        sec_type, index, key = data
        return value
    elif event == _IRQ_SET_SECRET:
        # 存储sec_type和key的秘钥
        sec_type, key, value = data
        return True
    elif event == _IRQ_PASSKEY_ACTION:
        # 在配对时响应秘钥请求。
        # 详情参见 gap_passkey()。
        # 动作将成为一个兼容配置为io的配置。
        # 如果动作为“numeric comperison”则秘钥将为非零值。
        conn_handle, action, passkey = data
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110

事件代码常量定义:

from micropython import const
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)
_IRQ_GATTS_READ_REQUEST = const(4)
_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
_IRQ_PERIPHERAL_CONNECT = const(7)
_IRQ_PERIPHERAL_DISCONNECT = const(8)
_IRQ_GATTC_SERVICE_RESULT = const(9)
_IRQ_GATTC_SERVICE_DONE = const(10)
_IRQ_GATTC_CHARACTERISTIC_RESULT = const(11)
_IRQ_GATTC_CHARACTERISTIC_DONE = const(12)
_IRQ_GATTC_DESCRIPTOR_RESULT = const(13)
_IRQ_GATTC_DESCRIPTOR_DONE = const(14)
_IRQ_GATTC_READ_RESULT = const(15)
_IRQ_GATTC_READ_DONE = const(16)
_IRQ_GATTC_WRITE_DONE = const(17)
_IRQ_GATTC_NOTIFY = const(18)
_IRQ_GATTC_INDICATE = const(19)
_IRQ_GATTS_INDICATE_DONE = const(20)
_IRQ_MTU_EXCHANGED = const(21)
_IRQ_L2CAP_ACCEPT = const(22)
_IRQ_L2CAP_CONNECT = const(23)
_IRQ_L2CAP_DISCONNECT = const(24)
_IRQ_L2CAP_RECV = const(25)
_IRQ_L2CAP_SEND_READY = const(26)
_IRQ_CONNECTION_UPDATE = const(27)
_IRQ_ENCRYPTION_UPDATE = const(28)
_IRQ_GET_SECRET = const(29)
_IRQ_SET_SECRET = const(30)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

对于_IRQ_GATTS_READ_REQUEST事件,返回的代码可以为:

_GATTS_NO_ERROR = const(0x00)
_GATTS_ERROR_READ_NOT_PERMITTED = const(0x02)
_GATTS_ERROR_WRITE_NOT_PERMITTED = const(0x03)
_GATTS_ERROR_INSUFFICIENT_AUTHENTICATION = const(0x05)
_GATTS_ERROR_INSUFFICIENT_AUTHORIZATION = const(0x08)
_GATTS_ERROR_INSUFFICIENT_ENCRYPTION = const(0x0f)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

对于_IRQ_PASSKEY_ACTION事件,可用的活动(action)有:

_PASSKEY_ACTION_NONE = const(0)
_PASSKEY_ACTION_INPUT = const(2)
_PASSKEY_ACTION_DISPLAY = const(3)
_PASSKEY_ACTION_NUMERIC_COMPARISON = const(4)
  • 1
  • 2
  • 3
  • 4

为了节省固件空间,bluetooth模块中并没有包含这些常量。

广播Broadcaster(广告Advertiser)者角色

BLE.gap_advertise(interval_us, adv_data=None, *, resp_data=None, connectable=True)

以指定的间隔时间(微秒为单位)进行广播。这个间隔时间会以625微秒为倍数进行舍入,大约在20ms – 10.24s之间。把interval设置为None停止广播。

adv_dataresp_data可以是实现了缓存协议的任何类型(如:bytesbytearraystr)。adv_data 包含在所有广播中,而 resp_data 则在回复主动扫描时发送。

注意: 如果adv_data(或resp_data)为None,则会重新使用上次调用 gap_advertise 时传递的数据。这样,广播者只需调用 gap_advertise(interval_us) ,就能继续进行广播。要清除广播的载荷,可以传入一个空字节,即 b’'。

观察Abserver(扫描Scanner)者角色

BLE.gap_scan(duration_ms, interval_us=1280000, window_us=11250, active=False, /)

按照指定的持续时间(微秒)进行扫描操作。

duration_ms0时,将一直扫描。

要停止扫描可以把 duration_ms 设置为None

interval_uswindow_us为可选参数,用来指定占空比。 扫描者将每隔 interval_us 微秒运行 window_us 微秒,持续运行 duration_ms 微秒。默认的间隔和窗口时间分别为1.28秒和11.25微秒(后台扫描)。

每个扫描到的结果都会触发 _IRQ_SCAN_RESULT 事件,并伴随返回事件数据(addr_type, addr, adv_type, rssi, adv_data)

  • addr_type表示地址类型是公开的还是随机的
    • 0x00 - PUBLIC 公开
    • 0x01 - RANDOM(无论是静态、RPA还是NRPA,类型都编码在自身的地址中)
  • adv_type 遵循蓝牙规范:
    • 0x00 - ADV_IND - 可连接、可扫描的非定向广播
    • 0x01 - ADV_DIRECT_IND - 可以连接的定向广播
    • 0x02 - ADV_SCAN_IND - 可扫描非定向广播
    • 0x03 - ADV_NONCONN_IND - 无连接的非定向广播
    • 0x04 - SCAN_RSP - 扫描响应
  • active 如果希望在返回值中接收扫描响应可以设置为True
    当扫描停止后(无论是扫描完成或是停止)_IRQ_SCAN_DONE 事件被触发。

中心(Central)角色

中心设备可以用观察者角色(参考gap_scan)或已知的地址连接到外围设备。

BLE.gap_connect(addr_type, addr, scan_duration_ms=2000, min_conn_interval_us=None, max_conn_interval_us=None, /)

连接到外围设备。

关于地址的详细信息可参考 gap_scan

如果要取消正在之前正在尝试的连接可以调用gap_connect(None)

如果连接成功,会触发_IRQ_PERIPHERAL_CONNECT 事件。如果是取消一个正在尝试的连接,将触发_IRQ_PERIPHERAL_DISCONNECT 事件。
设备将会等待scan_duration时间后收到一个广播载荷。
可以使用min_conn_interval_usmax_conn_interval_us指定连接的间隔时间(微秒)。否则使用缺省的间隔时间,在30000到50000微秒之间,间隔时间越短吞吐量越大,当然也会越耗电。

外围(Peripheral)角色

外围设备发送可连接的广播(参考gap_advertise),首先使用gatts_register_services服务注册和特征,通常充当一个GATT服务器。

当中心设备连接时触发_IRQ_CENTRAL_CONNECT事件。

中心(Central)和外设(Peripheral)角色

BLE.gap_disconnect(conn_handle, /)

断开指定句柄的连接。可以是中心设备主动断开外围设备的连接或者是外围设备主动断开与中心设备的连接。

断开成功后,将触发 _IRQ_PERIPHERAL_DISCONNECT_IRQ_CENTRAL_DISCONNECT 事件。

如果指定的连接句柄是非连接状态,返回False,其他情况返回True

GATT服务器

GATT 服务器有一组注册服务。每个服务都可能包含特征,而每个特征都有一个值。特征还可以包含描述符,描述符本身也有值。

这些值存储在本地,可通过服务注册时生成的 "值句柄 "进行访问。远程客户端设备也可以读取或写入这些值。此外,服务器还可以通过连接句柄向已连接的客户端 "通知 "某个特性的变化。

中心或外围设备都可以充当 GATT 服务器,但大多数情况下,外围设备充当服务器更常见。

特征和描述符的默认最大长度为 20 字节。客户端写入超过这一长度的内容会被截断。不过,本地写入的超长内容都会增加最大长度,因此如果想让客户端给某个特性写入更长的内容,可在注册后使用 getta_write进行扩容,例如:gatts_write(char_handle, bytes(100))

BLE.gatts_register_services(services_definition, /)

用指定服务定义来配置服务器,并替换现有服务。

services_definition 是一个服务(service)列表,其中每个服务(service)都是一个包含 UUID 和特征(characteristic)列表的双元素元组。

每个特性( characteristic )都是一个包含 UUID、标志值(flags)和描述符列表的二元或三元元组。

每个描述符(descriptor)是一个包含一个 UUID 和一个标志值(flags)的两元素的元组。

标志(flags)是常量定义按位或的组合。这些标志设置了特性(或描述符)的行为以及安全和隐私要求。

返回值是一个元组列表(每个服务一个元素)(每个元素是一个值句柄)。特征和描述符句柄会按照定义的顺序排列在同一个元组中。

下面的示例注册了两个服务(心率和 Nordic UART):

HR_UUID = bluetooth.UUID(0x180D)
HR_CHAR = (bluetooth.UUID(0x2A37), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,)
HR_SERVICE = (HR_UUID, (HR_CHAR,),)
UART_UUID = bluetooth.UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')
UART_TX = (bluetooth.UUID('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,)
UART_RX = (bluetooth.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_WRITE,)
UART_SERVICE = (UART_UUID, (UART_TX, UART_RX,),)
SERVICES = (HR_SERVICE, UART_SERVICE,)
( (hr,), (tx, rx,), ) = bt.gatts_register_services(SERVICES)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这三个值(hr, tx, rx)的句柄可以用于 gatts_readgatts_writegatts_notifygatts_indicate

**注意:**注册服务前必须停止广播。

可用的特性和描述符标志:

from micropython import const
_FLAG_BROADCAST = const(0x0001)
_FLAG_READ = const(0x0002)
_FLAG_WRITE_NO_RESPONSE = const(0x0004)
_FLAG_WRITE = const(0x0008)
_FLAG_NOTIFY = const(0x0010)
_FLAG_INDICATE = const(0x0020)
_FLAG_AUTHENTICATED_SIGNED_WRITE = const(0x0040)

_FLAG_AUX_WRITE = const(0x0100)
_FLAG_READ_ENCRYPTED = const(0x0200)
_FLAG_READ_AUTHENTICATED = const(0x0400)
_FLAG_READ_AUTHORIZED = const(0x0800)
_FLAG_WRITE_ENCRYPTED = const(0x1000)
_FLAG_WRITE_AUTHENTICATED = const(0x2000)
_FLAG_WRITE_AUTHORIZED = const(0x4000)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

要使用上面的这些常量,需要在你的代码中声明。

BLE.gatts_read(value_handle, /)

读取指定句柄的本地值(由 gatts_write 或远程客户端写入)。

BLE.gatts_write(value_handle, data, send_update=False, /)

写入指定句柄的本地值,可以被客户端读取。

如果send_updatetrue,所有已订阅的客户端都将收到通知(或提示,这取决于他们订阅的内容或特性支持的操作)。

BLE.gatts_notify(conn_handle, value_handle, data=None, /)

向连接的客户端发送通知请求。
如果dataNone(缺省),本地的当前值(由gatts_write设置)将被发送。

如果data不为None,则当前值则会作为通知的一部分发送给客户端。本地的不会被修改。

**注意:**无论客户端特性订阅状态如何,通知都会被发送。

BLE.gatts_indicate(conn_handle, value_handle, data=None, /)

向已连接的客户端发送指示请求。

如果dataNone(缺省),本地的当前值(由gatts_write设置)将被发送。

如果data不为None,则当前值则会作为指示的一部分发送给客户端。本地的值不会被修改。

**注意:**无论客户端特性订阅状态如何,指示都会被发送。

BLE.gatts_set_buffer(value_handle, len, append=False, /)

以字节为单位设置值的内部缓冲区大小。这个值将限制最大接收长度。默认值为 20 字节。

如果将append设置为 True,所有远程写入将追加到当前值,而不是替换当前值。这样最多只能缓冲 len 字节。使用 gatts_read 时,读取后的值将被清除。这一功能在实现类似 Nordic UART 服务时非常有用。

GATT客户端

GATT客户端可以发现并读写远程的GATT服务器的特征。

通常中心设备作为GATT客户端角色,但是外围设备也有可能作为客户端发现与其连接的中心设备的信息(比如从设备信息服务中读取设备名称)。

BLE.gattc_discover_services(conn_handle, uuid=None, /)

查询已连接服务器的服务。

uuid为可选参数,可以查询指定uuid的服务。

当发现服务时,会触发_IRQ_GATTC_SERVICE_RESULT事件,接下来在完成时触发_IRQ_GATTC_SERVICE_DONE 事件。

BLE.gattc_discover_characteristics(conn_handle, start_handle, end_handle, uuid=None, /)

查询服务端指定范围的特性。

特性的uuid是可选参数,指定后只查询特定的特性。

可以使用start_handle=1, end_handle=0xffff查询所有服务的特性。

当特征发现后,触发_IRQ_GATTC_CHARACTERISTIC_RESULT 事件,接下来在完成的时候触发_IRQ_GATTC_CHARACTERISTIC_DONE 事件。

BLE.gattc_discover_descriptors(conn_handle, start_handle, end_handle, /)

查询服务端指定范围的描述符。

当发现描述符时,触发_IRQ_GATTC_DESCRIPTOR_RESULT 事件,接下来在完成时触发_IRQ_GATTC_DEScRIPTOR_DONE

BLE.gattc_read(conn_handle, value_handle, /)

针对指定的特征或描述符句柄,向已连接的服务器发出远程读取命令。

当有值返回时,触发_IRQ_GATTC_READ_RESULT,此外,_IRQ_GATTC_READ_DONE 也将被触发。

BLE.gattc_write(conn_handle, value_handle, data, mode=0, /)

针对指定的特征或描述符句柄,想已连接的服务器发出远程写命令。
mode参数指定写的行为,目前支持的值有:

  • mode=0(缺省)不需要回复的写:写的内容发送到服务端,但是不关注返回值,并且没有事件触发。
  • mode=1需要回复的写:要求服务器回应或应答已经收到数据。

到收到服务器的回应时,触发_IRQ_GATTC_WRITE_DONE事件。

BLE.gattc_exchange_mtu(conn_handle, /)

使用 BLE.config(mtu=value) 设置MTU首选项,与已连接的服务器启动 MTU 交换。

MTU 交换完成后,_IRQ_MTU_EXCHANGED 事件将被触发。

注意:MTU 交换通常由中心启动。在中心角色中使用 BlueKitchen 协议栈时,不支持由远程外设启动 MTU 交换。NimBLE 可用于这两种角色。

L2CAP 面向连接的通道

该功能允许两个 BLE 设备之间进行类似套接字的数据交换。设备通过 GAP 连接后,任一设备都可以通过数字 PSM(协议/服务多路复用器)监听对方的连接。

**注意:**目前只有在 STM32 和 Unix(非 ESP32)上使用 NimBLE协议栈时才支持此功能。同一时间只能有一个 L2CAP 通道处于活动状态(即不能边监听边连接)。

活动 L2CAP 信道由其建立的连接句柄和 CID(信道 ID)标识。

面向连接的通道内置基于信用的流量控制。与设备协商共享 MTU 的 ATT 不同,监听设备和连接设备各自设置了一个独立的 MTU,该 MTU 限制了远程设备在 l2cap_recvinto 方法完全耗尽之前可发送的最大未处理数据量。

BLE.l2cap_listen(psm, mtu, /)

开始监听指定 psm 上传入的 L2CAP 信道请求,并将本地 MTU 设为 mtu。

当远程设备发起连接时,触发_IRQ_L2CAP_ACCEPT 事件,服务器将有机会拒绝传入的连接(返回一个非零整数)。

一旦连接被接受,_IRQ_L2CAP_CONNECT 事件就会被触发,从而允许服务器获取通道 ID(CID)以及本地和远程 MTU。

**注意:**当前无法停止监听。

BLE.l2cap_connect(conn_handle, psm, mtu, /)

连接到指定 psm 上的监听对等设备,并将本地 MTU 设置为 mtu。

连接成功后,将触发 _IRQ_L2CAP_CONNECT 事件,允许客户端获取 CID 以及本地和远程(对等程序)的 MTU。

连接不成功时,将引发 _IRQ_L2CAP_DISCONNECT 事件(状态非零)。

BLE.l2cap_disconnect(conn_handle, cid, /)

断开具有指定 conn_handle 和 cid 的活动 L2CAP 信道。

BLE.l2cap_send(conn_handle, cid, buf, /)

在由 conn_handlecid 标识的 L2CAP 信道上发送指定的 buf(必须支持缓冲协议)。

指定的缓冲区不能大于远程(对等)MTU,也不能超过本地 MTU 的两倍。

如果通道当前处于 "停滞 "状态,则返回 False,这意味着在收到 _IRQ_L2CAP_SEND_READY 事件之前(通常是在远程设备接收并处理完数据后,当远程设备授予更多信用点时),不得再次调用 l2cap_send。

BLE.l2cap_recvinto(conn_handle, cid, buf, /)

从指定的 conn_handlecid 处接收数据,并将数据存入提供的 buf(必须支持缓冲协议,如字节数组或内存视图)。

返回从通道读取的字节数。

如果 buf 为空,则返回可用字节数。

注意:接收到 _IRQ_L2CAP_RECV 事件后,应用程序应继续调用 l2cap_recvinto,直到接收缓冲区中没有可用字节为止(通常达到远程(对等)MTU 的大小)。

在接收缓冲区清空之前,远程设备不会获得更多信道点数,也无法发送更多数据。

配对和绑定

配对功能允许通过交换密钥对连接进行加密和验证(可选择通过密钥验证进行 MITM 保护)。

绑定是将这些密钥存储到非易失性存储器中的过程。绑定后,一台设备就能根据存储的身份解析密钥(IRK)解析来自另一台设备的可解析专用地址(RPA)。要支持绑定,应用程序必须实现 _IRQ_GET_SECRET_IRQ_SET_SECRET 事件。

注意:目前只有在 STM32 和 Unix(非 ESP32)上使用 NimBLE 堆栈时才支持该功能。

BLE.gap_pair(conn_handle, /)

启动与远程设备的配对。

调用前,请确保已设置 iomitmle_securebond 配置选项(通过 config方法)。

配对成功后,将引发 _IRQ_ENCRYPTION_UPDATE 事件。

BLE.gap_passkey(conn_handle, action, passkey, /)

使用指定的conn_handleaction参数响应_IRQ_PASSKEY_ACTION 事件。

passkey是一个数值,并且取决于action(由已设置的 I/O 功能决定):

  • action_PASSKEY_ACTION_INPUT 时,应用程序应提示用户输入远程设备上显示的密码。

  • action_PASSKEY_ACTION_DISPLAY 时,应用程序将随机生成一个 6 位数的密码并显示给用户。

  • action_PASSKEY_ACTION_NUMERIC_COMPARISON 时,应用程序应显示在 _IRQ_PASSKEY_ACTION 事件中提供的密码,然后以 0(取消配对)或 1(接受配对)作为响应。

UUID类

构造函数

classbluetooth.UUID(value, /)

使用给定的值创建一个UUID实例。
value的值可以为:

  • 16位的整数,如:0x2908
  • 128位的UUID字符串,如:'6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/573718
推荐阅读
相关标签
  

闽ICP备14008679号