Apply advertising TX power via Zephyr vendor-specific command for Nordic SDC.

This commit is contained in:
2026-04-30 17:07:28 +02:00
parent bc8cd78c4a
commit d2e47b79d9

View File

@@ -49,6 +49,7 @@ import bumble.transport
import bumble.utils
from bumble.device import Host, AdvertisingChannelMap
from bumble.audio import io as audio_io
from bumble.vendor.zephyr.hci import HCI_Write_Tx_Power_Level_Command
from auracast import auracast_config
from auracast.utils.read_lc3_file import read_lc3_file
@@ -537,12 +538,46 @@ async def init_broadcast(
)
bigs[f'big{i}']['advertising_set'] = advertising_set
logging.info(
'Advertising TX power: requested=%+d dBm, controller selected=%+d dBm (handle=%d)',
'Advertising TX power (LE_Set_Ext_Adv_Params): requested=%+d dBm, controller selected=%+d dBm (handle=%d)',
global_config.advertising_tx_power,
getattr(advertising_set, 'selected_tx_power', 0),
i,
)
# The Nordic SoftDevice Controller does not honor the per-set
# advertising_tx_power passed in HCI_LE_Set_Extended_Advertising_Parameters
# (it returns the compile-time CONFIG_BT_CTLR_TX_PWR_* value regardless).
# Apply the requested level via the Zephyr Vendor-Specific HCI command
# Write_Tx_Power_Level (opcode 0xFC0E), which the SDC honors per
# advertising handle. The SDC clamps the value to the nearest supported
# hardware step (max bounded by CONFIG_BT_CTLR_TX_PWR_PLUS_8).
try:
adv_handle = getattr(advertising_set, 'advertising_handle', i)
response = await device.send_command(
HCI_Write_Tx_Power_Level_Command(
handle_type=HCI_Write_Tx_Power_Level_Command.TX_POWER_HANDLE_TYPE_ADV,
connection_handle=adv_handle,
tx_power_level=global_config.advertising_tx_power,
)
)
rp = getattr(response, 'return_parameters', None)
status = getattr(rp, 'status', 0xFF) if rp is not None else 0xFF
selected = getattr(rp, 'selected_tx_power_level', None) if rp is not None else None
if status == 0 and selected is not None:
logging.info(
'Advertising TX power (VS Write_Tx_Power_Level): requested=%+d dBm, controller selected=%+d dBm (handle=%d)',
global_config.advertising_tx_power,
selected,
adv_handle,
)
else:
logging.warning(
'VS Write_Tx_Power_Level failed: status=0x%02X handle=%d requested=%+d dBm',
status, adv_handle, global_config.advertising_tx_power,
)
except Exception as e:
logging.warning('VS Write_Tx_Power_Level not supported by controller: %s', e)
logging.info('Start Periodic Advertising')
await advertising_set.start_periodic()