diff --git a/src/auracast/multicast.py b/src/auracast/multicast.py index b962492..f3421a2 100644 --- a/src/auracast/multicast.py +++ b/src/auracast/multicast.py @@ -520,7 +520,17 @@ async def init_broadcast( advertising_sid=i, primary_advertising_phy=hci.Phy.LE_1M, # 2m phy config throws error - because for primary advertising channels, 1mbit is only supported secondary_advertising_phy=hci.Phy.LE_1M, # this is the secondary advertising beeing send on non advertising channels (extendend advertising) - advertising_tx_power=global_config.advertising_tx_power, # dBm; clamped to nearest SDC-supported step (max via CONFIG_BT_CTLR_TX_PWR_*) + # Pass NO_PREFERENCE (0x7F) here for two reasons: + # 1. The Nordic SoftDevice Controller ignores this field for + # advertising sets and always returns the compile-time + # CONFIG_BT_CTLR_TX_PWR_* value. The real TX power is + # applied via the Zephyr VS Write_Tx_Power_Level command + # issued right after create_advertising_set() returns. + # 2. Bumble's HCI metadata declares this field as 1-byte + # *unsigned* (a bumble bug — the BT spec defines it as + # signed int8), so negative values would raise + # "bytes must be in range(0, 256)" at serialization. + advertising_tx_power=hci.HCI_LE_Set_Extended_Advertising_Parameters_Command.TX_POWER_NO_PREFERENCE, #secondary_advertising_max_skip=10, ), advertising_data=( @@ -537,9 +547,11 @@ async def init_broadcast( auto_start=True, ) bigs[f'big{i}']['advertising_set'] = advertising_set - logging.info( - 'Advertising TX power (LE_Set_Ext_Adv_Params): requested=%+d dBm, controller selected=%+d dBm (handle=%d)', - global_config.advertising_tx_power, + # NOTE: selected_tx_power below reflects the SDC's compile-time max + # (LE_Set_Ext_Adv_Params was sent with NO_PREFERENCE). The actual + # transmit power is set by the VS Write_Tx_Power_Level call below. + logging.debug( + 'LE_Set_Ext_Adv_Params reports controller fallback TX power: %+d dBm (handle=%d)', getattr(advertising_set, 'selected_tx_power', 0), i, )