Автоматически принимать пары Bluetooth


9

Я использую Raspberry PI 3 без головы и хочу, чтобы он автоматически принимал пары с любого устройства.

Я видел этот ответ в идентичном вопросе:

Автоматический прием Bluetooth-соединений на Pi 3

Но это кажется немного устаревшим, и некоторые из используемых команд, кажется, не существуют.

Я запускаю 2016-05-27-raspbian-jessie.imgобраз ОС.


Что вы подразумеваете под "некоторыми из используемых команд, кажется, не существует"? Что именно у вас не получилось?
Дмитрий Григорьев

1
Если я правильно помню bluetooth-agent, но я не уверен.
Гилад Нааман,

Ответы:


7

Поскольку bluetooth-agentкоманда не существует в Jessie, современный способ заключается в передаче соответствующих команд bluetoothctl. Исходя из этого вопроса SO , следующий скрипт должен включить автоматическое сопряжение без ручного ввода пин-кода:

sudo bluetoothctl <<EOF
power on
discoverable on
pairable on
agent NoInputNoOutput
default-agent 
EOF

1
Это помогло сделать мой RPi Zero W доступным для обнаружения при загрузке. Ранее я обновил свою конфигурацию Bluetooth с помощью шагов, описанных здесь, и с помощью этого сценария .
charliesneath

Это работает, но вы не против рассказать мне, как заставить Raspberry Pi автоматически доверять устройству после сопряжения? Спасибо
Даниэле Сегато

Кажется, что это позволяет спаривать, но не авторизует соединения из-за отсутствия агента. Я считаю, что агентская часть этого скрипта не работает должным образом. Когда я запускаю этот скрипт, я получаю No agent is registered, кажется, default-agentкоманда работает быстро. Когда я ввожу команды вручную, это не выдает эту ошибку, но как только я bluetoothctlзавершаю работу, агент регистрируется, и попытка подключения завершается неудачно. Если я ухожу bluetoothctl, я получаю подсказку с вопросом, следует ли доверять соединению, что не так, NoInputNoOutputкак вы надеетесь ...
Маттис

Я подозреваю, что NoInputNoOutputэто не столько политика авторизации, сколько часть протокола Bluetooth, чтобы выяснить, какие типы механизмов авторизации (например, можно ли использовать пин-код?) Доступны.
Маттис

1
Возможно, но тогда вам придется продолжать вводить «да» для всех попыток сопряжения (и я не совсем уверен, работает ли это с помощью стандартного ввода, или, возможно, сценарий пытается быть умным и пытается открыть терминал напрямую, а не стандартный ввод (это также бывает иногда) ... не пробовал этого, хотя я в итоге использовал скрипт python от gist.github.com/mill1000/74c7473ee3b4a5b13f6325e9994ff84c
Matthijs Kooijman

0

Я просто использовал новую установку, 2016-09-23-raspbian-jessie-lite.imgчтобы попробовать его без каких-либо дополнительных обновлений. Нет apt-get updateнет apt-get install bluez-utilsили что-нибудь. Эта единственная команда делает Пи обнаружимым и доступным. Без агента, который контролирует, кто может подключиться, он позволяет любому:

sudo hciconfig hci0 piscan

0

Распбиан - Джесси

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

1
Ответ, состоящий только из кода, не очень точный, поэтому, пожалуйста, предоставьте более подробное объяснение вашего ответа. Также сделайте отступ в блоке кода, чтобы он выглядел как код; используйте 4 пробела или табуляцию, по вашему выбору.

0

Я столкнулся с той же проблемой и обнаружил, что этот метод работает (RasPi 3, модель B, Raspbian 9 Stretch)

Я использую Raspberry Pi в качестве устройства IoT EDGE и мне нужно было принимать запросы пар Bluetooth без вмешательства. У меня есть приложение для Android, которое передает текстовую информацию Pi через Bluetooth, и для постановки задачи мне нужно было подключить любое устройство Android .

Во-первых, я не использую какие-либо отдельные Bluetooth-агенты (нет Blueman, фактически мне пришлось его удалить)

Отредактировал файл .bashrc в

    sudo nano /home/pi/.bashrc

Добавил две команды к этому в конце

    sudo hciconfig hci0 piscan 
    sudo hciconfig hci0 sspmode 1

piscan делает Raspberry Pi Bluetooth доступным для обнаружения

sspmode 1 включает «Безопасное простое сопряжение», которое является тем же методом, который используется вашими наушниками или динамиками Bluetooth (в основном это устройства, у которых нет дисплея, на котором вы можете подтвердить PIN-код). И поскольку эти команды находятся в .bashrc, они запускаются при загрузке.

Запустите скрипт Bluetooth. Пара. Хотя есть всплывающее окно с просьбой подтвердить, я могу обмениваться сообщениями с Pi и с помощью моего приложения

Примечание: hci0 может не совпадать, может быть hci1, hci2, пожалуйста, проверьте, запустив hciconfig на вашем CLI

Это почти как уловка, и я не уверен, есть ли какие-то неизвестные последствия, но это работает. Любые улучшения приветствуются


-1

Вы можете взглянуть на исходный код из EcoDroidLink . Он принимает Bluetooth-соединения без необходимости входа в систему.

РЕДАКТИРОВАТЬ: По многочисленным просьбам, вот выдержки из кодаedl_agent модуля, который делает это.

# - 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")

1
Хотя это может теоретически ответить на вопрос, было бы предпочтительным включить сюда основные части ответа и предоставить ссылку для справки.
Jacobm001

@ Jacobm001 Я добавил выдержки из кода. Это лучше сейчас?
Серж
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.