Bluetooth headphone not letting me change its profile to a2dp once connected

Questions about hardware,drivers and peripherals
Forum rules
Before you post please read how to get help
Post Reply
ysul0614
Level 1
Level 1
Posts: 6
Joined: Tue Jul 10, 2018 12:09 am

Bluetooth headphone not letting me change its profile to a2dp once connected

Post by ysul0614 » Thu Jul 12, 2018 9:48 pm

Similar problems seem to be asked a lot, but I haven't seen answers that solved this problem, so I'll post this as a new question.

I am using a bluetooth headphone, Sony WH-1000xm2, which seems to have capability of being connected as A2DP or HSP.
What I want to do is to simply let Linux Mint 19 connect to it using A2DP profile every time headphone is turned on.

However, every time I turn my headphone on, it succeeds to connect to Mint, but Mint chooses "off" profile by default. Once in this state, I am able to change its profile to either HSP or off (either from blueman or from audio settings), but I cannot get Mint to use A2DP profile.
  • In case of blueman, it gives me an error saying that: "Failed to change profile to a2dp_sink".
  • From audio settings, I can choose the output profile option to be a2dp sink, but the option reverts to what it was previously once I choose other available devices.
What is strange is that, I can get a2dp working if I reconnect the headphone in a specific way.
  1. Disconnect headphone (usually using blueman)
  2. Right click on the headphone entry, and choose "audio sink."
If I choose to connect my headphone this way, not only I can choose a2dp profile (and actually listen to music,etc.), but I can freely switch 3 profiles back and forth (off, HSP, A2DP).

So, here is the summary of what seems to be happening.
  • If I just turn my headphone on, Mint connects to this headphone in "limited mode", in which I can only choose either "off" or "HSP" profile.
  • If I specifically choose "a2dp sink" upon connection, Mint "fully" connects to this headphone, in which I can choose all profiles.
To further investigate, I looked at outputs of "bluetoothctl" when headphone is in the two states described above.

Code: Select all

# turn on my headphone. Headphone in limited mode (only HSP/off available)
[CHG] Device 70:26:05:79:1F:4F Connected: yes
# disconnect
[CHG] Device 70:26:05:79:1F:4F Connected: no
# reconnect, specifically choosing "a2dp sink" from blueman menu
[CHG] Device 70:26:05:79:1F:4F Connected: yes
[CHG] Device 70:26:05:79:1F:4F ServicesResolved: yes
I do not know what ServicesResolved means, but I hope it gives some clues.

I also looked at the outputs of "pacmd list-modules" on these two states.
Note that, some of the outputs are in Japanese, and I couldn't get it to change using LC_ALL=C. Translations are provided as comments.
In "limited mode" (only HSP/OFF profile available), profile = OFF :

Code: Select all

index: 20
	name: <bluez_card.70_26_05_79_1F_4F>
	driver: <module-bluez5-device.c>
	owner module: 47
	properties:
		device.description = "WH-1000XM2"
		device.string = "70:26:05:79:1F:4F"
		device.api = "bluez"
		device.class = "sound"
		device.bus = "bluetooth"
		device.form_factor = "headset"
		bluez.path = "/org/bluez/hci0/dev_70_26_05_79_1F_4F"
		bluez.class = "0x240404"
		bluez.alias = "WH-1000XM2"
		device.icon_name = "audio-headset-bluetooth"
		device.intended_roles = "phone"
	profiles:
		headset_head_unit: Headset Head Unit (HSP/HFP) (priority 30, available: unknown)
		a2dp_sink: High Fidelity Playback (A2DP Sink) (priority 40, available: no)
		off: オフ (priority 0, available: yes)	# オフ==off
	active profile: <off>
	ports:
		headset-output: ヘッドセット (priority 0, latency offset 0 usec, available: unknown) 	#ヘッドセット==headset
			properties:
				
		headset-input: ヘッドセット (priority 0, latency offset 0 usec, available: unknown) 	#ヘッドセット==headset
			properties:
				
After enabling a2dp, using the methods above (profile=a2dp_sink):

Code: Select all

index: 21
	name: <bluez_card.70_26_05_79_1F_4F>
	driver: <module-bluez5-device.c>
	owner module: 48
	properties:
		device.description = "WH-1000XM2"
		device.string = "70:26:05:79:1F:4F"
		device.api = "bluez"
		device.class = "sound"
		device.bus = "bluetooth"
		device.form_factor = "headset"
		bluez.path = "/org/bluez/hci0/dev_70_26_05_79_1F_4F"
		bluez.class = "0x240404"
		bluez.alias = "WH-1000XM2"
		device.icon_name = "audio-headset-bluetooth"
		device.intended_roles = "phone"
	profiles:
		headset_head_unit: Headset Head Unit (HSP/HFP) (priority 30, available: unknown)
		a2dp_sink: High Fidelity Playback (A2DP Sink) (priority 40, available: yes)
		off: オフ (priority 0, available: yes)	# オフ==off
	active profile: <a2dp_sink>
	sinks:
		bluez_sink.70_26_05_79_1F_4F.a2dp_sink/#10: WH-1000XM2
	sources:
		bluez_sink.70_26_05_79_1F_4F.a2dp_sink.monitor/#14: Monitor of WH-1000XM2
	ports:
		headset-output: ヘッドセット (priority 0, latency offset 0 usec, available: yes) 	#ヘッドセット==headset
			properties:
				
		headset-input: ヘッドセット (priority 0, latency offset 0 usec, available: unknown)  	#ヘッドセット==headset
			properties:
				
This was all I was able to investigate so far.
Does anyone know how to get this headphone to connect to Mint in a2dp-enabled fashion by default?
It is very frustrating having to manually disconnect/reconnect from blueman.

Using Linux mint 19 Cinnamon, 64-bit.

Edit 1 (July 14, 2018)
Some additional information.
  1. Results of journalctl --unit=bluetooth -f
    I tried to look at the log for bluetooth connection, and noticed that, when the headset is reconnected (and thus a2dp is enabled), the message below shows up:

    Code: Select all

     7月 14 22:31:25 ysul0614-LM19 bluetoothd[20961]: /org/bluez/hci0/dev_70_26_05_79_1F_4F/fd1: fd(38) ready
    
    However, when the headset is powered off, then on ,and automatically gets reconnected, this message does not show up.
  2. Results of tail -f /var/log/syslog during these procedures
    I inspected system log during initial headphone disconnection (via power button of headphone), power on, disconnection (via blueman), and reconnection (via blueman):

    Code: Select all

    # headset is turned off
    Jul 14 22:40:21 ysul0614-LM19 acpid: input device has been disconnected, fd 21
    Jul 14 22:40:21 ysul0614-LM19 bluetoothd[20961]: Unable to get io data for Headset Voice gateway: getpeername: Transport endpoint is not connected (107)
    Jul 14 22:40:23 ysul0614-LM19 kernel: [47925.782311] retire_capture_urb: 2492 callbacks suppressed
    Jul 14 22:40:28 ysul0614-LM19 kernel: [47930.786300] retire_capture_urb: 2492 callbacks suppressed
    Jul 14 22:40:29 ysul0614-LM19 kernel: [47931.352188] Bluetooth: hci0: last event is not cmd complete (0x0f)
    Jul 14 22:40:33 ysul0614-LM19 kernel: [47935.790267] retire_capture_urb: 2492 callbacks suppressed
    # headset is turned on, headset in "limited" mode (no a2dp available)
    Jul 14 22:40:35 ysul0614-LM19 pulseaudio[14614]: [pulseaudio] module-bluez5-device.c: Profile a2dp_sink has no transport
    Jul 14 22:40:38 ysul0614-LM19 kernel: [47940.794310] retire_capture_urb: 2492 callbacks suppressed
    # headphone is disconnected via blueman
    Jul 14 22:40:43 ysul0614-LM19 bluetoothd[20961]: Unable to get io data for Headset Voice gateway: getpeername: Transport endpoint is not connected (107)
    Jul 14 22:40:43 ysul0614-LM19 kernel: [47945.798327] retire_capture_urb: 2492 callbacks suppressed
    Jul 14 22:40:48 ysul0614-LM19 kernel: [47950.352321] Bluetooth: hci0: last event is not cmd complete (0x0f)
    Jul 14 22:40:48 ysul0614-LM19 kernel: [47950.802251] retire_capture_urb: 2492 callbacks suppressed
    Jul 14 22:40:53 ysul0614-LM19 kernel: [47955.806306] retire_capture_urb: 2492 callbacks suppressed
    Jul 14 22:40:58 ysul0614-LM19 kernel: [47960.810327] retire_capture_urb: 2492 callbacks suppressed
    Jul 14 22:41:03 ysul0614-LM19 kernel: [47965.812332] retire_capture_urb: 2491 callbacks suppressed
    Jul 14 22:41:04 ysul0614-LM19 kernel: [47966.352184] Bluetooth: hci0: last event is not cmd complete (0x0f)
    # headphone is reconnected via blueman
    Jul 14 22:41:04 ysul0614-LM19 bluetoothd[20961]: /org/bluez/hci0/dev_70_26_05_79_1F_4F/fd3: fd(38) ready
    Jul 14 22:41:04 ysul0614-LM19 rtkit-daemon[1492]: Supervising 5 threads of 1 processes of 1 users.
    Jul 14 22:41:04 ysul0614-LM19 rtkit-daemon[1492]: Successfully made thread 3329 of process 14614 (n/a) owned by '1000' RT at priority 5.
    Jul 14 22:41:04 ysul0614-LM19 rtkit-daemon[1492]: Supervising 6 threads of 1 processes of 1 users.
    Jul 14 22:41:04 ysul0614-LM19 kernel: [47966.972245] input: 70:26:05:79:1F:4F as /devices/virtual/input/input64
    
    The log saying "pulseaudio[14614]: [pulseaudio] module-bluez5-device.c: Profile a2dp_sink has no transport" might indicate some error, but again, I'm not an expert on this.
Looking at these results, I'm starting to feel like this is either bluez (or some bluetooth software) bug, or a pulseaudio bug, although I initially thought it's a hardware bug.

I would appreciate any input on how I can deal with this, or if this is a system bug (on either bluez or pulseaudio) that should be reported elsewhere.
Last edited by ysul0614 on Sun Jul 15, 2018 1:49 am, edited 1 time in total.

ysul0614
Level 1
Level 1
Posts: 6
Joined: Tue Jul 10, 2018 12:09 am

Re: Bluetooth headphone not letting me change its profile to a2dp once connected

Post by ysul0614 » Sat Jul 14, 2018 2:39 am

Edit (additiona info):
First of all, I have not solved this problem, but I found some additional behavior that might help in debugging this problem.

I just discovered that, after this headphone gets into "limited" mode, a simple disconnect -> reconnect (without specifying audio sink from blueman) gets a2dp working. So, commands in in bluetoothctl like:

Code: Select all

[WH-1000XM2]# disconnect 70:26:05:79:1F:4F 
Attempting to disconnect from 70:26:05:79:1F:4F
Successful disconnected
[CHG] Device 70:26:05:79:1F:4F Connected: no
[bluetooth]# connect 70:26:05:79:1F:4F 
Attempting to connect to 70:26:05:79:1F:4F
[CHG] Device 70:26:05:79:1F:4F Connected: yes
Connection successful
[CHG] Device 70:26:05:79:1F:4F ServicesResolved: yes
enables a2dp. This is such a weird behavior, since when the headphone turns on and automatically connects to the laptop, it connects in such a way that a2dp is disabled. However, a simple disconnect/reconnect enables a2dp.

Anyway, I would like to get the headphone to connect automatically with a2dp enabled the first time it connects. Any advice is appreciated.

ugly
Level 3
Level 3
Posts: 164
Joined: Thu Nov 24, 2016 9:17 pm

Re: Bluetooth headphone not letting me change its profile to a2dp once connected

Post by ugly » Sat Jul 14, 2018 6:45 pm

This was a problem for me for a long time in LM 18.x.

After doing a clean install of LM 19, the problem seems to have gone away and connecting my bluetooth headphones works like I expect it to.

When I did have the issue, I found a script someone made that does the whole disconnect/reconnect routine to get it working.

I believe this is the script that I used: https://gist.github.com/pylover/d68be36 ... 5e6ed6e7ae

But I haven't tested in LM 19.

ysul0614
Level 1
Level 1
Posts: 6
Joined: Tue Jul 10, 2018 12:09 am

Re: Bluetooth headphone not letting me change its profile to a2dp once connected

Post by ysul0614 » Sun Jul 15, 2018 1:31 am

ugly wrote:
Sat Jul 14, 2018 6:45 pm
This was a problem for me for a long time in LM 18.x.

After doing a clean install of LM 19, the problem seems to have gone away and connecting my bluetooth headphones works like I expect it to.

When I did have the issue, I found a script someone made that does the whole disconnect/reconnect routine to get it working.

I believe this is the script that I used: https://gist.github.com/pylover/d68be36 ... 5e6ed6e7ae

But I haven't tested in LM 19.
I tried that script, but it doesn't seem like it works in my case.
Since, in my case, pulseaudio determines that a2dp profile is not available, a2dp.py fails after 15 attempts of finding the a2dp profile.

ugly
Level 3
Level 3
Posts: 164
Joined: Thu Nov 24, 2016 9:17 pm

Re: Bluetooth headphone not letting me change its profile to a2dp once connected

Post by ugly » Sun Jul 15, 2018 2:50 pm

I'm far from knowledgeable enough to find a solution for you. When I connect my BT headphones they usually connect as a2dp. Once in a while, they connect as HSP. I made a little script that selects between different audio sources, and part of selecting the BT headphones, I have it select a2dp. Maybe some info to compare to might help you figure your case out.

After connecting my BT headphones, if I run:

Code: Select all

pactl list cards
I get (edited down to just the BT headphones):

Code: Select all

Card #3
	Name: bluez_card.00_1A_7D_21_8B_D4
	Driver: module-bluez5-device.c
	Owner Module: 28
	Properties:
		device.description = "Kinivo BTH240"
		device.string = "00:1A:7D:21:8B:D4"
		device.api = "bluez"
		device.class = "sound"
		device.bus = "bluetooth"
		device.form_factor = "headset"
		bluez.path = "/org/bluez/hci0/dev_00_1A_7D_21_8B_D4"
		bluez.class = "0x240404"
		bluez.alias = "Kinivo BTH240"
		device.icon_name = "audio-headset-bluetooth"
		device.intended_roles = "phone"
	Profiles:
		headset_head_unit: Headset Head Unit (HSP/HFP) (sinks: 1, sources: 1, priority: 30, available: yes)
		a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 40, available: yes)
		off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
	Active Profile: a2dp_sink
	Ports:
		headset-output: Headset (priority: 0, latency offset: 0 usec)
			Part of profile(s): headset_head_unit, a2dp_sink
		headset-input: Headset (priority: 0, latency offset: 0 usec)
			Part of profile(s): headset_head_unit
You can see that I have 3 available profiles - off, a2dp_sink and headset_head_unit.

This time my active is a2dp_sink. Like I said, sometimes it doesn't work out like that.

If I run:

Code: Select all

pacmd list-sinks
I get (again, edited down to just BT):

Code: Select all

index: 2
	name: <bluez_sink.00_1A_7D_21_8B_D4.a2dp_sink>
	driver: <module-bluez5-device.c>
	flags: HARDWARE DECIBEL_VOLUME LATENCY 
	state: SUSPENDED
	suspend cause: IDLE 
	priority: 9050
	volume: front-left: 65536 / 100% / 0.00 dB,   front-right: 65536 / 100% / 0.00 dB
	        balance 0.00
	base volume: 65536 / 100% / 0.00 dB
	volume steps: 65537
	muted: no
	current latency: 0.00 ms
	max request: 3 KiB
	max rewind: 0 KiB
	monitor source: 3
	sample spec: s16le 2ch 44100Hz
	channel map: front-left,front-right
	             Stereo
	used by: 0
	linked by: 0
	fixed latency: 45.32 ms
	card: 3 <bluez_card.00_1A_7D_21_8B_D4>
	module: 28
	properties:
		bluetooth.protocol = "a2dp_sink"
		device.description = "Kinivo BTH240"
		device.string = "00:1A:7D:21:8B:D4"
		device.api = "bluez"
		device.class = "sound"
		device.bus = "bluetooth"
		device.form_factor = "headset"
		bluez.path = "/org/bluez/hci0/dev_00_1A_7D_21_8B_D4"
		bluez.class = "0x240404"
		bluez.alias = "Kinivo BTH240"
		device.icon_name = "audio-headset-bluetooth"
		device.intended_roles = "phone"
	ports:
		headset-output: Headset (priority 0, latency offset 0 usec, available: unknown)
			properties:
				
	active port: <headset-output>
In LM 18.3, this used to be named "bluez_sink.00_1A_7D_21_8B_D4"
In LM 19, it is named "bluez_sink.00_1A_7D_21_8B_D4.a2dp_sink" with .a2pd_sink appended.

So, my script for selecting my BT audio headset with a2pd has these commands:

Code: Select all

#get this from running pacmd list-sinks
devicename="bluez_sink.00_1A_7D_21_8B_D4.a2dp_sink"

#get these from running pactl list
cardname="bluez_card.00_1A_7D_21_8B_D4"
profilename="a2dp_sink"

pactl set-card-profile "$cardname" "$profilename"
pacmd set-default-sink "$devicename"

#move all audio to the new sink
for app in $(pacmd list-sink-inputs | sed -n -e 's/index:[[:space:]]\([[:digit:]]\)/\1/p');
do
	pacmd "move-sink-input $app "$devicename""
done
But, if your a2dp isn't showing up at all, this probably won't work. But hopefully, it will at least give you something to compare to.

Note that, without doing

Code: Select all

pactl set-card-profile "$cardname" "$profilename"
first, then bluez_sink.00_1A_7D_21_8B_D4.a2dp_sink is not listed when I run pacmd set-default-sink or pacmd list-sinks

ysul0614
Level 1
Level 1
Posts: 6
Joined: Tue Jul 10, 2018 12:09 am

Re: Bluetooth headphone not letting me change its profile to a2dp once connected

Post by ysul0614 » Sun Jul 15, 2018 5:14 pm

ugly wrote:
Sun Jul 15, 2018 2:50 pm
But, if your a2dp isn't showing up at all, this probably won't work. But hopefully, it will at least give you something to compare to.

Note that, without doing

Code: Select all

pactl set-card-profile "$cardname" "$profilename"
first, then bluez_sink.00_1A_7D_21_8B_D4.a2dp_sink is not listed when I run pacmd set-default-sink or pacmd list-sinks
Yup. As you expected, the given script doesn't work, showing the output:

Code: Select all

Failure: Input/Output error
Sink bluez_sink.70_26_05_79_1F_4F.a2dp_sink does not exist.
No sink found by this name or index.
but thank you for sharing your solutions.

It seems like the fundamental problem is, as seen from the output of "pactl list-sinks," the a2dp sink for this headphone is not showing up when connected.
This, I think, can mean 2 things:
  1. Sink is there, but pulseaudio does not detect/refresh the list of sinks properly, thus not showing up.
  2. Whatever process responsible for creating sink does not create sink properly
  3. Bugs happening at even lower level than that
To test for the first possibility, I ran the command "pacmd unload-module module-udev-detect && pacmd load-module module-udev-detect"
To re-scan for available sinks, but a2dp profile still didn't show up. That might indicate that the problem lies in either possibility 2 or 3.

Post Reply

Return to “Hardware Support”