Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aioble/server.py: Allow BufferedCharacteristic to support all ops. #729

Merged
merged 1 commit into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion micropython/bluetooth/aioble-server/manifest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
metadata(version="0.4.0")
metadata(version="0.4.1")

require("aioble-core")

Expand Down
4 changes: 2 additions & 2 deletions micropython/bluetooth/aioble/aioble/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,8 @@ def _indicate_done(conn_handle, value_handle, status):


class BufferedCharacteristic(Characteristic):
def __init__(self, service, uuid, max_len=20, append=False):
super().__init__(service, uuid, read=True)
def __init__(self, *args, max_len=20, append=False, **kwargs):
super().__init__(*args, **kwargs)
self._max_len = max_len
self._append = append

Expand Down
2 changes: 1 addition & 1 deletion micropython/bluetooth/aioble/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# code. This allows (for development purposes) all the files to live in the
# one directory.

metadata(version="0.4.0")
metadata(version="0.4.1")

# Default installation gives you everything. Install the individual
# components (or a combination of them) if you want a more minimal install.
Expand Down
139 changes: 139 additions & 0 deletions micropython/bluetooth/aioble/multitests/ble_buffered_characteristic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Test characteristic read/write/notify from both GATTS and GATTC.

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")
CHAR1_UUID = bluetooth.UUID("00000000-1111-2222-3333-444444444444")
CHAR2_UUID = bluetooth.UUID("00000000-1111-2222-3333-555555555555")
CHAR3_UUID = bluetooth.UUID("00000000-1111-2222-3333-666666666666")


# Acting in peripheral role.
async def instance0_task():
service = aioble.Service(SERVICE_UUID)
characteristic1 = aioble.BufferedCharacteristic(service, CHAR1_UUID, write=True)
characteristic2 = aioble.BufferedCharacteristic(service, CHAR2_UUID, write=True, max_len=40)
characteristic3 = aioble.BufferedCharacteristic(
service, CHAR3_UUID, write=True, max_len=80, append=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")

# The first will just see the second write (truncated).
await characteristic1.written(timeout_ms=TIMEOUT_MS)
await characteristic1.written(timeout_ms=TIMEOUT_MS)
print("written", characteristic1.read())

# The second will just see the second write (still truncated because MTU
# exchange hasn't happened).
await characteristic2.written(timeout_ms=TIMEOUT_MS)
await characteristic2.written(timeout_ms=TIMEOUT_MS)
print("written", characteristic2.read())

# MTU exchange should happen here.

# The second will now see the full second write.
await characteristic2.written(timeout_ms=TIMEOUT_MS)
await characteristic2.written(timeout_ms=TIMEOUT_MS)
print("written", characteristic2.read())

# The third will see the two full writes concatenated.
await characteristic3.written(timeout_ms=TIMEOUT_MS)
await characteristic3.written(timeout_ms=TIMEOUT_MS)
print("written", characteristic3.read())

# 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)
characteristic1 = await service.characteristic(CHAR1_UUID)
print("characteristic1", characteristic1.uuid)
characteristic2 = await service.characteristic(CHAR2_UUID)
print("characteristic2", characteristic2.uuid)
characteristic3 = await service.characteristic(CHAR3_UUID)
print("characteristic3", characteristic3.uuid)

# Write to each characteristic twice, with a long enough value to trigger
# truncation.
print("write1")
await characteristic1.write(
"central1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaa", response=True, timeout_ms=TIMEOUT_MS
)
await characteristic1.write(
"central1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbb", response=True, timeout_ms=TIMEOUT_MS
)
print("write2a")
await characteristic2.write(
"central2a-aaaaaaaaaaaaaaaaaaaaaaaaaaaa", response=True, timeout_ms=TIMEOUT_MS
)
await characteristic2.write(
"central2a-bbbbbbbbbbbbbbbbbbbbbbbbbbbb", response=True, timeout_ms=TIMEOUT_MS
)
print("exchange mtu")
await connection.exchange_mtu(100)
print("write2b")
await characteristic2.write(
"central2b-aaaaaaaaaaaaaaaaaaaaaaaaaaaa", response=True, timeout_ms=TIMEOUT_MS
)
await characteristic2.write(
"central2b-bbbbbbbbbbbbbbbbbbbbbbbbbbbb", response=True, timeout_ms=TIMEOUT_MS
)
print("write3")
await characteristic3.write(
"central3-aaaaaaaaaaaaaaaaaaaaaaaaaaaaa", response=True, timeout_ms=TIMEOUT_MS
)
await characteristic3.write(
"central3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbb", response=True, timeout_ms=TIMEOUT_MS
)

# Disconnect from peripheral.
print("disconnect")
await connection.disconnect(timeout_ms=TIMEOUT_MS)
print("disconnected")


def instance1():
try:
asyncio.run(instance1_task())
finally:
aioble.stop()
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--- instance0 ---
advertise
connected
written b'central1-bbbbbbbbbbb'
written b'central2a-bbbbbbbbbb'
written b'central2b-bbbbbbbbbbbbbbbbbbbbbbbbbbbb'
written b'central3-aaaaaaaaaaaaaaaaaaaaaaaaaaaaacentral3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
disconnected
--- instance1 ---
connect
service UUID('a5a5a5a5-ffff-9999-1111-5a5a5a5a5a5a')
characteristic1 UUID('00000000-1111-2222-3333-444444444444')
characteristic2 UUID('00000000-1111-2222-3333-555555555555')
characteristic3 UUID('00000000-1111-2222-3333-666666666666')
write1
write2a
exchange mtu
write2b
write3
disconnect
disconnected
Loading