How to run multiple GATT servers #572
-
I have tried sharing async with await open_transport_or_link(link_name) as transport:
start_device(create_device1(transport))
start_device(create_device2(transport)) Both But got error
I also tried create
It turns out that only first device are listening. My question is what is the correct way to start multiple servers in single process? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
Transport cannot be shared by multiple hosts. If you have multiple transports, you can run independent host on each transport like https://github.com/google/bumble/blob/main/examples/run_csis_servers.py. In fact, running multiple GATT servers on a single device is impossible, because all of them share the same ATT L2CAP channel. So, I think you need to check what's your actual use case and solve them in the other way, instead of reusing the transport. |
Beta Was this translation helpful? Give feedback.
-
As @zxzxwu points out, you can only have one Device/Host per transport. |
Beta Was this translation helpful? Give feedback.
-
@zxzxwu @barbibulle Thanks a lot for your reply. I should first state out my use case. I serve two devices by running this python code twice: import asyncio
from sys import argv
from bumble.core import AdvertisingData
from bumble.device import Connection, Device, DeviceConfiguration
from bumble.hci import Address
from bumble.transport import open_transport_or_link
from bumble.transport.common import Transport
class Listener(Device.Listener, Connection.Listener):
def __init__(self, device):
self.device = device
def on_connection(self, connection):
print(f"=== Connected to {connection}")
connection.listener = self
def on_disconnection(self, reason):
print(f"### Disconnected, reason={reason}")
def create_device(name: str, address: str, transport: Transport) -> Device:
config = DeviceConfiguration(
name=name,
address=Address(address),
advertising_data=bytes(
AdvertisingData(
[(AdvertisingData.COMPLETE_LOCAL_NAME, bytes(name, "utf-8"))]
)
),
)
device = Device.from_config_with_hci(config, transport.source, transport.sink)
device.listener = Listener(device)
return device
async def main():
transport = await open_transport_or_link("android-netsim")
device = create_device(argv[1], argv[2], transport)
await device.power_on()
await device.start_advertising(auto_restart=True)
print(f"start device {argv[1]}")
await transport.source.terminated
asyncio.run(main()) for example: $ python run_gatt.py Device1 F0:F0:F0:F0:F0:F0
start device Device1
# Another terminal
$ python run_gatt.py Device2 F0:F0:F0:F0:F0:F1
start device Device2 After execute the code twice, I can have two device listen on Now, I want to use single python process to start up multiple server: async def main():
transports = []
for name, address in zip(argv[1::2], argv[2::2]):
transport = await open_transport_or_link("android-netsim")
transports.append(transport)
device = await create_device(name, address)
await device.power_on()
await device.start_advertising(auto_restart=True)
print(f'start device {argv[1]}')
await asyncio.gather(*[e.source.terminated for e in transports]) I create transport for each device from your advices
But I got the error and my app can only discovery first device ( $ python run_gatt.py Device1 F0:F0:F0:F0:F0:F0 Device2 F0:F0:F0:F0:F0:F1
start device Device1
ERROR:fsevents:Unhandled exception in FSEventsEmitter
Traceback (most recent call last):
File "./site-packages/watchdog/observers/fsevents.py", line 307, in run
_fsevents.add_watch(self, self.watch, self.events_callback, self.pathnames)
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: Cannot add watch <ObservedWatch: path='printer_status', is_recursive=True> - it is already scheduled
start device Device2 |
Beta Was this translation helpful? Give feedback.
Transport cannot be shared by multiple hosts. If you have multiple transports, you can run independent host on each transport like https://github.com/google/bumble/blob/main/examples/run_csis_servers.py.
In fact, running multiple GATT servers on a single device is impossible, because all of them share the same ATT L2CAP channel. So, I think you need to check what's your actual use case and solve them in the other way, instead of reusing the transport.