Автоматически принимать пары 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.