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

controller extended advertising #238

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
37 changes: 37 additions & 0 deletions apps/controller_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
from bumble.colors import color
from bumble.core import name_or_number
from bumble.hci import (
HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND,
HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND,
HCI_Read_Local_Extended_Features_Command,
HCI_Read_Local_Supported_Features_Command,
map_null_terminated_utf8_string,
HCI_SUCCESS,
HCI_LE_SUPPORTED_FEATURES_NAMES,
Expand Down Expand Up @@ -58,6 +62,36 @@ def command_succeeded(response):
return False


# -----------------------------------------------------------------------------
async def get_common_info(host):
if host.supports_command(HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND):
response = await host.send_command(HCI_Read_Local_Supported_Features_Command())
if response.return_parameters.status == HCI_SUCCESS:
print()
print(color('LMP Features:', 'yellow'))
# TODO: support printing discrete enum values
print(' ', response.return_parameters.lmp_features.hex())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be helpful to parse features into set or IntFlag or something else because sometimes we need to check controller capabilities for both dev and product evaluation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I'll try to add that in a separate PR.


if host.supports_command(HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND):
response = await host.send_command(
HCI_Read_Local_Extended_Features_Command(page_number=0)
)
if response.return_parameters.status == HCI_SUCCESS:
if response.return_parameters.max_page_number > 0:
print()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the empty line intended?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. That's to ensure a blank line before the section.

print(color('Extended LMP Features:', 'yellow'))

for page in range(1, response.return_parameters.max_page_number + 1):
response = await host.send_command(
HCI_Read_Local_Extended_Features_Command(page_number=page)
)

if response.return_parameters.status == HCI_SUCCESS:
# TODO: support printing discrete enum values
print(f' Page {page}:')
print(' ', response.return_parameters.extended_lmp_features.hex())


# -----------------------------------------------------------------------------
async def get_classic_info(host):
if host.supports_command(HCI_READ_BD_ADDR_COMMAND):
Expand Down Expand Up @@ -162,6 +196,9 @@ async def async_main(transport):
)
print(color(' LMP Subversion:', 'green'), host.local_version.lmp_subversion)

# Get the common info
await get_common_info(host)

# Get the Classic info
await get_classic_info(host)

Expand Down
30 changes: 15 additions & 15 deletions apps/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,33 @@
# -----------------------------------------------------------------------------
import logging
import asyncio
import sys
import os

from bumble.controller import Controller
import click

from bumble.controller import Controller, Options
from bumble.link import LocalLink
from bumble.transport import open_transport_or_link


# -----------------------------------------------------------------------------
async def async_main():
if len(sys.argv) != 3:
print(
'Usage: controllers.py <hci-transport-1> <hci-transport-2> '
'[<hci-transport-3> ...]'
)
print('example: python controllers.py pty:ble1 pty:ble2')
return

async def async_main(extended_advertising, transport_names):
# Create a local link to attach the controllers to
link = LocalLink()

# Create a transport and controller for all requested names
transports = []
controllers = []
for index, transport_name in enumerate(sys.argv[1:]):
options = Options(extended_advertising=extended_advertising)
for index, transport_name in enumerate(transport_names):
transport = await open_transport_or_link(transport_name)
transports.append(transport)
controller = Controller(
f'C{index}',
host_source=transport.source,
host_sink=transport.sink,
link=link,
options=options,
)
controllers.append(controller)

Expand All @@ -61,9 +56,14 @@ async def async_main():


# -----------------------------------------------------------------------------
def main():
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
asyncio.run(async_main())
@click.command()
@click.option(
'--extended-advertising', is_flag=True, help="Enable extended advertising"
)
@click.argument('transports', nargs=-1, required=True)
def main(extended_advertising, transports):
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper())
asyncio.run(async_main(extended_advertising, transports))


# -----------------------------------------------------------------------------
Expand Down
11 changes: 8 additions & 3 deletions apps/link_relay/link_relay.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ async def serve(self, websocket, path):


# ----------------------------------------------------------------------------
def main():
async def async_main():
# Check the Python version
if sys.version_info < (3, 6, 1):
print('ERROR: Python 3.6.1 or higher is required')
Expand All @@ -280,8 +280,13 @@ def main():

# Start a relay
relay = Relay(args.port)
asyncio.get_event_loop().run_until_complete(relay.start())
asyncio.get_event_loop().run_forever()
async with relay.start():
await asyncio.Future()


# ----------------------------------------------------------------------------
def main():
asyncio.run(async_main())


# ----------------------------------------------------------------------------
Expand Down
Loading