kopia lustrzana https://github.com/micropython/micropython-lib
aioble/multitests: Add test for subscription and notification.
This replicates the failure described in #453 (which is fixed by #459. Also adds a test for subscription. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>pull/459/head
rodzic
9169ca6543
commit
dd9b783568
|
@ -0,0 +1,148 @@
|
|||
# Test notification-specific behavior.
|
||||
|
||||
import sys
|
||||
|
||||
sys.path.append("")
|
||||
|
||||
from micropython import const
|
||||
import time, machine
|
||||
|
||||
import uasyncio as asyncio
|
||||
import aioble
|
||||
import bluetooth
|
||||
|
||||
TIMEOUT_MS = 5000
|
||||
|
||||
SERVICE_UUID = bluetooth.UUID("A5A5A5A5-FFFF-9999-1111-5A5A5A5A5A5A")
|
||||
CHAR_UUID = bluetooth.UUID("00000000-1111-2222-3333-444444444444")
|
||||
|
||||
|
||||
# Acting in peripheral role.
|
||||
async def instance0_task():
|
||||
service = aioble.Service(SERVICE_UUID)
|
||||
characteristic = aioble.Characteristic(service, CHAR_UUID, read=True, notify=True)
|
||||
aioble.register_services(service)
|
||||
|
||||
multitest.globals(BDADDR=aioble.config("mac"))
|
||||
multitest.next()
|
||||
|
||||
# Wait for central to connect to us.
|
||||
print("advertise")
|
||||
connection = await aioble.advertise(
|
||||
20_000, adv_data=b"\x02\x01\x06\x04\xffMPY", timeout_ms=TIMEOUT_MS
|
||||
)
|
||||
print("connected")
|
||||
|
||||
# Send a subscribed-write (but client isn't subscribed, won't send anything).
|
||||
multitest.wait("discovery")
|
||||
await asyncio.sleep_ms(100)
|
||||
characteristic.write("before-subscribe", send_update=True)
|
||||
|
||||
# Send a subscribed-write (now client is subscribed, client should get notified).
|
||||
multitest.wait("subscribed")
|
||||
await asyncio.sleep_ms(100)
|
||||
characteristic.write("after-subscribe", send_update=True)
|
||||
|
||||
# Send a subscribed-write (now client is unsubscribed, won't send anything).
|
||||
multitest.wait("unsubscribed")
|
||||
await asyncio.sleep_ms(100)
|
||||
characteristic.write("after-unsubscribe", send_update=True)
|
||||
|
||||
# Send 5 direct notifications.
|
||||
multitest.wait("start-direct")
|
||||
for i in range(5):
|
||||
# Send 1 notification each time, except for 3 quick notifications the third time.
|
||||
# The client should only see the last one.
|
||||
for j in range(3 if i == 2 else 1):
|
||||
if j > 0:
|
||||
await asyncio.sleep_ms(100)
|
||||
msg = "direct-{}-{}".format(i, j)
|
||||
print("notify", msg)
|
||||
characteristic.notify(connection, msg)
|
||||
|
||||
# Tell client to wait for notification.
|
||||
multitest.broadcast("notified")
|
||||
# Wait until client is ready for next notification.
|
||||
multitest.wait("next")
|
||||
|
||||
# Wait for the central to disconnect.
|
||||
await connection.disconnected(timeout_ms=TIMEOUT_MS)
|
||||
print("disconnected")
|
||||
|
||||
|
||||
def instance0():
|
||||
try:
|
||||
asyncio.run(instance0_task())
|
||||
finally:
|
||||
aioble.stop()
|
||||
|
||||
|
||||
# Acting in central role.
|
||||
async def instance1_task():
|
||||
multitest.next()
|
||||
|
||||
# Connect to peripheral and then disconnect.
|
||||
print("connect")
|
||||
device = aioble.Device(*BDADDR)
|
||||
connection = await device.connect(timeout_ms=TIMEOUT_MS)
|
||||
|
||||
# Discover characteristics.
|
||||
service = await connection.service(SERVICE_UUID)
|
||||
print("service", service.uuid)
|
||||
characteristic = await service.characteristic(CHAR_UUID)
|
||||
print("characteristic", characteristic.uuid)
|
||||
|
||||
# Expect to not receive a notification (not subscribed).
|
||||
multitest.broadcast("discovery")
|
||||
try:
|
||||
await characteristic.notified(timeout_ms=500)
|
||||
print("fail")
|
||||
return
|
||||
except asyncio.TimeoutError:
|
||||
print("no notification")
|
||||
|
||||
# Subscribe and expect a notification.
|
||||
await characteristic.subscribe(notify=True)
|
||||
multitest.broadcast("subscribed")
|
||||
value = await characteristic.notified()
|
||||
print("notified", value)
|
||||
|
||||
# Unsubscribe, and expect not to receive a notification.
|
||||
await characteristic.subscribe(notify=False)
|
||||
multitest.broadcast("unsubscribed")
|
||||
try:
|
||||
await characteristic.notified(timeout_ms=500)
|
||||
print("fail")
|
||||
return
|
||||
except asyncio.TimeoutError:
|
||||
print("no notification")
|
||||
|
||||
# Receive 5 notifications.
|
||||
multitest.broadcast("start-direct")
|
||||
for i in range(5):
|
||||
multitest.wait("notified")
|
||||
await asyncio.sleep_ms(200)
|
||||
value = await characteristic.notified()
|
||||
print("notified", value)
|
||||
|
||||
# Expect that after receiving a notification we don't get another one
|
||||
# until we broadcast to the server.
|
||||
try:
|
||||
value = await characteristic.notified(timeout_ms=100)
|
||||
print("unexpected notify", value)
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
|
||||
multitest.broadcast("next")
|
||||
|
||||
# Disconnect from peripheral.
|
||||
print("disconnect")
|
||||
await connection.disconnect(timeout_ms=TIMEOUT_MS)
|
||||
print("disconnected")
|
||||
|
||||
|
||||
def instance1():
|
||||
try:
|
||||
asyncio.run(instance1_task())
|
||||
finally:
|
||||
aioble.stop()
|
|
@ -0,0 +1,25 @@
|
|||
--- instance0 ---
|
||||
advertise
|
||||
connected
|
||||
notify direct-0-0
|
||||
notify direct-1-0
|
||||
notify direct-2-0
|
||||
notify direct-2-1
|
||||
notify direct-2-2
|
||||
notify direct-3-0
|
||||
notify direct-4-0
|
||||
disconnected
|
||||
--- instance1 ---
|
||||
connect
|
||||
service UUID('a5a5a5a5-ffff-9999-1111-5a5a5a5a5a5a')
|
||||
characteristic UUID('00000000-1111-2222-3333-444444444444')
|
||||
no notification
|
||||
notified b'after-subscribe'
|
||||
no notification
|
||||
notified b'direct-0-0'
|
||||
notified b'direct-1-0'
|
||||
notified b'direct-2-2'
|
||||
notified b'direct-3-0'
|
||||
notified b'direct-4-0'
|
||||
disconnect
|
||||
disconnected
|
Ładowanie…
Reference in New Issue