fix(bridge): notify 通道 1f1f/331f 双候选 + services 诊断 op,build=3

This commit is contained in:
agent committed 2026-07-28 15:34:31 +00:00
1 parent 89335e0e82
commit 92a8661088
1 file changed
+27 -3
+27 -3
View File
@@ -27,12 +27,15 @@ import platform
import sys
PROTOCOL_VERSION = 1
SERVER_BUILD = 2 # 2026-07-28: connect 改为扫描解析 BLEDevice 后连接(WinRT 兼容)
SERVER_BUILD = 3 # 2026-07-28: notify 通道 1f1f/331f 双候选 + connect 返回 GATT 表
EPD_SERVICE_UUID = "13187b10-eba9-a3ba-044e-83d3217d9a38"
EPD_CHAR_UUID = "4b646063-6264-f3a7-8941-e65356ea82fe"
RXTX_SERVICE_UUID = "00001f10-0000-1000-8000-00805f9b34fb"
RXTX_CHAR_UUID = "00001f1f-0000-1000-8000-00805f9b34fb"
# 固件分析(firmware-analysis §2/§3):0x221f 服务的 0x331f 特征(handle 0x0B)
# 与 0x1f1f(handle 7)同入命令分发器;部分固件 notify 能力挂在 331f 上
ALT_NOTIFY_UUID = "0000331f-0000-1000-8000-00805f9b34fb"
DEVICE_NAME_PREFIX = "NRF-"
SPOTA_SERVICE_UUID = "0000fef5-0000-1000-8000-00805f9b34fb"
@@ -63,6 +66,7 @@ class BleSession:
def __init__(self):
self.client = None
self.notify_char = None
self._id_buf = bytearray()
self._id_event = asyncio.Event()
@@ -94,8 +98,26 @@ class BleSession:
raise RuntimeError(f"设备解析失败(扫描未见 {address})")
self.client = BleakClient(dev, timeout=timeout)
await self.client.connect()
await self.client.start_notify(RXTX_CHAR_UUID, self._on_notify)
return {"address": address, "name": dev.name}
# notify 通道:1f1f 优先,331f 兜底(固件两 handle 同入分发器,notify 位可能只在 331f)
self.notify_char = None
for uuid in (RXTX_CHAR_UUID, ALT_NOTIFY_UUID):
try:
await self.client.start_notify(uuid, self._on_notify)
self.notify_char = uuid
break
except Exception:
continue
table = self._gatt_table()
return {"address": address, "name": dev.name,
"notify_char": self.notify_char, "gatt": table}
def _gatt_table(self):
table = []
for s in self.client.services:
for c in s.characteristics:
table.append({"service": str(s.uuid), "char": str(c.uuid),
"handle": c.handle, "props": list(c.properties)})
return table
def _on_notify(self, _sender, data: bytearray):
self._id_buf.extend(data)
@@ -228,6 +250,8 @@ class BridgeServer:
return await self.ble.request_device_id(float(req.get("timeout", 8.0)))
if op == "close":
return await self.ble.close() or {}
if op == "services":
return {"gatt": self.ble._gatt_table(), "notify_char": self.ble.notify_char}
raise ValueError(f"unknown op {op!r}")