<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>my tech blog &#187; bluetooth</title>
	<atom:link href="http://billauer.se/blog/category/bluetooth/feed/" rel="self" type="application/rss+xml" />
	<link>https://billauer.se/blog</link>
	<description>Anything I found worthy to write down.</description>
	<lastBuildDate>Thu, 12 Mar 2026 11:36:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Notes on Bluetooth on Linux internals</title>
		<link>https://billauer.se/blog/2023/06/bluetoothd-sniffing-dbus/</link>
		<comments>https://billauer.se/blog/2023/06/bluetoothd-sniffing-dbus/#comments</comments>
		<pubDate>Sat, 03 Jun 2023 10:12:49 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[bluetooth]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=6887</guid>
		<description><![CDATA[Introduction These are notes I made while trying to make my Sony WH-CH510 bluetooth headphones work properly with my Linux Mint 19 machine. It&#8217;s evident that an upgrade of the whole OS would have fixed the problem, but I have my opinion on upgrades. The problem: It takes a long time for the headphones to [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>These are notes I made while trying to make my Sony WH-CH510 bluetooth headphones work properly with my Linux Mint 19 machine. It&#8217;s evident that an upgrade of the whole OS would have fixed the problem, but I have my opinion on upgrades.</p>
<p>The problem: It takes a long time for the headphones to connect (around 20-30 seconds), and once that happens, the headphones are not automatically chosen by Pulseaudio as the output device. There are hacky solutions to the second part of the problems, but I have this thing about wanting to solve a problem properly.</p>
<p>The twist is that there&#8217;s no problem at all with Sony&#8217;s WH-CH500 headphones, neither with a pair of junky earbuds, which are labeled Y30.</p>
<p>So after trying quite a few quick fixes, I decided to get to the bottom of the problem. The good news is that I found out the reason for the problem. The bad news is that I didn&#8217;t find any direct solution for it.</p>
<p>So my solution was to upgrade the bluetooth daemon, and I did it in a rather exotic way: I basically installed a Linux Mint 21.1 (&#8220;Victoria&#8221;) pretty much in the same way as explained in <a title="Upgrading to Linux Mint 19, running the old system in a chroot" href="https://billauer.se/blog/2018/11/linux-chroot-system-in-parallel/" target="_blank">this post</a>. Now bluetoothd version 5.64 runs instead of Linux Mint&#8217;s 19 version 5.48 of this daemon, and everything works like a charm. But it&#8217;s a rather tangled solution if you don&#8217;t have this parallel Linux distribution installed for other reasons.</p>
<p>The rest of this post is a collection of things I tried before upgrading the daemon.</p>
<p>Bluetooth is handled by the kernel, which presents an hci device (typically hci0). The heavy lifting of implementing the protocol is done by bluetoothd ( /usr/lib/bluetooth/bluetoothd on my machine, started by the bluetooth systemd service). Try, for example,</p>
<pre>$ hciconfig</pre>
<h3>Sniffing</h3>
<p>To capture bluetooth communication, there are two primary option: The bluetooth0 interface in Wireshark or the btmon command line utility. Wireshark is more comprehensive as always, however btmon is actually easier to work with, because all crucial information is concentrated in a text file. The eternal tradeoff between GUI and text. Possibly, use both.</p>
<p>I&#8217;m going to show excerpts from btmon dumps below, obtained with e.g.</p>
<pre>$ sudo stdbuf -oL btmon | tee btmon.txt</pre>
<p>This could have been just &#8220;sudo btmon&#8221;, but using stdbuf and tee, there&#8217;s also data printed out to console in real time (stdbuf removes unnecessary buffering).</p>
<p>I skip a lot of entries, because there are, well, a lot of them. Hopefully I didn&#8217;t throw away anything relevant.</p>
<p>With btmon, &#8220;&gt;&#8221; means incoming to host, and &#8220;&lt;&#8221; means outgoing from host (the device is at the left side, which is a bit odd).</p>
<p>I&#8217;ve never carried out a bluetooth-related project, so <span class="punch">all my comments on btmon&#8217;s output below are no more than hopefully intelligent guesses</span>. I don&#8217;t pretend to be acquainted with any of the related protocols.</p>
<h3>The connection</h3>
<p>This is WH-CH510&#8242;s connection request (the earbud&#8217;s request was exactly the same):</p>
<pre>&gt; HCI Event: Connect Request (0x04) plen 10                #11 [hci0] 10.725859
        Address: 30:53:C1:11:40:2D (OUI 30-53-C1)
        Class: 0x240404
          Major class: Audio/Video (headset, speaker, stereo, video, vcr)
          Minor class: Wearable Headset Device
          Rendering (Printing, Speaker)
          Audio (Speaker, Microphone, Headset)
        Link type: ACL (0x01)
&lt; HCI Command: Accept Connection R.. (0x01|0x0009) plen 7  #12 [hci0] 10.725914
        Address: 30:53:C1:11:40:2D (OUI 30-53-C1)
        Role: Master (0x00)</pre>
<p>And after a few packet exchanges, this appears in the dump output (three times, not clear why):</p>
<pre>@ MGMT Event: Device Connected (0x000b) plen 28       {0x0001} [hci0] 11.256871
        BR/EDR Address: 30:53:C1:11:40:2D (OUI 30-53-C1)
        Flags: 0x00000000
        Data length: 15
        Name (complete): WH-CH510
        Class: 0x240404
          Major class: Audio/Video (headset, speaker, stereo, video, vcr)
          Minor class: Wearable Headset Device
          Rendering (Printing, Speaker)
          Audio (Speaker, Microphone, Headset)</pre>
<h3>Cheap earbud&#8217;s service negotiation</h3>
<p>Unlike USB, the device is in control: The requests information, and the host responds. The device chooses how to set up the connection, and the host follows suit. And it&#8217;s also the device that possibly messes up.</p>
<p>For the Y30 earbuds, the attribute request / response session went as follows.</p>
<p>First, the device checks if the host supports Handsfree Audio Gateway (0x111f), by asking for attributes, but the host doesn&#8217;t have any of it:</p>
<pre>&gt; ACL Data RX: Handle 17 flags 0x02 dlen 24                #42 [hci0] 14.317596
      Channel: 64 len 20 [PSM 1 mode 0] {chan 0}
      SDP: Service Search Attribute Request (0x06) tid 1 len 15
        Search pattern: [len 6]
          Sequence (6) with 3 bytes [16 extra bits] len 6
            UUID (3) with 2 bytes [0 extra bits] len 3
              <span class="punch">Handsfree Audio Gateway</span> (0x111f)
        Max record count: 512
        Attribute list: [len 6]
          Sequence (6) with 3 bytes [16 extra bits] len 6
            Unsigned Integer (1) with 2 bytes [0 extra bits] len 3
              0x0004
        Continuation state: 0
&lt; ACL Data TX: Handle 17 flags 0x00 dlen 14                #43 [hci0] 14.317758
      Channel: 64 len 10 [PSM 1 mode 0] {chan 0}
      SDP: Service Search Attribute Response (0x07) tid 1 len 5
        Attribute bytes: 2
        Continuation state: 0</pre>
<p>So the device tries AVDTP (0x0019) instead:</p>
<pre>&gt; ACL Data RX: Handle 17 flags 0x02 dlen 24                #45 [hci0] 14.322578
      Channel: 64 len 20 [PSM 1 mode 0] {chan 0}
      SDP: Service Search Attribute Request (0x06) tid 2 len 15
        Search pattern: [len 6]
          Sequence (6) with 3 bytes [16 extra bits] len 6
            UUID (3) with 2 bytes [0 extra bits] len 3
              <span class="punch">AVDTP (0x0019)</span>
        Max record count: 512
        Attribute list: [len 6]
          Sequence (6) with 3 bytes [16 extra bits] len 6
            Unsigned Integer (1) with 2 bytes [0 extra bits] len 3
              0x0004
        Continuation state: 0
&lt; ACL Data TX: Handle 17 flags 0x00 dlen 60                #46 [hci0] 14.322737
      Channel: 64 len 56 [PSM 1 mode 0] {chan 0}
      SDP: Service Search Attribute Response (0x07) tid 2 len 51
        Attribute bytes: 48
          Attribute list: [len 21] {position 0}
            Attribute: Protocol Descriptor List (0x0004) [len 2]
              Sequence (6) with 6 bytes [8 extra bits] len 8
                UUID (3) with 2 bytes [0 extra bits] len 3
                  L2CAP (0x0100)
                Unsigned Integer (1) with 2 bytes [0 extra bits] len 3
                  0x0019
              Sequence (6) with 6 bytes [8 extra bits] len 8
                UUID (3) with 2 bytes [0 extra bits] len 3
                  <span class="punch">AVDTP</span> (0x0019)
                Unsigned Integer (1) with 2 bytes [0 extra bits] len 3
                  0x0103
          Attribute list: [len 21] {position 1}
            Attribute: Protocol Descriptor List (0x0004) [len 2]
              Sequence (6) with 6 bytes [8 extra bits] len 8
                UUID (3) with 2 bytes [0 extra bits] len 3
                  L2CAP (0x0100)
                Unsigned Integer (1) with 2 bytes [0 extra bits] len 3
                  0x0019
              Sequence (6) with 6 bytes [8 extra bits] len 8
                UUID (3) with 2 bytes [0 extra bits] len 3
                  <span class="punch">AVDTP</span> (0x0019)
                Unsigned Integer (1) with 2 bytes [0 extra bits] len 3
                  0x0103
        Continuation state: 0</pre>
<p>And yes, the host supports it.</p>
<p>AVDTP is (<a rel="noopener" href="https://en.wikipedia.org/wiki/Bluetooth#Audio/Video_Distribution_Transport_Protocol" target="_blank">according to Wikipedia</a>) used by the advanced audio distribution (A2DP) profile to stream music to stereo headsets over an L2CAP channel intended for video distribution profile in the Bluetooth transmission.</p>
<p>So it goes on with connecting channel 65 to service number 0x0019 (PSM stands for Protocol Service Multiplexor).</p>
<pre>&gt; ACL Data RX: Handle 17 flags 0x02 dlen 12                #51 [hci0] 14.358888
      L2CAP: Connection Request (0x02) ident 3 len 4
        <span class="punch">PSM: 25 (0x0019)</span>
        <span class="punch">Source CID: 65</span>
&lt; ACL Data TX: Handle 17 flags 0x00 dlen 16                #52 [hci0] 14.358945
      L2CAP: Connection Response (0x03) ident 3 len 8
        Destination CID: 65
        Source CID: 65
        Result: Connection pending (0x0001)
        Status: Authorization pending (0x0002)
&lt; ACL Data TX: Handle 17 flags 0x00 dlen 16                #53 [hci0] 14.359202
      L2CAP: Connection Response (0x03) ident 3 len 8
        Destination CID: 65
        Source CID: 65
        Result: Connection successful (0x0000)
        Status: No further information available (0x0000)
&lt; ACL Data TX: Handle 17 flags 0x00 dlen 12                #54 [hci0] 14.359220
      L2CAP: Configure Request (0x04) ident 3 len 4
        Destination CID: 65
        Flags: 0x0000
AVDTP (0x0019)&gt; HCI Event: Number of Completed Packets (0x13) plen 5     #55 [hci0] 14.361709
        Num handles: 1
        Handle: 17
        Count: 1</pre>
<p>This is followed by a discovery phase:</p>
<pre>@ MGMT Command: Start Discovery (0x0023) plen 1       {0x0001} [hci0] 14.362330
        Address type: 0x07
          BR/EDR
          LE Public
          LE Random</pre>
<p>In the packet exchange that follows, the device obtains the capabilities of the host, and the audio connection is set up.</p>
<h3>Sony WH-CH510&#8242;s service negotiation</h3>
<p>The WH-CH510 takes another approach: It issues a Service Search Request for the Headset AG (0x1112). AG means Audio Gateway.</p>
<pre>&gt; ACL Data RX: Handle 20 flags 0x02 dlen 17                #48 [hci0] 11.736388
      Channel: 64 len 13 [PSM 1 mode 0] {chan 0}
      SDP: Service Search Request (0x02) tid 1 len 8
        Search pattern: [len 5]
          Sequence (6) with 3 bytes [8 extra bits] len 5
            UUID (3) with 2 bytes [0 extra bits] len 3
              <span class="punch">Headset AG (0x1112)</span>
        Max record count: 68
        Continuation state: 0
&lt; ACL Data TX: Handle 20 flags 0x00 dlen 18                #49 [hci0] 11.736611
      Channel: 64 len 14 [PSM 1 mode 0] {chan 0}
      SDP: Service Search Response (0x03) tid 1 len 9
        Total record count: 1
        Current record count: 1
        Record handle: <span class="punch">0x1000c</span>
        Continuation state: 0</pre>
<p>And yes, it&#8217;s supported and given the handle 0x1000c. Using this handle, the device asks for this service&#8217;s attributes:</p>
<pre>&gt; ACL Data RX: Handle 20 flags 0x02 dlen 23                #51 [hci0] 11.741392
      Channel: 64 len 19 [PSM 1 mode 0] {chan 0}
      SDP: Service Attribute Request (0x04) tid 2 len 14
        Record handle: <span class="punch">0x1000c</span>
        Max attribute bytes: 277
        Attribute list: [len 7]
          Sequence (6) with 5 bytes [8 extra bits] len 7
            Unsigned Integer (1) with 4 bytes [0 extra bits] len 5
              0x0000ffff
        Continuation state: 0
&lt; ACL Data TX: Handle 20 flags 0x00 dlen 97                #52 [hci0] 11.741610
      Channel: 64 len 93 [PSM 1 mode 0] {chan 0}
      SDP: Service Attribute Response (0x05) tid 2 len 88
        Attribute bytes: 85
          Attribute list: [len 83] {position 0}
            Attribute: Service Record Handle (0x0000) [len 2]
              0x0001000c
            Attribute: Service Class ID List (0x0001) [len 2]
              UUID (3) with 2 bytes [0 extra bits] len 3
                Headset AG (0x1112)
              UUID (3) with 2 bytes [0 extra bits] len 3
                Generic Audio (0x1203)
            Attribute: Protocol Descriptor List (0x0004) [len 2]
              Sequence (6) with 3 bytes [8 extra bits] len 5
                UUID (3) with 2 bytes [0 extra bits] len 3
                  L2CAP (0x0100)
              Sequence (6) with 5 bytes [8 extra bits] len 7
                UUID (3) with 2 bytes [0 extra bits] len 3
                  <span class="punch">RFCOMM (0x0003)</span>
                Unsigned Integer (1) with 1 byte [0 extra bits] len 2
                  0x0c
            Attribute: Browse Group List (0x0005) [len 2]
              UUID (3) with 2 bytes [0 extra bits] len 3
                Public Browse Root (0x1002)
            Attribute: Bluetooth Profile Descriptor List (0x0009) [len 2]
              Sequence (6) with 6 bytes [8 extra bits] len 8
                UUID (3) with 2 bytes [0 extra bits] len 3
                  Headset (0x1108)
                Unsigned Integer (1) with 2 bytes [0 extra bits] len 3
                  0x0102
            Attribute: Unknown (0x0100) [len 2]
              Headset Voice gateway [len 21]
        Continuation state: 0</pre>
<p>The device chooses to connect channel 65 to the RFCOMM service:</p>
<pre>&gt; ACL Data RX: Handle 20 flags 0x02 dlen 12                #62 [hci0] 12.337691
      L2CAP: Connection Request (0x02) ident 6 len 4
<span class="punch">        PSM: 3 (0x0003)
        Source CID: 65
</span>&lt; ACL Data TX: Handle 20 flags 0x00 dlen 16                #63 [hci0] 12.337747
      L2CAP: Connection Response (0x03) ident 6 len 8
        Destination CID: 64
        Source CID: 65
        Result: Connection successful (0x0000)
        Status: No further information available (0x0000)</pre>
<p>After some configuration packets, the discovery begins:</p>
<pre>@ MGMT Event: Discovering (0x0013) plen 2             {0x0001} [hci0] 14.686897
        Address type: 0x07
          BR/EDR
          LE Public
          LE Random
        Discovery: Disabled (0x00)
&gt; ACL Data RX: Handle 20 flags 0x02 dlen 18                #91 [hci0] 15.848944
      Channel: 64 len 14 [PSM 3 mode 0] {chan 0}
      RFCOMM: Unnumbered Info with Header Check (UIH) (0xef)
         Address: 0x63 cr 1 dlci 0x18
         Control: 0xef poll/final 0
         Length: 10
         FCS: 0x0e
        41 54 2b 43 49 4e 44 3d 3f 0d 0e                 <span class="punch">AT+CIND=?</span>..
&gt; ACL Data RX: Handle 20 flags 0x02 dlen 17                #92 [hci0] 18.849015
      Channel: 64 len 13 [PSM 3 mode 0] {chan 0}
      RFCOMM: Unnumbered Info with Header Check (UIH) (0xef)
         Address: 0x63 cr 1 dlci 0x18
         Control: 0xef poll/final 0
         Length: 9
         FCS: 0x0e
        41 54 2b 43 49 4e 44 3f 0d 0e                    AT+CIND?..</pre>
<p>This discovery isn&#8217;t all that successful: The device sends AT commands, but the host doesn&#8217;t respond to them. 4 seconds of futile attempts.</p>
<p>After some useless back and forth, the device tries again with the same Service Search Request, to which it receives the same answer, and so it goes on.</p>
<pre>&gt; ACL Data RX: Handle 20 flags 0x02 dlen 17               #108 [hci0] 20.717682
      Channel: 65 len 13 [PSM 1 mode 0] {chan 1}
      SDP: Service Search Request (0x02) tid 3 len 8
        Search pattern: [len 5]
          Sequence (6) with 3 bytes [8 extra bits] len 5
            UUID (3) with 2 bytes [0 extra bits] len 3
              Headset AG (0x1112)
        Max record count: 68
        Continuation state: 0

<span class="yadayada">[ ... ]</span></pre>
<p>The device disconnects the futile channel 65:</p>
<pre>&gt; ACL Data RX: Handle 20 flags 0x02 dlen 12               #114 [hci0] 20.818859
      L2CAP: Disconnection Request (0x06) ident 10 len 4
        Destination CID: 65
        Source CID: 64
&lt; ACL Data TX: Handle 20 flags 0x00 dlen 12               #115 [hci0] 20.818906
      L2CAP: Disconnection Response (0x07) ident 10 len 4
        Destination CID: 65
        Source CID: 64</pre>
<p>And then it tries another few AT commands on this same channel, despite having disconnected it. It didn&#8217;t reconnect it, so probably disconnection doesn&#8217;t mean what I think it does&#8230;?</p>
<pre>&gt; ACL Data RX: Handle 20 flags 0x02 dlen 24               #118 [hci0] 22.225305
      Channel: 64 len 20 [PSM 3 mode 0] {chan 0}
      RFCOMM: Unnumbered Info with Header Check (UIH) (0xef)
         Address: 0x63 cr 1 dlci 0x18
         Control: 0xef poll/final 0
         Length: 16
         FCS: 0x0e
        41 54 2b 43 4d 45 52 3d 33 2c 30 2c 30 2c 31 0d  AT+CMER=3,0,0,1.
        0e                                               .
&gt; ACL Data RX: Handle 20 flags 0x02 dlen 18               #119 [hci0] 25.285306
      Channel: 64 len 14 [PSM 3 mode 0] {chan 0}
      RFCOMM: Unnumbered Info with Header Check (UIH) (0xef)
         Address: 0x63 cr 1 dlci 0x18
         Control: 0xef poll/final 0
         Length: 10
         FCS: 0x0e
        41 54 2b 43 43 57 41 3d 31 0d 0e                 AT+CCWA=1..</pre>
<p>Needless to say, this was futile as well.</p>
<p>And then, out of the blue, the device requests to connect to AVDTP by choosing the service at address 0x0019.</p>
<pre>&gt; ACL Data RX: Handle 20 flags 0x02 dlen 12               #125 [hci0] 29.875346
      L2CAP: Connection Request (0x02) ident 11 len 4
<span class="punch">        PSM: 25 (0x0019)</span>
        Source CID: 64
&lt; ACL Data TX: Handle 20 flags 0x00 dlen 16               #126 [hci0] 29.875431
      L2CAP: Connection Response (0x03) ident 11 len 8
        Destination CID: 65
        Source CID: 64
        Result: Connection pending (0x0001)
        Status: Authorization pending (0x0002)
&lt; ACL Data TX: Handle 20 flags 0x00 dlen 16               #128 [hci0] 29.875677
      L2CAP: Connection Response (0x03) ident 11 len 8
        Destination CID: 65
        Source CID: 64
        Result: Connection successful (0x0000)
        Status: No further information available (0x0000)</pre>
<p>It&#8217;s not clear where the device got the idea to do this: As far as I can tell, the device wasn&#8217;t informed by the host about the existence of this service, at least not directly.</p>
<p>From this point, the negotiation goes well, and an audio device is set up. This allows selecting the headphones in the Sound Settings. Something that is done automatically with the old headphones and the junky earbuds.</p>
<p>So what is the problem? Maybe that the host doesn&#8217;t answer the AT commands. This is maybe solved in later versions of bluetoothd or Linux distributions in general. It&#8217;s quite possible that my distribution is too old for these newer headphones. Upgrade or perish.</p>
<p>Or go the other way: Downgrade. I suppose the solution would be to disable the Headset AG profile (0x1112), so that bluetoothd refuses to play ball when this is requested. This would speed up the fallback to A2DP, I hope, and possibly solve the problem.</p>
<p>I&#8217;ve tried hard to find a way to make bluetoothd refuse to the Headset AG profile, but in vain (so far?). sdptool has the option to disable a service, however it&#8217;s deprecated, and bluez 5 won&#8217;t talk with it. The updated method to tickle bluetoothd is through Dbus. Not sure if it has an API for turning off a service.</p>
<p>Unfortunately, I have no idea how to do this except for compiling bluetoothd from its sources and remove that option altogether. Actually, changing the UUID is enough to make it unusable.</p>
<p>I tried that, but it didn&#8217;t work all that well. More on that below.</p>
<p>Now to some extra stuff I randomly found out while working on this.</p>
<h3>bluetootctl</h3>
<p>This utility talks with bluetoothd through Dbus.</p>
<p>Doesn&#8217;t require root (when run from a terminal window on the computer&#8217;s desktop):</p>
<pre>$ bluetoothctl
[NEW] Controller 9C:BB:CC:DD:EE:FF compname [default]
[NEW] Device 78:2E:D4:D9:62:C1 Y30
[NEW] Device 00:18:09:76:27:29 WH-CH500
[NEW] Device 30:53:C1:11:40:2D WH-CH510
Agent registered
[bluetooth]# show
Controller 9C:BB:CC:DD:EE:FF (public)
	Name: compname
	Alias: compname
	Class: 0x001c0104
	Powered: yes
	Discoverable: yes
	Pairable: yes
	UUID: Headset AG                (00001112-0000-1000-8000-00805f9b34fb)
	UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
	UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
	UUID: OBEX File Transfer        (00001106-0000-1000-8000-00805f9b34fb)
	UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
	UUID: OBEX Object Push          (00001105-0000-1000-8000-00805f9b34fb)
	UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
	UUID: IrMC Sync                 (00001104-0000-1000-8000-00805f9b34fb)
	UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
	UUID: Audio Source              (0000110a-0000-1000-8000-00805f9b34fb)
	UUID: Audio Sink                (0000110b-0000-1000-8000-00805f9b34fb)
	UUID: Vendor specific           (00005005-0000-1000-8000-0002ee000001)
	UUID: Message Notification Se.. (00001133-0000-1000-8000-00805f9b34fb)
	UUID: Phonebook Access Server   (0000112f-0000-1000-8000-00805f9b34fb)
	UUID: Message Access Server     (00001132-0000-1000-8000-00805f9b34fb)
	UUID: Headset                   (00001108-0000-1000-8000-00805f9b34fb)
	Modalias: usb:v1D6Bp0246d0530
	Discovering: no</pre>
<p>This utility spits out a lot of information by itself when the daemon is restarted with e.g. &#8220;systemctl restart bluetooth&#8221;. There&#8217;s also output when a device is connected and disconnected.</p>
<p>An interesting feature of bluetootctl is the submenus, in particular &#8220;gatt&#8221; and &#8220;advertise&#8221;. Maybe the former allows deregistering UUIDs.</p>
<p>Try</p>
<pre>[bluetooth]# menu gatt</pre>
<p>and when done, go back to original menu:</p>
<pre>[bluetooth]# back</pre>
<h3>btmgmt</h3>
<p>btmgmt talks with the kernel directly through an AF_BLUETOOTH raw network socket. I considered this tool because it has the rm-uuid command, which is supposed to remove a UUID.</p>
<pre>$ sudo btmgmt
[mgmt]# rm-uuid 00001112-0000-1000-8000-00805f9b34fb
Remove UUID succeeded. Class 0x1c0104</pre>
<p>This is reverted when the bluetooth service is restarted. But it doesn&#8217;t seem to have any effect on the interface anyhow. The UUID keeps appearing in bluetoothctl&#8217;s &#8220;show&#8221; and the service is advertised and used. &#8220;clr-uuids&#8221; apparently removes all UUIDs, but this has no real effect.</p>
<p>It seems like the effective UUIDs are kept in bluetoothd. btmgmt changes the UUIDs in the kernel. See &#8220;Remove UUID Command&#8221; in <a rel="noopener" href="https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/mgmt-api.txt" target="_blank">mgmt-api.txt</a>.</p>
<p>btmgmt also gets very active when bluetoothd is restarted and other events occur.</p>
<h3>Talking with bluetoothd directly through DBus</h3>
<p>See my notes on DBus on <a title="systemd / DBus debugging starter pack" href="https://billauer.se/blog/2019/05/dbus-dump-systemd-debugging/" target="_blank">this post</a>. Getting a property:</p>
<pre>$ <strong>dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0 org.freedesktop.DBus.Properties.Get string:org.bluez.Adapter1 string:Address</strong>
method return time=1685778877.065819 sender=:1.4 -&gt; destination=:1.4934 serial=82 reply_serial=2
   variant       string "9C:BB:CC:DD:EE:FF"</pre>
<p>Let&#8217;s break this down. Bluetoothd&#8217; Dbus API is published in its source&#8217;s <a rel="noopener" href="https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/" target="_blank">doc/ subdirectory</a>. The Address property of the adapter is documented in <a rel="noopener" href="https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt" target="_blank">adapter-api.txt</a>. So:</p>
<ul>
<li>&#8211;print-reply: We want the reply to this query, of course.</li>
<li>&#8211;system: Bluetoothd is connected to the system DBus.</li>
<li>&#8211;dest=org.bluez: Taken from &#8220;Service&#8221; in adapter-api.txt.</li>
<li>/org/bluez/hci0: Taken from &#8220;Object path&#8221; in adapter-api.txt.</li>
<li>org.freedesktop.DBus.Properties.Get: Every dbus-send command needs a method. In this case fetching a property&#8217;s value. So use the generic method for fetching a property.</li>
<li>string:org.bluez.Adapter1: Taken from &#8220;Interface&#8221; in adapter-api.txt.</li>
<li>string:Address: This is the name of the property, as listed in adapter-api.txt.</li>
</ul>
<p>Likewise, I can fetch the UUIDs:</p>
<pre>$ <strong>dbus-send --print-reply --system --dest=org.bluez /org/bluez/hci0 org.freedesktop.DBus.Properties.Get string:org.bluez.Adapter1 string:UUIDs</strong>
method return time=1685779625.693856 sender=:1.4 -&gt; destination=:1.5017 serial=89 reply_serial=2
   variant       array [
         string "00001112-0000-1000-8000-00805f9b34fb"
         string "00001801-0000-1000-8000-00805f9b34fb"
         string "0000110e-0000-1000-8000-00805f9b34fb"
         string "00001106-0000-1000-8000-00805f9b34fb"
         string "00001800-0000-1000-8000-00805f9b34fb"
         string "00001105-0000-1000-8000-00805f9b34fb"
         string "00001200-0000-1000-8000-00805f9b34fb"
         string "0000110c-0000-1000-8000-00805f9b34fb"
         string "00001104-0000-1000-8000-00805f9b34fb"
         string "0000110a-0000-1000-8000-00805f9b34fb"
         string "0000110b-0000-1000-8000-00805f9b34fb"
         string "00005005-0000-1000-8000-0002ee000001"
         string "00001133-0000-1000-8000-00805f9b34fb"
         string "0000112f-0000-1000-8000-00805f9b34fb"
         string "00001132-0000-1000-8000-00805f9b34fb"
         string "00001108-0000-1000-8000-00805f9b34fb"
      ]</pre>
<p>So this is how bluetoothctl got these values. Unfortunately, this property is read-only according to adapter-api.txt, so it can&#8217;t be manipulated with a Set method.</p>
<p>It&#8217;s of course possible to run methods that are published in bluetoothd&#8217;s DBus API, but I didn&#8217;t find anything related to disabling services.</p>
<h3>Hacking the source</h3>
<p>Download the <a rel="noopener" href="https://launchpad.net/ubuntu/+source/bluez/5.48-0ubuntu3.1" target="_blank">sources</a> for bluez 5.48-0ubuntu3.1 as <a rel="noopener" href="https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/bluez/5.48-0ubuntu3.1/bluez_5.48.orig.tar.xz" target="_blank">bluez_5.48.orig.tar.xz</a> (which is the version running on Mint 19).</p>
<p>In lib/sdp.h, change 0x1112 to 0xeb12. Same in lib/uuid.h and in src/profile.c.</p>
<p>Then in the source&#8217;s root directory, go:</p>
<pre>$ ./configure &amp;&amp; echo Success</pre>
<p>and then just</p>
<pre>$ make &amp;&amp; echo Success</pre>
<p>On my machine, there was a need to install libical, to make configure work, i.e.</p>
<pre>$ sudo apt-get install libical-dev</pre>
<p>And then replace /usr/lib/bluetooth/bluetoothd with the compiled version in src/. Keep a copy of the old executable, of course.</p>
<p>That didn&#8217;t work at all. The old UUID kept appearing in bluetoothctl&#8217;s output for &#8220;show&#8221;. There was a change, however: The WH-CH510 headphones refused to connect to the host, and reverted to pairing. At least I did something, I thought. But as it turned out, these headphones refused to connect to the host even after going back to the original bluetooth daemon (but had no problem with my cellphone). Y30 had no problems, as usual.</p>
<p>Resetting the headphone by pressing the power button and &#8220;-&#8221; button for 7 seconds didn&#8217;t help either. What eventually did the trick was to remove /usr/lib/bluetooth/bluetoothd, go &#8220;systemctl restart bluetooth&#8221;, which failed of course. Then return bluetoothd to its place, which worked, as expected. And then everything was back to normal again.</p>
<h3>Extra reading</h3>
<ul>
<li>A <a rel="noopener" href="https://wiki.debian.org/BluetoothUser" target="_blank">Debian wiki page</a> with several interesting examples (in particular how to use dbus-send to talk with bluetoothd)</li>
<li><a rel="noopener" href="http://trac.gateworks.com/wiki/wireless/bluetooth" target="_blank">This page</a> contains a lot of information about using command line</li>
<li>The <a rel="noopener" href="https://www.kali.org/tools/bluez/" target="_blank">list of tools</a> that come with the bluez package</li>
<li><a rel="noopener" href="https://pythonhosted.org/BT-Manager/config.html" target="_blank">Some information</a> about configuration files.</li>
</ul>
<h3>Random jots</h3>
<ul>
<li>The bluetooth service is defined in /lib/systemd/system/bluetooth.service, which runs /usr/lib/bluetooth/bluetoothd.</li>
<li>It&#8217;s also possible to run the daemon directly, by typing &#8220;/usr/lib/bluetooth/bluetoothd&#8221; at shell prompt. The daemon runs in the foreground in this case. Add the &#8220;-n&#8221; flag to get the logging information on the console as well.</li>
<li>bluetoothd stores persistent information (the list and information about already discovered devices in particular) in /var/lib/bluetooth. This directory can be removed</li>
</ul>
<p>It&#8217;s possible to stop the Bluetooth daemon with</p>
<pre># systemctl stop bluetooth</pre>
<p>however clicking on desktop&#8217;s bluetooth applet restarts it automatically, unless it is running by other means (e.g. started manually with a command).</p>
<p>The &#8220;bluetoothctl&#8221; command won&#8217;t do this, but rather wait for a connection. It&#8217;s actually OK to turn off the bluetooth deamon while this utility is running.</p>
<p>After upgrading bluetoothd as mentioned above, I noticed a lot of log messages of this sort every 16 seconds or so:</p>
<pre>kernel: Bluetooth: hci0: last event is not cmd complete (0x0f)</pre>
<p>But looking at old logs, it&#8217;s evident that these existed in the past as well. So they&#8217;re not related to my manipulations with the Bluetooth daemon. In fact, these messages appear while the Cinnamon Bluetooth applet&#8217;s utility window is displayed. Close this window, and the messages stop. This is a <a rel="noopener" href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1748565" target="_blank">kernel bug</a> that <a rel="noopener" href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1629db9c75342325868243d6bca5853017d91cf8" target="_blank">was fixed</a> in kernel v5.0.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2023/06/bluetoothd-sniffing-dbus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux: Atheros QCA6174&#8242;s Bluetooth disappearing after reboot</title>
		<link>https://billauer.se/blog/2019/07/qualcomm-atheros-qca6174-bluetooth/</link>
		<comments>https://billauer.se/blog/2019/07/qualcomm-atheros-qca6174-bluetooth/#comments</comments>
		<pubDate>Sun, 21 Jul 2019 10:26:17 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[bluetooth]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Linux kernel]]></category>
		<category><![CDATA[USB]]></category>
		<category><![CDATA[wifi]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=5773</guid>
		<description><![CDATA[When Bluetooth goes poof Having rebooted my computer after a few months of continuous operation, I suddenly failed to use my Bluetooth headphones. It took some time to figure out that the problem wasn&#8217;t with the Cinnamon 3.8.9 fancy stuff, nor the DBus interface, which produced error messages. There was simply no Bluetooth device in [...]]]></description>
			<content:encoded><![CDATA[<h3>When Bluetooth goes poof</h3>
<p>Having rebooted my computer after a few months of continuous operation, I suddenly failed to use my Bluetooth headphones. It took some time to figure out that the problem wasn&#8217;t with the Cinnamon 3.8.9 fancy stuff, nor the DBus interface, which produced error messages. There was simply no Bluetooth device in the system to talk to.</p>
<p>Prior to this mishap, my Atheros QCA6174 had worked flawlessly and reliably for several months, both as a Wifi adapter and a Bluetooth adapter.</p>
<p>For the record, I have a Linux Mint 19 Tara machine with 4.15.0-20-generic kernel on a X299 AORUS Gaming 7 motherboard, running in 64 bit mode of course.</p>
<p>I&#8217;ll jump to the spoiler: If you happen to have a Qualcomm Atheros QCA6174 802.11ac Wireless Network Adapter on your machine, never just reboot the machine: Shut down the computer completely, and disconnect main power for a minute or so with the power supply&#8217;s switch. Just powering off the computer the fine way isn&#8217;t enough. The device probably continues to get power from the motherboard when in computer is off by virtue of its own power control.</p>
<p>Powering off the computer this way is what solved it for me. However there are also some rumors on the web, which I can&#8217;t confirm, about Bluetooth coming back to life after loading Windows on the same computer. Or turning Bluetooth off and on again with the BIOS. My guess is that due to a bug, the chip sometimes needs some kind of tickle on shutdown or when starting, or Bluetooth is lost. Something that is worked around with a hush-hush fix in the driver for Windows,  but the Linux driver doesn&#8217;t do the same.</p>
<p>This post goes down to the gory details, partly for the sake of quick diagnostics in the future, and partly because Bluetooth tends to be a mystery thing. So I&#8217;m trying to give an idea on what&#8217;s going on.</p>
<h3>Why it&#8217;s confusing</h3>
<p>Here&#8217;s the thing: The Qualcomm QCA6174 connects to the motherboard as a PCIe device as a Wifi adapter, and to the USB bus as a Bluetooth device. Sounds weird, but that&#8217;s the way it is. Bluetooth has been wonky for 20 years, and that&#8217;s probably its destiny.</p>
<p>So there are wires going from the QCA6174 to the PCIe bus and other wires from the same device going to one of the ports of the motherboard&#8217;s USB root hub (see details below). On my specific motherboard, the Bluetooth interface of the QCA6174 is connected to port 13 of the root hub, that facilitates the motherboard&#8217;s physical USB connector at the back of the computer. So while designing the board, they wired some of the D+/D- wires to the physical ports at the back, and a couple of those go to the QCA6174. I&#8217;m saying this over and over again, because it&#8217;s so counterintuitive.</p>
<p>Counterintuituve, but it seems like it&#8217;s quite common. Intel&#8217;s AC 7260 Wifi / Bluetooth combo seems to do exactly the same thing.</p>
<p>As a PCIe device, QCA6174 has Vendor / Product IDs 168c:003e. As as USB device, it&#8217;s 0cf3:e300. Confusing? It won&#8217;t surprise me if the Wifi and Bluetooth interfaces are two independent units on the same chip, that happen to share an antenna.</p>
<p>Apparently, when the QCA6174 has a bad day, the PCIe interface wakes up properly, and USB doesn&#8217;t. The result is that the Wifi works fine, but the Bluetooth is absent.</p>
<p>To add some confusion,  the kernel source&#8217;s drivers/net/wireless/ath/ath10k/usb.c matches USB device 13b1:0042,  which is indeed a Linksys device (the comment in the code says Linksys  WUSB6100M). Not clear why it&#8217;s there.</p>
<p>On the other hand, drivers/bluetooth/btusb.c, matches a  whole range of Atheros USB devices, among others 0cf3:e300, calling it  &#8220;QCA ROME&#8221; in the comments. So it&#8217;s the btusb module that takes care of QCA6174&#8242;s Bluetooth interface, not anything in ath/ath10k. Cute, isn&#8217;t it?</p>
<h3>What it looks like when it works</h3>
<p>When trying to figure out what&#8217;s wrong, it helps knowing that it looks like when it&#8217;s OK. So below is a lot of info that was collected when I got the Bluetooth up and running.</p>
<p>When it failed, everything looked exactly the same in relation to the device&#8217;s PCIe interface, but there was absolutely nothing related to USB and Bluetooth: No entry for the device in lsusb, hcicontrol nor rfkill, as shown below.</p>
<p>Kernel log output on behalf of the device, as connected to the PCIe bus. Note that the exact same logs appeared when the Bluetooth device was absent. Exactly-exactly. Down to the single character, I&#8217;ve compared them. So this isn&#8217;t really relevant, but anyhow:</p>
<pre>[    0.126428] pci 0000:03:00.0: [168c:003e] type 00 class 0x028000
[    0.126456] pci 0000:03:00.0: reg 0x10: [mem 0x92800000-0x929fffff 64bit]
[    0.126555] pci 0000:03:00.0: PME# supported from D0 D3hot D3cold

<span style="color: #888888;"><em>[ ... ]</em></span>

[   17.616738] ath10k_pci 0000:03:00.0: enabling device (0000 -&gt; 0002)
[   17.617514] ath10k_pci 0000:03:00.0: pci irq msi oper_irq_mode 2 irq_mode 0 reset_mode 0

<span style="color: #888888;"><em>[ ... ]</em></span>

[   17.915091] ath10k_pci 0000:03:00.0: Direct firmware load for ath10k/pre-cal-pci-0000:03:00.0.bin failed with error -2
[   17.915109] ath10k_pci 0000:03:00.0: Direct firmware load for ath10k/cal-pci-0000:03:00.0.bin failed with error -2
[   17.926172] ath10k_pci 0000:03:00.0: qca6174 hw3.2 target 0x05030000 chip_id 0x00340aff sub 1a56:1535
[   17.926173] ath10k_pci 0000:03:00.0: kconfig debug 0 debugfs 1 tracing 1 dfs 0 testmode 0
[   17.926505] ath10k_pci 0000:03:00.0: firmware ver WLAN.RM.4.4.1-00124-QCARMSWPZ-1 api 6 features wowlan,ignore-otp crc32 d8fe1bac
[   18.078191] ath10k_pci 0000:03:00.0: board_file api 2 bmi_id N/A crc32 506ce037

<span style="color: #888888;"><em>[ ... ]</em></span>

[   18.642461] ath10k_pci 0000:03:00.0: Unknown eventid: 3
[   18.658195] ath10k_pci 0000:03:00.0: Unknown eventid: 118809
[   18.661096] ath10k_pci 0000:03:00.0: Unknown eventid: 90118
[   18.661772] ath10k_pci 0000:03:00.0: htt-ver 3.56 wmi-op 4 htt-op 3 cal otp max-sta 32 raw 0 hwcrypto 1</pre>
<p>Note that two attempts to load firmware failed, but apparently the third went OK. Don&#8217;t let these error messages mislead you: The kernel messages in this respect were the same when the Bluetooth appeared and when it didn&#8217;t.</p>
<p>The &#8220;Unknown eventid&#8221; may appear more than once.</p>
<p>Its entry with plain lspci (unrelated entries removed):</p>
<pre>$ lspci
03:00.0 Network controller: Qualcomm Atheros QCA6174 802.11ac Wireless Network Adapter (rev 32)</pre>
<p>And now to the parts that were missing completely when the Bluetooth device didn&#8217;t appear: The logs on behalf of the device, connected to the USB bus:</p>
<pre>[    3.764868] usb 1-13: new full-speed USB device number 12 using xhci_hcd
[    3.913930] usb 1-13: New USB device found, idVendor=0cf3, idProduct=e300
[    3.915610] usb 1-13: New USB device strings: Mfr=0, Product=0, SerialNumber=0</pre>
<p>Plain lsusb:</p>
<pre>$ lsusb
<em>[ ... ]</em>
Bus 001 Device 012: ID 0cf3:e300 Atheros Communications, Inc.
<em>[ ... ]</em></pre>
<p>lsusb, tree view (a lot of irrelevant stuff excluded):</p>
<pre>$ lsusb -t
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/16p, 480M
    |__ Port 13: Dev 12, If 1, Class=Wireless, Driver=btusb, 12M
    |__ Port 13: Dev 12, If 0, Class=Wireless, Driver=btusb, 12M</pre>
<p>More in detail for the device:</p>
<pre># lsusb -v -d 0cf3:e300

Bus 001 Device 012: ID 0cf3:e300 Atheros Communications, Inc.
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.01
  bDeviceClass          224 Wireless
  bDeviceSubClass         1 Radio Frequency
  bDeviceProtocol         1 Bluetooth
  bMaxPacketSize0        64
  idVendor           0x0cf3 Atheros Communications, Inc.
  idProduct          0xe300
<em><span style="color: #888888;">[ ... ]</span></em></pre>
<p>Several modules appear in lsmod, but the point is that there are  dependencies on bluetooth module, in particular the btusb module.  Irrelevant modules deleted from list below:</p>
<pre>$ lsusb
rfcomm                 77824  16
bnep                   20480  2
btusb                  45056  0
btrtl                  16384  1 btusb
btbcm                  16384  1 btusb
btintel                16384  1 btusb
bluetooth             548864  43 btrtl,btintel,bnep,btbcm,rfcomm,btusb</pre>
<h3>How to check if a Bluetooth device is present</h3>
<p>There is no device file for Bluetooth interface, exactly as there&#8217;s none for network. Like there&#8217;s eth0 for Ethernet, there&#8217;s hci0 for Bluetooth.</p>
<p>hcicontrol grabs the info by opening a socket. As in the relevant strace:</p>
<pre>socket(PF_BLUETOOTH, SOCK_RAW, 1)</pre>
<p>So this is what it looked like with the Bluetooth device present (without it, hciconfig simply prints nothing):</p>
<pre>$ hciconfig
hci0:	Type: Primary  Bus: USB
	BD Address: xx:xx:xx:xx:xx:xx  ACL MTU: 1024:8  SCO MTU: 50:8
	UP RUNNING PSCAN ISCAN
	RX bytes:1386 acl:0 sco:0 events:94 errors:0
	TX bytes:5494 acl:0 sco:0 commands:94 errors:0</pre>
<p>Real hex numbers appear instead of the xx&#8217;s above. Use hciconfig -a for more verbose output.</p>
<p>And the device appears in the rfkill list, and shouldn&#8217;t be blocked.</p>
<pre>$ rfkill list
0: hci0: Bluetooth
	Soft blocked: no
	Hard blocked: no
1: phy0: Wireless LAN
	Soft blocked: no
	Hard blocked: no</pre>
<p>These two show that the kernel supplies a Bluetooth device to the higher software levels. If Bluetooth doesn&#8217;t work, there are other reasons&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2019/07/qualcomm-atheros-qca6174-bluetooth/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Pairing a mobile phone with VW RCD 510 / Kufatec Fiscon car radio</title>
		<link>https://billauer.se/blog/2016/03/vw-mk6-bluetooth-pairing/</link>
		<comments>https://billauer.se/blog/2016/03/vw-mk6-bluetooth-pairing/#comments</comments>
		<pubDate>Sat, 26 Mar 2016 13:47:19 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[bluetooth]]></category>
		<category><![CDATA[miscellaneous]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=4960</guid>
		<description><![CDATA[I struggled with this a bit, and ended up doing it right by guessing. Even though I should have read the manual to begin with. So the procedure is simple (cited from manual, page 7, &#8220;Pairing&#8221;): Turn the ignition on. Make sure the Bluetooth feature of your phone is turned on. Start the pairing procedure [...]]]></description>
			<content:encoded><![CDATA[<p>I struggled with this a bit, and ended up doing it right by guessing. Even though I <a href="http://www.oemretrofits.co.uk/manuals/fiscon_vw_en.pdf" target="_blank">should have read the manual</a> to begin with.</p>
<p>So the procedure is simple (cited from manual, page 7, &#8220;Pairing&#8221;):</p>
<ol>
<li>Turn the ignition on.</li>
<li>Make sure the Bluetooth feature of your phone is turned on.</li>
<li>Start the pairing procedure on your mobile phone.</li>
<li>When prompted for a passkey, enter <strong>1234</strong> on your mobile phone</li>
</ol>
<p>The crucial hint is that nothing is expected to happen in the &#8220;Phone&#8221; any setup menu, as shown in many video tutorials.</p>
<p>So on an Android phone, open Settings &gt; Bluetooth and make it search for devices. Once it finds it, enter the 1234 passcode (it&#8217;s was actually suggested, that and 0000. So it was 1234). Don&#8217;t expect anything to happen on the car radio&#8217;s side nor the dashboard display until the phone is paired.</p>
<p>I managed to pair two phones (the manual says there are up to five allowed).</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2016/03/vw-mk6-bluetooth-pairing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
