15

I am running a headless Raspberry PI 3, and I want it to automatically accept pairings from any device.

I saw this answer in an identical question:

Automatically accepting Bluetooth connections on a Pi 3

But it seems to be a bit outdated and some of the used commands don't seem to exist.

I am running the 2016-05-27-raspbian-jessie.img OS image.

Ingo
  • 42,107
  • 20
  • 85
  • 197
Gilad Naaman
  • 259
  • 1
  • 2
  • 4

9 Answers9

10

Since bluetooth-agent command doesn't exist on Jessie, the modern way is to pipe relevant commands to bluetoothctl. Based on this SO question, the following script should enable automatic pairing without manual pin entry:

sudo bluetoothctl <<EOF
power on
discoverable on
pairable on
agent NoInputNoOutput
default-agent 
EOF
Dmitry Grigoryev
  • 27,928
  • 6
  • 53
  • 144
  • 1
    This worked for making my RPi Zero W discoverable on boot. I had previously updated my Bluetooth config via the steps outlined here and with this script. – charliesneath Dec 06 '18 at 02:22
  • This works, but do you mind telling me how to make the raspberry pi auto-trust the device after pairing? Thanks – Daniele Segato Jun 17 '19 at 16:08
  • It seems this allows pairing, but does not authorize connections for lack of an agent. I believe the agent part of this script does not work properly. When I run this script, I get No agent is registered, it seems the default-agent command runs to fast. When I input the commands manually, it does not give this error, but once I quit bluetoothctl it unregisters the agent and trying to connect fails. If I leave bluetoothctl running, I get a prompt asking whether to trust the connection, which is not so NoInputNoOutput as you'd hope... – Matthijs Kooijman Jul 08 '19 at 22:25
  • I suspect the NoInputNoOutput is not so much an authorization policy, but part of the bluetooth protocol to figure out what type of authorization mechanisms (e.g. can a pin be used?) are available. – Matthijs Kooijman Jul 08 '19 at 22:27
  • @MatthijsKooijman If the script worked, you could feed a yes to the prompt asking whether to trust the connection. – Dmitry Grigoryev Jul 09 '19 at 06:46
  • 2
    Probably, but then you'd have to keep feeding yes's for all pairing attempts (and I'm not entirely sure if that works from stdin or perhaps the script tries to be smart and tries to open the terminal directly rather than stdin (that also happens sometimes)... Have not tried this, though, I ended up using the python script from https://gist.github.com/mill1000/74c7473ee3b4a5b13f6325e9994ff84c – Matthijs Kooijman Jul 09 '19 at 10:05
  • 1
    Down voted because bluetoothctl shenanigans are inferior to calling hciconfig hci0 piscan and hciconfig hci0 sspmode 1 – Phlip Feb 18 '21 at 13:38
  • @Phlip I upvoted your comment to make it more visible :) It should be noted that sspmode 1 was added in BT 2.1, legacy devices still require "shenanigans" to connect. – Dmitry Grigoryev Feb 18 '21 at 13:59
  • furtherless, I must call hciconfig hci0 piscan each time I then want to use Python pybluez to open a Bluetooth server... – Phlip Feb 19 '21 at 23:28
  • 1
    The mentioned options still did not work for them, RPi still asked for PIN. What finally worked was hciconfig hci0 class 0x400100. After this I cannot connect RFCOMM socket without prior pairing. – Quimby Jan 13 '22 at 10:22
4

I was facing the same issue and found this method to work (RasPi 3, Model B, Raspbian 9 Stretch)

I am using Raspberry Pi as an IoT EDGE Device and needed it to accept Bluetooth Pair Requests without intervention. I have an Android App that communicates text information to the Pi via Bluetooth and my problem statement needed any Android device to connect.

Firstly, I am not running any separate Bluetooth Agents (No Blueman, infact I had to remove it)

Edited the .bashrc file at

    sudo nano /home/pi/.bashrc

Added two commands to this at the end

    sudo hciconfig hci0 piscan 
    sudo hciconfig hci0 sspmode 1

piscan makes Raspberry Pi Bluetooth discoverable

sspmode 1 enables 'Secure Simple Pairing' which is the same type of method used by your Bluetooth Earphones or Speakers (basically devices that don't have a display where you can confirm PIN). And since these commands are in .bashrc they run at boot.

Run Bluetooth Script. Pair. Although there is a pop-up asking me to confirm, I can communicate messages to and from the Pi with my app

Note : hci0 may not be the same throughout, could be hci1, hci2 please check by running hciconfig on your CLI

This is almost like a contraption, and I am not sure if there are any unknown repercussions, but it works. Any improvements are appreciated

  • 1
    I put them into /etc/rc.local, because bash only calls .bashrc opportunistically, and I preceded them with hciconfig hci0 up just in case the Bluetooth is feeling down that day. – Phlip Feb 18 '21 at 13:39
0

One simple way is Just to remove the Blueman if you have installed it by using

sudo apt remove blueman 

And remove the Bluetooth logo from the top menu by right click and remove.

And install bluedot using

sudo pip3 install bluedot

for more about bluedot click here

import time
from bluedot.btcomm import BluetoothServer
import os
import bluetooth

def data_received(data): print(data) s.send(data)

os.system('bluetoothctl discoverable on && bluetoothctl agent NoInputNoOutput') time.sleep(2) s = BluetoothServer(data_received)

Now In Android phone go to Bluetooth settings and pair raspberry Pi

And if you will send data it will print on the terminal you can check it's working or not by using this application if you didn't develop your own.

  • Raspbian Jessie, used by the questioner, is outdated since 2020-01-01 and not supported anymore. Its repository is archived. – Ingo Aug 15 '20 at 08:59
  • I have the same Error and I took 2 days to search and resolve it and I just posted here so someone have the same error it will help – Sejpalsinh Jadeja Aug 15 '20 at 15:04
  • What operating system and version do you use? You should edit your answer and mention it. – Ingo Aug 16 '20 at 08:02
0

I have to make clear some terminology:

  • A bluetooth service is an asset to which you pair and to which you pair.
  • Therefore a bluetooth client is the asset which you use to connect to the bluetooth server

I am currently working on a project which involves bluetooth pairing in Linux - note that the server you want to connect (defined as bluetooth server - i.e MUST HAVE the "Just works" (aka NoInputNoOutput) capability in order to work. "Just works" means exactly that - the pairing is in the simplest form: does not require authorization/pin/confirmation etc (Hence No Input No Output)

Now, due to the explaination above, automatic pairing becomes a relative term: automatic in relation to what?

  • Automatic in the context of the server having implemented the "NoInputNoOutput" capability means that all the client has to do (automatically) is to call the "Pair" method. This will be sufficient to be able to discover all the GATT services/characteristics.
  • Automatic in the context of the server NOT HAVING the "NoInputNoOutput" capability implemented, means that the client must somehow have the subsequent capability (the one that is implemented in the server) implemented in an Agent. This custom agent could then handle the process automatically, with the exception of a case in which you want to display a code on the server and input in on the client (like bluetooth pairing in a car where the code is displayed on the dashboard and you have to insert it on your phone)

In conclusion, it depends on the capability of the bluetooth device you want to connect to (you are the client, again).

I banged my head to the wall for a long time until I realized this and I was trying to autopair something that is not autopairable.

bem22
  • 121
  • 4
  • 1
    With some more detail, this might be a useful answer. the device you want to connect... that would not be the RPi I'll guess - but what type of device is it?; perhaps some insight into what exactly "Just works" is? – Seamus Mar 09 '21 at 17:46
0
sudo apt install bluez-tools 
sudo bt-agent -c DisplayOnly -p pins.txt

pins.txt:

00:00:00:00:00:00 *
*                 *
user3817445
  • 101
  • 1
0

Not working on me

bt-agent -c NoInputNoOutput -d -p pins.txt

Warning! pins.txt is world readable!

0

You may take a peek at the source code of EcoDroidLink. It accepts Bluetooth connections without the need to log in.

EDIT: By popular demand, here are code excerpts of the edl_agent module that makes this happen.

# - automate the agent for running on a headless Pi - to answer pair and connection requests without a blocking query

import dbus
import dbus.service
import dbus.mainloop.glib
import bluezutils

BUS_NAME = 'org.bluez'
AGENT_INTERFACE = 'org.bluez.Agent1'
AGENT_PATH = "/test/agent"

bus = None
device_obj = None
dev_path = None

def set_trusted(path):
    props = dbus.Interface(bus.get_object("org.bluez", path),
                    "org.freedesktop.DBus.Properties")
    props.Set("org.bluez.Device1", "Trusted", True)

def dev_connect(path):
    dev = dbus.Interface(bus.get_object("org.bluez", path),
                            "org.bluez.Device1")
    dev.Connect()

class Rejected(dbus.DBusException):
    _dbus_error_name = "org.bluez.Error.Rejected"

class Agent(dbus.service.Object):
    exit_on_release = True

    def set_exit_on_release(self, exit_on_release):
        self.exit_on_release = exit_on_release

    @dbus.service.method(AGENT_INTERFACE,
                    in_signature="", out_signature="")
    def Release(self):
        printlog("Release")
        if self.exit_on_release:
            mainloop.quit()

    @dbus.service.method(AGENT_INTERFACE,
                    in_signature="os", out_signature="")
    def AuthorizeService(self, device, uuid):
        printlog("AuthorizeService (%s, %s)" % (device, uuid))
        authorize = "yes" #ask("Authorize connection (yes/no): ")
        if (authorize == "yes"):
            return
        raise Rejected("Connection rejected by user")

    @dbus.service.method(AGENT_INTERFACE,
                    in_signature="o", out_signature="s")
    def RequestPinCode(self, device):
        printlog("RequestPinCode (%s)" % (device))
        set_trusted(device)
        return "0000" #ask("Enter PIN Code: ")

    @dbus.service.method(AGENT_INTERFACE,
                    in_signature="o", out_signature="u")
    def RequestPasskey(self, device):
        printlog("RequestPasskey (%s)" % (device))
        set_trusted(device)
        passkey = "0000" #ask("Enter passkey: ")
        return dbus.UInt32(passkey)

    @dbus.service.method(AGENT_INTERFACE,
                    in_signature="ouq", out_signature="")
    def DisplayPasskey(self, device, passkey, entered):
        printlog("DisplayPasskey (%s, %06u entered %u)" %
                        (device, passkey, entered))

    @dbus.service.method(AGENT_INTERFACE,
                    in_signature="os", out_signature="")
    def DisplayPinCode(self, device, pincode):
        printlog("DisplayPinCode (%s, %s)" % (device, pincode))

    @dbus.service.method(AGENT_INTERFACE,
                    in_signature="ou", out_signature="")
    def RequestConfirmation(self, device, passkey):
        printlog("RequestConfirmation (%s, %06d)" % (device, passkey))
        confirm = "yes" #ask("Confirm passkey (yes/no): ")
        if (confirm == "yes"):
            set_trusted(device)
            return
        raise Rejected("Passkey doesn't match")

    @dbus.service.method(AGENT_INTERFACE,
                    in_signature="o", out_signature="")
    def RequestAuthorization(self, device):
        printlog("RequestAuthorization (%s)" % (device))
        auth = "yes" #ask("Authorize? (yes/no): ")
        if (auth == "yes"):
            return
        raise Rejected("Pairing rejected")

    @dbus.service.method(AGENT_INTERFACE,
                    in_signature="", out_signature="")
    def Cancel(self):
        printlog("Cancel")
Serge Stroobandt
  • 455
  • 7
  • 18
0

I just used a fresh install of 2016-09-23-raspbian-jessie-lite.img to try it without any additional updates. No apt-get update no apt-get install bluez-utils or anything. This single command makes the Pi discoverable and pairable. Without an agent to control who can connect, it just lets anyone:

sudo hciconfig hci0 piscan
Jon Musselwhite
  • 774
  • 4
  • 16
0

Raspbian - Jessie

sudo apt-get install expect

xxxxx.sh

#!/usr/bin/expect -f
set prompt "#"
spawn sudo bluetoothctl
sleep 1
expect -re $prompt
sleep 1
send "agent NoInputNoOutput\r"
sleep 2
expect "Agent registered"
send "default-agent\r"
expect -re $prompt
sleep 3
interact
expect eof
hyu
  • 11
  • 1
  • 1
    An answer that consists of code only is not very explicit so please provide some more detailed explanation on your answer. Also indent your code block to make it appear like code; use 4 spaces or a tab, at your preference. –  Nov 01 '17 at 14:47
  • downvoted because scripting bluetoothctl is inferior to calling hciconfig hci0 piscan and hciconfig hci0 sspmode 1 – Phlip Feb 18 '21 at 13:41