12

I'm looking to develop a platform for my car which automatically connects any device which attempts to connect to the Pi via bluetooth. Currently it requires a pairing accept by the Pi but in this case there will be no screen so it will need to do it automatically. How can I accomplish this?

  • could you please elaborate on which pi model that you have, as only the pi 3 is carib;e of bluetooth without external hardware? – Mohammad Ali May 17 '16 at 14:18
  • Raspberry Pi 3 Model B - Built in bluetooth – Oliver Kuchies May 18 '16 at 0:43
  • So all you expect is for the Pi to be constantly broadcasting and to accept any pairing connections being made by your phone? you do understand the security implications? right? And also is writing a small Python script to do the job an acceptable solution? – Mohammad Ali May 18 '16 at 3:33
  • Yep but to make it more secure I suggest showing how to limit to one connection before rediscovering. Also feel free to add security implications to answer to help others :) – Oliver Kuchies May 18 '16 at 4:28
11
+50

So currently you state that you can connect to the Pi just fine, but require a monitor for the pairing process.

Note: accepting any connection is an incredibly insecure idea, and if you are only using a limited set of devices, setting them up as trusted devices would make a lot more sense as it would limit connection to your Mac addresses but wold not allow for new devices to be added without a monitor

But anyway, the commands that you will need to run to accept all connections being made to the Pi, to make it discoverable and to set a predictable pin are listed below:

Note: you may need to change the zero in hci0 to your devices Bluetooth number.

hciconfig hci0 up
hciconfig hci0 sspmode 1
hciconfig hci0 piscan
sudo bluetooth-agent 1234

Now after running these commands and seeing if they work as expected we can move on to setting them up to start on the boot of your Pi.

  1. We start by creating a bash file by running the command sudo nano mohammadIsAmazing.sh
  2. We now enter the following into that file:

    #!/bin/sh
    sleep 20
    hciconfig hci0 up
    hciconfig hci0 sspmode 1
    hciconfig hci0 piscan
    sudo bluetooth-agent 1234
    
  3. Now we save and close our file using the control key and x

  4. We open up the file /etc/rc.local using the following command:

    Sudo nano /etc/rc.local
    
  5. Now we enter the command to run our bash script into /etc/rc.local

    sudo /path/to/script/mohammadIsAmazing.sh &
    

    Note: you have to put the command before the last line in /etc/rc.local that contains: exit 0

  6. We now save and close that file, then reboot the Pi.

On a side note: be sure to chose a random pin to marginally increase security

On another side note: If you would like to change the bluetooth device name, you need to create a file called /etc/machine-info which should contain the following:

PRETTY_HOSTNAME=device-name

Then run service bluetooth restart after that

  • 2
    Remember that & on the end of the line in the rc.local file - without it the RPi may not finish booting as the shell waits for your script /path/to/script/mohammadIsAmazing.sh to finish executing before it continues - and if it doesn't finish the boot you will not be able to ssh into it in order to fix things...! – SlySven May 18 '16 at 19:22
  • Hi Mohammad. sudo bluetooth-agent is an unrecognised command – Oliver Kuchies May 26 '16 at 4:10
  • @OliverKuchies try running apt-get install bluetooth bluez first and tell me if that works for you. – Mohammad Ali May 26 '16 at 12:28
  • I have tried running bluetooth-agent and couldn't find it as well. Installing the packages did not fix it. – Gilad Naaman Jun 28 '16 at 17:50
  • @GiladNaaman well what os, are you using? – Mohammad Ali Jun 28 '16 at 17:51
0

Based on what I understand what you require is a slave bluetooth module. You can use the popular HC-06 Module and connect it to the raspberry pi via a level shifter to the TX and RX pins on the Pi and use a python script to read the serial data and process it as required

  • I would assume there would be a python module which could be run as soon as a bluetooth device connects rather than connecting hardware? I'm not too shabby with the pi, still a beginner but it seems it would be a logical approach – Oliver Kuchies May 15 '16 at 8:54
  • @OliverKuchies I've never done any bluetooth programming (or use!) on linux but you are looking for some kind of daemon service that will respond to such things. To elaborate: a python module will not run itself, it has to be used by a process that's already running. That's a daemon. Searching "bluetooth linux daemon" does turn up some stuff. I think I've noticed systemd has one, you presumably have to configure it to behave in specific ways. – goldilocks May 16 '16 at 17:19
  • @OliverKuchies have a look at blog.miguelgrinberg.com/post/… – evolutionizer May 17 '16 at 4:11
0

I'm not going to discuss the security implication or not but this is how I do it:

1) Create a script called auto_connect.sh with the following content:

#!/bin/bash
bt-adapter --set Powered 1
bt-adapter --set DiscoverableTimeout 0
bt-adapter --set Discoverable 1
bt-adapter --set PairableTimeout 0
bt-adapter --set Pairable 1
/path/to/python_script.py >/dev/nul 2>dev/nul &
list=""
bt-device -l | grep -E -o '[[:xdigit:]]{2}(:[[:xdigit:]]{2}){5}' | { while read line
do
       list="$list connect $line
"
done
bluetoothctl << EOF
$list
EOF
}

2) Create the file /path/to/python_script.py with the following content:

#!/usr/bin/python3

from __future__ import absolute_import, print_function, unicode_literals

#import gobject
from gi.repository import GObject as gobject

import re
import dbus
import dbus.mainloop.glib
import subprocess

relevant_ifaces = [ "org.bluez.Adapter1", "org.bluez.Device1" ]

def property_changed(interface, changed, invalidated, path):
        iface = interface[interface.rfind(".") + 1:]
        for name, value in changed.iteritems():
                val = str(value)
                print("{%s.PropertyChanged} [%s] %s = %s" % (iface, path, name,
                                                                        val))

def interfaces_added(path, interfaces):
        for iface in interfaces:
                if not(iface in relevant_ifaces):
                        continue
                try:
                        found = re.search('dev\_(..\_..\_..\_..\_..\_..)', path).group(1)
                except AttributeError:
                        found = '' # apply your error handling
                mac=found.replace("_",":")
                cmd='echo -e "trust '+mac+' \\nconnect '+mac+' \\nquit" | bluetoothctl'
                subprocess.call(cmd, shell=True)

def interfaces_removed(path, interfaces):
        for iface in interfaces:
                if not(iface in relevant_ifaces):
                        continue
                print("{Removed %s} [%s]" % (iface, path))

if __name__ == '__main__':
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

        bus = dbus.SystemBus()

        bus.add_signal_receiver(interfaces_added, bus_name="org.bluez",
                        dbus_interface="org.freedesktop.DBus.ObjectManager",
                        signal_name="InterfacesAdded")

        bus.add_signal_receiver(interfaces_removed, bus_name="org.bluez",
                        dbus_interface="org.freedesktop.DBus.ObjectManager",
                        signal_name="InterfacesRemoved")

        mainloop = gobject.MainLoop()
        mainloop.run()

3) Depending on the os you are using make sure you run the auto_connect.sh on your boot.

What this all does:

1) Sets the device to be always discoverable.

2) When a device pairs to it, it will automatically mark it at trusted device and connect to it.

3) On every boot it will itinerant through the list of known devices and will try to connect to them.

Please be mindful that this approach goes directly against any kind of security, but there might be user cases when you want to achieve just that.

-1

In Raspberry Pi3 Model B there is a bulit in bluetooth and wifi. Using OBEX server you can receive the files from other devices without asking about pairing request every time. You have to do pairing first time with that device and make one directory, in that the files received all the time.

Just follow the step of below link.

https://www.raspberrypi.org/forums/viewtopic.php?p=963751#p963751

  • 1
    Have you read the question? The OP specifically asks how to avoid manual pairing because there will be no screen, and you suggest he should do pairing anyway? – Dmitry Grigoryev Sep 27 '16 at 11:40
  • You have to do pairing only once in this so for the first time you may connect with display for pairing. – Mihit Gandhi Sep 27 '16 at 12:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.