Skip to content

Commit 87bc782

Browse files
committed
aioble/multitests: Add re-registration multitest.
Test that singleton service/characteristic instances can be re-registered across multiple stop/start cycles without data loss. Verifies initial= values persist and writable characteristics accept cycle-specific values after each re-registration.
1 parent 75ab7fd commit 87bc782

1 file changed

Lines changed: 118 additions & 0 deletions

File tree

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Test that singleton service/characteristic instances can be re-registered
2+
# across multiple stop/start cycles without data loss.
3+
4+
import sys
5+
6+
# ruff: noqa: E402
7+
sys.path.append("")
8+
9+
from micropython import const
10+
import machine
11+
import time
12+
13+
import asyncio
14+
import aioble
15+
import bluetooth
16+
17+
TIMEOUT_MS = 5000
18+
19+
SERVICE_UUID = bluetooth.UUID("A5A5A5A5-FFFF-9999-1111-5A5A5A5A5A5A")
20+
CHAR_INITIAL_UUID = bluetooth.UUID("00000000-1111-2222-3333-444444444444")
21+
CHAR_WRITE_UUID = bluetooth.UUID("00000000-1111-2222-3333-555555555555")
22+
23+
24+
# Acting in peripheral role.
25+
async def instance0_task():
26+
# Create service and characteristics ONCE (singleton pattern).
27+
service = aioble.Service(SERVICE_UUID)
28+
char_initial = aioble.Characteristic(
29+
service, CHAR_INITIAL_UUID, read=True, initial=b"hello"
30+
)
31+
char_write = aioble.Characteristic(
32+
service, CHAR_WRITE_UUID, read=True, write=True
33+
)
34+
35+
multitest.globals(BDADDR=aioble.config("mac"))
36+
multitest.next()
37+
38+
for i in range(3):
39+
# Re-register the same service instances.
40+
aioble.register_services(service)
41+
42+
# Write a cycle-specific value to the writable characteristic.
43+
char_write.write("periph{}".format(i))
44+
45+
multitest.broadcast("connect-{}".format(i))
46+
47+
# Wait for central to connect.
48+
print("advertise", i)
49+
connection = await aioble.advertise(
50+
20_000, adv_data=b"\x02\x01\x06\x04\xffMPY", timeout_ms=TIMEOUT_MS
51+
)
52+
print("connected", i)
53+
54+
# Wait for the central to write.
55+
await char_write.written(timeout_ms=TIMEOUT_MS)
56+
print("written", i)
57+
58+
# Wait for the central to disconnect.
59+
await connection.disconnected(timeout_ms=TIMEOUT_MS)
60+
print("disconnected", i)
61+
62+
# Shutdown aioble.
63+
print("shutdown", i)
64+
aioble.stop()
65+
66+
await asyncio.sleep_ms(100)
67+
68+
69+
def instance0():
70+
try:
71+
asyncio.run(instance0_task())
72+
finally:
73+
aioble.stop()
74+
75+
76+
# Acting in central role.
77+
async def instance1_task():
78+
multitest.next()
79+
80+
for i in range(3):
81+
multitest.wait("connect-{}".format(i))
82+
83+
# Connect to peripheral.
84+
print("connect", i)
85+
device = aioble.Device(*BDADDR)
86+
connection = await device.connect(timeout_ms=TIMEOUT_MS)
87+
88+
# Discover characteristics.
89+
service = await connection.service(SERVICE_UUID)
90+
char_initial = await service.characteristic(CHAR_INITIAL_UUID)
91+
char_write = await service.characteristic(CHAR_WRITE_UUID)
92+
93+
# Read the initial= characteristic — must be the same every cycle.
94+
print("read initial", await char_initial.read(timeout_ms=TIMEOUT_MS))
95+
96+
# Read the writable characteristic — should have cycle-specific value.
97+
print("read written", await char_write.read(timeout_ms=TIMEOUT_MS))
98+
99+
# Write to the writable characteristic.
100+
print("write", i)
101+
await char_write.write("central{}".format(i), response=True, timeout_ms=TIMEOUT_MS)
102+
103+
# Disconnect from peripheral.
104+
print("disconnect", i)
105+
await connection.disconnect(timeout_ms=TIMEOUT_MS)
106+
print("disconnected", i)
107+
108+
# Shutdown aioble.
109+
aioble.stop()
110+
111+
await asyncio.sleep_ms(100)
112+
113+
114+
def instance1():
115+
try:
116+
asyncio.run(instance1_task())
117+
finally:
118+
aioble.stop()

0 commit comments

Comments
 (0)