So why did Bluez initiate A2DP even when the headset was the one that established the ACL?
The bluetoothd logs help out here:
Aug 29 00:54:47 RhoPC bluetoothd[4046739]: src/adapter.c:connected_callback() hci0 device FC:58:FA:7F:E5:18 connected eir_len 5
Aug 29 00:54:47 RhoPC bluetoothd[4046739]: src/profile.c:ext_confirm() incoming connect from FC:58:FA:7F:E5:18
Aug 29 00:54:47 RhoPC bluetoothd[4046739]: src/service.c:btd_service_ref() 0x562f6441d710: ref=2
Aug 29 00:54:47 RhoPC bluetoothd[4046739]: src/profile.c:ext_confirm() Headset Voice gateway authorizing connection from FC:58:FA:7F:E5:18
Aug 29 00:54:47 RhoPC bluetoothd[4046739]: src/profile.c:ext_auth() FC:58:FA:7F:E5:18 authorized to connect to Headset Voice gateway
Aug 29 00:54:47 RhoPC bluetoothd[4046739]: src/profile.c:ext_connect() Headset Voice gateway connected to FC:58:FA:7F:E5:18
Aug 29 00:54:47 RhoPC bluetoothd[4046739]: src/service.c:change_state() 0x562f6441d710: device FC:58:FA:7F:E5:18 profile Headset Voice gateway state changed: disconnected -> connecting (0)
Aug 29 00:54:47 RhoPC bluetoothd[4046739]: src/service.c:change_state() 0x562f6441d710: device FC:58:FA:7F:E5:18 profile Headset Voice gateway state changed: connecting -> connected (0)
Aug 29 00:54:47 RhoPC bluetoothd[4046739]: src/device.c:device_profile_connected() Headset Voice gateway Success (0)
Aug 29 00:54:47 RhoPC bluetoothd[4046739]: plugins/policy.c:policy_connect() /org/bluez/hci0/dev_FC_58_FA_7F_E5_18 profile a2dp-sink
Aug 29 00:54:47 RhoPC bluetoothd[4046739]: profiles/audio/a2dp.c:a2dp_sink_connect() path /org/bluez/hci0/dev_FC_58_FA_7F_E5_18
One can easily see at the end there, where something in plugins/policy.c kicks off A2DP connection, apparently as soon as it got word that HFP had connected.
Checking that file, the offending code seems to be this in hs_cb():
case BTD_SERVICE_STATE_CONNECTED:
/* Check if service initiate the connection then proceed
* immediately otherwise set timer
*/
if (old_state == BTD_SERVICE_STATE_CONNECTING)
policy_connect(data, sink);
else if (btd_service_get_state(sink) !=
BTD_SERVICE_STATE_CONNECTED)
policy_set_sink_timer(data);
break;
The reasoning is sound though -- if the HFP connection was locally initiated i.e. previously in STATE_CONNECTING, then go ahead and connect A2DP right now. Otherwise, respect right-of-way and set a timer to connect it in around 2s, in case the headset somehow fails to do so.
The problem is, this HFP connection was NOT locally initiated. So why was policy.c informed that it is?
So why did Bluez initiate A2DP even when the headset was the one that established the ACL?
The bluetoothd logs help out here:
Aug 29 00:54:47 RhoPC bluetoothd[ 4046739] : src/adapter. c:connected_ callback( ) hci0 device FC:58:FA:7F:E5:18 connected eir_len 5 4046739] : src/profile. c:ext_confirm( ) incoming connect from FC:58:FA:7F:E5:18 4046739] : src/service. c:btd_service_ ref() 0x562f6441d710: ref=2 4046739] : src/profile. c:ext_confirm( ) Headset Voice gateway authorizing connection from FC:58:FA:7F:E5:18 4046739] : src/profile. c:ext_auth( ) FC:58:FA:7F:E5:18 authorized to connect to Headset Voice gateway 4046739] : src/profile. c:ext_connect( ) Headset Voice gateway connected to FC:58:FA:7F:E5:18 4046739] : src/service. c:change_ state() 0x562f6441d710: device FC:58:FA:7F:E5:18 profile Headset Voice gateway state changed: disconnected -> connecting (0) 4046739] : src/service. c:change_ state() 0x562f6441d710: device FC:58:FA:7F:E5:18 profile Headset Voice gateway state changed: connecting -> connected (0) 4046739] : src/device. c:device_ profile_ connected( ) Headset Voice gateway Success (0) 4046739] : plugins/ policy. c:policy_ connect( ) /org/bluez/ hci0/dev_ FC_58_FA_ 7F_E5_18 profile a2dp-sink 4046739] : profiles/ audio/a2dp. c:a2dp_ sink_connect( ) path /org/bluez/ hci0/dev_ FC_58_FA_ 7F_E5_18
Aug 29 00:54:47 RhoPC bluetoothd[
Aug 29 00:54:47 RhoPC bluetoothd[
Aug 29 00:54:47 RhoPC bluetoothd[
Aug 29 00:54:47 RhoPC bluetoothd[
Aug 29 00:54:47 RhoPC bluetoothd[
Aug 29 00:54:47 RhoPC bluetoothd[
Aug 29 00:54:47 RhoPC bluetoothd[
Aug 29 00:54:47 RhoPC bluetoothd[
Aug 29 00:54:47 RhoPC bluetoothd[
Aug 29 00:54:47 RhoPC bluetoothd[
One can easily see at the end there, where something in plugins/policy.c kicks off A2DP connection, apparently as soon as it got word that HFP had connected.
Checking that file, the offending code seems to be this in hs_cb():
case BTD_SERVICE_ STATE_CONNECTED : STATE_CONNECTIN G) connect( data, sink); get_state( sink) != SERVICE_ STATE_CONNECTED ) set_sink_ timer(data) ;
/* Check if service initiate the connection then proceed
* immediately otherwise set timer
*/
if (old_state == BTD_SERVICE_
policy_
else if (btd_service_
BTD_
policy_
break;
The reasoning is sound though -- if the HFP connection was locally initiated i.e. previously in STATE_CONNECTING, then go ahead and connect A2DP right now. Otherwise, respect right-of-way and set a timer to connect it in around 2s, in case the headset somehow fails to do so.
The problem is, this HFP connection was NOT locally initiated. So why was policy.c informed that it is?