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
Jim Mussared 2021-11-10 17:39:35 +11:00
rodzic 9169ca6543
commit dd9b783568
2 zmienionych plików z 173 dodań i 0 usunięć

Wyświetl plik

@ -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()

Wyświetl plik

@ -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