Connect to bluetooth device from command line

Background: I'm using my bluetooth headset as audio output. I managed to get it working by the long list of instructions on BluetoothHeadset community documentation, and I have automated the process of activating the headset as default audio output into a script, thanks to another question.

However, since I use the bluetooth headset with both my phone and computer (and the headset doesn't support two input connections) in order for the phone not to "steal" the connection when handset is turned on, I force the headset into a discovery mode when connecting to the computer (phone gets to connect to it automatically).

So even though the headset is paired ok and would in "normal" scenario autoconnect, I have to always use the little bluetooth icon in the notification area to actually connect to my device (see screenshot).

What I want to avoid: This GUI for connecting to a known and paired bluetooth device:

Connecting to Bluetooth headset using icon

What I want instead: I'd want to make the bluetooth do exactly what the clicking the connect item in the GUI does, only by using command line. I want to use command line so I can make a single keypress shortcut for the action, and would't need to navigate the GUI every time I want to establish a connection to the device.

The question: How can I attempt to connect to a specific, known and paired bluetooth device from command line?

Further question: How do I tell if the connection was successful or not?


Bluetooth daemon

In the default installation a daemon (bluetoothd) runs in the background (run from the file /etc/init.d/bluetooth). This daemon takes care on recognizing and connecting to known bluetooth devices and may be cofigured with configuration files in /etc/bluetooth. For autoconneting a headset the following line in audio.conf should be uncommented (remove #):

AutoConnect=true

To restart the daemon type sudo /etc/init.d/bluetooth restart.

Remark: Using the command line tool sudo hcitool cc <MAC-Adress> did not lead to a stable connection to a known device in the test environment here when the daemon was running.


DBus

In order to connect a disconnected but physically present and paired headset we can use D-Bus from a script. Here's an example in python:

#!/usr/bin/python
# Toggles headset connection

import dbus
from dbus.mainloop.glib import DBusGMainLoop

dbus_loop = DBusGMainLoop()
bus = dbus.SystemBus(mainloop=dbus_loop)

#Get dbus interface for headset
manager = bus.get_object('org.bluez', '/')
iface_m = dbus.Interface(manager, 'org.bluez.Manager')
adapterPath = iface_m.DefaultAdapter()
adapter = bus.get_object('org.bluez', adapterPath)
iface_a = dbus.Interface(adapter, 'org.bluez.Adapter')
devicePath = iface_a.ListDevices()[0]  # assuming first device
device = bus.get_object('org.bluez', devicePath)
iface_h = dbus.Interface(device, 'org.bluez.Headset')

#Check state of connection
connected = iface_h.IsConnected()
print 'Toggling connection. Please wait'
# toggle connection
if not connected:
    try:
        iface_h.Connect()
        print 'Connecting: ', devicePath
    except:
        print 'Device not found'
else:
    iface_h.Disconnect()
    print 'Disconnecting: ', devicePath

In case we have more than one Bluetooth device we will have to adapt the devicePath appropriately, of course. The example above will connect a Headset. Change the interface to a different protocol for any other service (e.g. AudioSink).


Pulseaudio

If you know the MAC adress of your Bluetooth device you can connect it as an output sink for pulseaudio by:

pacmd set-default-sink bluez_sink.xx_xx_xx_xx_xx_xx

Where xx_xx_xx_xx_xx_xx is the MAC address (replace ':' by '_' for pulseaudio to recognize it).

See also this answer for more details.


After trying some of the above (scripts didn't work for me) I found the following solution.

First find out the MAC-Adress of the device you want to connect to

bluetoothctl

this will enter a shell and list all available devices with adress. ("quit" to exit the shell & get back to prompt)

Then connect to XX:XX:XX:XX:XX:XX bluetooth device :

echo -e 'connect XX:XX:XX:XX:XX:XX' | bluetoothctl

to disconnect

echo -e 'disconnect XX:XX:XX:XX:XX:XX' | bluetoothctl

been searching for this quite a while - nothing seemed to work, felt so relieved when I found out. Thought others might want to know about it, too. :))