Repository navigation
Conversation
Some controllers, such as the Realtek RTL8761, implement only the non-enhanced Setup/Accept/Reject Synchronous Connection commands. bumble had the non-enhanced accept and reject commands but not the setup one, so a host could not create a SCO/eSCO link on those controllers. Also add VoiceSetting.codec_id(), which maps the Air_Coding_Format of a voice setting to the air mode (codec ID) of the Synchronous Connection Complete event: the two use different numbering.
Implement the non-enhanced Setup, Accept and Reject Synchronous Connection commands, which the enhanced commands already had. The non-enhanced setup command does not say whether a SCO or an eSCO link is wanted: follow the spec and make it an eSCO link if any of the eSCO packet types is allowed, a SCO link otherwise. Report the air mode of a link in the Synchronous Connection Complete event, derived from the voice setting (non-enhanced commands) or from the coding format (enhanced commands), instead of always reporting 0. The USB transport uses that air mode to select the isochronous alternate setting.
Add EscoParameters.as_legacy_dict(), which maps codec parameters to the parameters of the non-enhanced Setup/Accept Synchronous Connection commands: the air coding format is taken from the transmit coding format (mSBC and LC3 are coded by the host, so they go over the air as transparent data), and the rest of the coding format is reduced to the sample size, format and bit position of the PCM data on HCI. Add setup_synchronous_connection_command() and accept_synchronous_connection_request_command(), which build the enhanced command when the controller supports it and the non-enhanced one otherwise, and use them in the SCO examples, so that they work with both kinds of controller.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implement the non-enhanced Setup/Accept/Reject Synchronous Connection commands, so that SCO and eSCO links can be set up with controllers that do not implement the enhanced commands, and let the SCO examples fall back to them.
Problem
Bumble had the non-enhanced Accept and Reject Synchronous Connection commands (0x0429, 0x042A) and the events that go with them, but not the non-enhanced Setup Synchronous Connection command (0x0428), so a host could not create a SCO or eSCO link on a controller that only implements the non-enhanced commands. Realtek RTL8761 based dongles (e.g. ASUS BT600) are such controllers: they report neither 0x043D nor 0x043E.
The SCO examples sent the enhanced commands unconditionally (one of them had a hand-rolled fallback with its own voice setting mapping), and the emulated controller only implemented the enhanced commands, so that path could not be tested without hardware.
Fix
bumble/hci.py: add the missingHCI_Setup_Synchronous_Connection_Command(0x0428), with aPacketTypeflag andSCO_PACKET_TYPES/ESCO_PACKET_TYPESmasks, andVoiceSetting.codec_id(), which maps the Air_Coding_Format of a voice setting to the air mode (codec ID) of the Synchronous Connection Complete event (the two use different numbering).bumble/controller.py: implement the non-enhanced Setup, Accept and Reject commands. The non-enhanced setup command does not say whether a SCO or an eSCO link is wanted: make it an eSCO link if any of the eSCO packet types is allowed, and a SCO link otherwise. Also report the air mode of the link in the Synchronous Connection Complete event (from the voice setting for the non-enhanced commands, from the coding format for the enhanced ones) instead of always reporting 0 — the USB transport uses that air mode to select the isochronous alternate setting (see Fix SCO over USB: align packets to the alternate setting, select it per SCO link #1011).bumble/hfp.py: addEscoParameters.as_legacy_dict(), which reduces codec parameters to the parameters of the non-enhanced commands (the air coding format is taken from the transmit coding format: mSBC and LC3 are coded by the host, so they go over the air as transparent data; the rest of the coding format is reduced to the sample size, format and bit position of the PCM data on HCI), andsetup_synchronous_connection_command()/accept_synchronous_connection_request_command(), which return the enhanced command when the controller supports it and the non-enhanced one otherwise.examples/:run_esco_connection.py,run_hfp_gateway.pyandrun_hfp_handsfree.pyuse those builders, so they work with both kinds of controller (and the hand-rolled fallback inrun_hfp_handsfree.pygoes away).Testing
Unit tests: the non-enhanced Setup command round-trips (SCO and eSCO packet types);
VoiceSetting.codec_id(); the legacy parameter mapping (CVSD, mSBC, 8-bit PCM, sign and magnitude); a full eSCO setup and a full SCO setup over the emulated controller with the non-enhanced commands, a setup that the peer rejects, and the existing enhanced setups, all asserting the link type and the air mode. Full suite: 1045 passed, 2 skipped.black -S --check,ruff check,mypyandpylint -Eare clean.Realtek (2x ASUS BT600,
0b05:1d70, RTL8761CU), which only implements the non-enhanced commands:examples/run_esco_connection.pybetween the two dongles picks the non-enhanced commands automatically, and both sides report an eSCO link with CVSD air mode and 60-byte packets:Requesting HV3 only (Core spec SCO packet types) still yields an eSCO link on this controller (
link_type 0x02,tx_packet_length540), which looks like a firmware quirk: bumble reports what the controller reports.Notes
as_legacy_dict()documents what is kept and what is not.