|  | 
|  | 1 | +# Test for shutting down and restarting the BLE stack. | 
|  | 2 | + | 
|  | 3 | +import sys | 
|  | 4 | + | 
|  | 5 | +sys.path.append("") | 
|  | 6 | + | 
|  | 7 | +from micropython import const | 
|  | 8 | +import time, machine | 
|  | 9 | + | 
|  | 10 | +import uasyncio as asyncio | 
|  | 11 | +import aioble | 
|  | 12 | +import bluetooth | 
|  | 13 | + | 
|  | 14 | +TIMEOUT_MS = 5000 | 
|  | 15 | + | 
|  | 16 | +SERVICE_UUID = bluetooth.UUID("A5A5A5A5-FFFF-9999-1111-5A5A5A5A5A5A") | 
|  | 17 | +CHAR_UUID = bluetooth.UUID("00000000-1111-2222-3333-444444444444") | 
|  | 18 | + | 
|  | 19 | +_L2CAP_PSN = const(22) | 
|  | 20 | +_L2CAP_MTU = const(128) | 
|  | 21 | + | 
|  | 22 | + | 
|  | 23 | +# Acting in peripheral role. | 
|  | 24 | +async def instance0_task(): | 
|  | 25 | +    multitest.globals(BDADDR=aioble.config("mac")) | 
|  | 26 | +    multitest.next() | 
|  | 27 | + | 
|  | 28 | +    for i in range(3): | 
|  | 29 | +        service = aioble.Service(SERVICE_UUID) | 
|  | 30 | +        characteristic = aioble.Characteristic(service, CHAR_UUID, read=True) | 
|  | 31 | +        aioble.register_services(service) | 
|  | 32 | + | 
|  | 33 | +        # Write initial characteristic value. | 
|  | 34 | +        characteristic.write("periph{}".format(i)) | 
|  | 35 | + | 
|  | 36 | +        multitest.broadcast("connect-{}".format(i)) | 
|  | 37 | + | 
|  | 38 | +        # Wait for central to connect to us. | 
|  | 39 | +        print("advertise") | 
|  | 40 | +        connection = await aioble.advertise( | 
|  | 41 | +            20_000, adv_data=b"\x02\x01\x06\x04\xffMPY", timeout_ms=TIMEOUT_MS | 
|  | 42 | +        ) | 
|  | 43 | +        print("connected") | 
|  | 44 | + | 
|  | 45 | +        multitest.broadcast("connected-{}".format(i)) | 
|  | 46 | + | 
|  | 47 | +        for j in range(3): | 
|  | 48 | +            channel = await connection.l2cap_accept(_L2CAP_PSN, _L2CAP_MTU) | 
|  | 49 | +            print("channel accepted") | 
|  | 50 | + | 
|  | 51 | +            buf = bytearray(10) | 
|  | 52 | +            n = await channel.recvinto(buf) | 
|  | 53 | +            print("recv", n, buf[:n]) | 
|  | 54 | + | 
|  | 55 | +            multitest.broadcast("recv-{}-{}".format(i, j)) | 
|  | 56 | + | 
|  | 57 | +            await channel.disconnected(5000) | 
|  | 58 | +            print("channel disconnected") | 
|  | 59 | + | 
|  | 60 | +        # Wait for the central to disconnect. | 
|  | 61 | +        await connection.disconnected(timeout_ms=TIMEOUT_MS) | 
|  | 62 | +        print("disconnected") | 
|  | 63 | + | 
|  | 64 | +        # Shutdown aioble + modbluetooth. | 
|  | 65 | +        print("shutdown") | 
|  | 66 | +        aioble.stop() | 
|  | 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 | +        # Connect to peripheral. | 
|  | 83 | +        print("connect") | 
|  | 84 | +        device = aioble.Device(*BDADDR) | 
|  | 85 | +        connection = await device.connect(timeout_ms=TIMEOUT_MS) | 
|  | 86 | + | 
|  | 87 | +        multitest.wait("connected-{}".format(i)) | 
|  | 88 | + | 
|  | 89 | +        # Discover characteristics. | 
|  | 90 | +        service = await connection.service(SERVICE_UUID) | 
|  | 91 | +        print("service", service.uuid) | 
|  | 92 | +        characteristic = await service.characteristic(CHAR_UUID) | 
|  | 93 | +        print("characteristic", characteristic.uuid) | 
|  | 94 | + | 
|  | 95 | +        # Issue read of characteristic, should get initial value. | 
|  | 96 | +        print("read", await characteristic.read(timeout_ms=TIMEOUT_MS)) | 
|  | 97 | + | 
|  | 98 | +        for j in range(3): | 
|  | 99 | +            print("connecting channel") | 
|  | 100 | +            channel = await connection.l2cap_connect(_L2CAP_PSN, _L2CAP_MTU) | 
|  | 101 | +            print("channel connected") | 
|  | 102 | + | 
|  | 103 | +            await channel.send("l2cap-{}-{}".format(i, j)) | 
|  | 104 | +            await channel.flush() | 
|  | 105 | + | 
|  | 106 | +            multitest.wait("recv-{}-{}".format(i, j)) | 
|  | 107 | + | 
|  | 108 | +            print("disconnecting channel") | 
|  | 109 | +            await channel.disconnect() | 
|  | 110 | +            print("channel disconnected") | 
|  | 111 | + | 
|  | 112 | +            await asyncio.sleep_ms(100) | 
|  | 113 | + | 
|  | 114 | +        # Disconnect from peripheral. | 
|  | 115 | +        print("disconnect") | 
|  | 116 | +        await connection.disconnect(timeout_ms=TIMEOUT_MS) | 
|  | 117 | +        print("disconnected") | 
|  | 118 | + | 
|  | 119 | +        # Shutdown aioble. | 
|  | 120 | +        print("shutdown") | 
|  | 121 | +        aioble.stop() | 
|  | 122 | + | 
|  | 123 | + | 
|  | 124 | +def instance1(): | 
|  | 125 | +    try: | 
|  | 126 | +        asyncio.run(instance1_task()) | 
|  | 127 | +    finally: | 
|  | 128 | +        aioble.stop() | 
0 commit comments