Aceitar automaticamente conexões Bluetooth em um Pi 3

14

Estou procurando desenvolver uma plataforma para o meu carro que conecte automaticamente qualquer dispositivo que tente se conectar ao Pi via bluetooth. Atualmente, ele exige uma aceitação de emparelhamento pelo Pi, mas neste caso não haverá tela, portanto será necessário fazê-lo automaticamente. Como posso fazer isso?

Oliver Kuchies
fonte
você poderia elaborar qual modelo de pi você possui, já que apenas a pi 3 é carib; e de bluetooth sem hardware externo?
Mohammad Ali
Framboesa Pi 3 Modelo B - construída em Bluetooth
Oliver Kuchies
Então, tudo o que você espera é que o Pi esteja transmitindo constantemente e aceite quaisquer conexões de emparelhamento sendo feitas pelo seu telefone? você entende as implicações de segurança? certo? E também está escrevendo um pequeno script Python para fazer o trabalho uma solução aceitável?
Mohammad Ali
Sim, mas para torná-lo mais seguro, sugiro mostrar como limitar a uma conexão antes de redescobrir. Também se sentem livres para adicionar implicações de segurança de resposta para ajudar os outros :)
Oliver Kuchies

Respostas:

12

( Observe que esta resposta não está mais funcionando como no Raspbian Jessie, pois o bluez removeu o comando bluetooth-agent )

Portanto, atualmente você declara que pode se conectar perfeitamente ao Pi, mas precisa de um monitor para o processo de emparelhamento.

Nota: aceitar qualquer conexão é uma ideia incrivelmente insegura e, se você estiver usando apenas um conjunto limitado de dispositivos, configurá-los como dispositivos confiáveis ​​faria muito mais sentido, pois limitaria a conexão com os endereços do Mac, mas não permitiria novos dispositivos a serem adicionados sem um monitor

Mas, de qualquer maneira, os comandos que você precisará executar para aceitar todas as conexões feitas no Pi, para torná-lo detectável e definir um pino previsível estão listados abaixo:

Nota: pode ser necessário alterar o zero hci0 para o número Bluetooth do seu dispositivo.

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

Agora, depois de executar esses comandos e ver se eles funcionam como esperado, podemos prosseguir para configurá-los para iniciar a inicialização do seu Pi.

  1. Começamos criando um arquivo bash executando o comando sudo nano mohammadIsAmazing.sh
  2. Agora, inserimos o seguinte nesse arquivo:

    #!/bin/sh
    sleep 20
    hciconfig hci0 up
    hciconfig hci0 sspmode 1
    hciconfig hci0 piscan
    sudo bluetooth-agent 1234
    
  3. Agora salvamos e fechamos nosso arquivo usando o control key and x

  4. Abrimos o arquivo /etc/rc.localusando o seguinte comando:

    Sudo nano /etc/rc.local
    
  5. Agora inserimos o comando para executar nosso script bash no /etc/rc.local

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

    Nota: você deve colocar o comando antes da última linha em /etc/rc.local que contém: exit 0

  6. Agora, salvamos e fechamos esse arquivo e reiniciamos o Pi.

Em uma nota lateral: certifique-se de escolher um pino aleatório para aumentar marginalmente a segurança

Em outra observação: Se você deseja alterar o nome do dispositivo bluetooth, é necessário criar um arquivo chamado /etc/machine-infoque deve conter o seguinte:

PRETTY_HOSTNAME=device-name

Então corra service bluetooth restartdepois disso

Mohammad Ali
fonte
2
Lembre-se que &no final da linha no rc.localarquivo - sem ela, o RPI pode não terminar a inicialização como as esperas shell para seu script /path/to/script/mohammadIsAmazing.shpara concluir a execução antes de continuar - e se ele não terminar a inicialização que você não será capaz de sshem para consertar as coisas ...!
SlySven 18/05/19
Olá Mohammad. sudo Bluetooth-agente é um comando não reconhecido
Oliver Kuchies
@OliverKuchies tente executar apt-get install bluetooth bluezprimeiro e me diga se isso funciona para você.
Mohammad Ali
Eu tentei correr bluetooth-agente não consegui encontrá-lo também. A instalação dos pacotes não foi corrigida.
Gilad Naaman
@GiladNaaman bem, o que você está usando?
Mohammad Ali
0

Com base no que entendo, o que você precisa é de um módulo bluetooth escravo. Você pode usar o popular módulo HC-06 e conectá-lo ao raspberry pi por meio de um deslocador de nível nos pinos TX e RX no Pi e usar um script python para ler os dados seriais e processá-los conforme necessário

evolucionista
fonte
Eu diria que haveria um módulo python que poderia ser executado assim que um dispositivo bluetooth se conectar ao invés de conectar um hardware? Eu não estou muito gasto com o pi, ainda um novato, mas parece que seria uma abordagem lógica
Oliver Kuchies
@OliverKuchies Eu nunca fiz nenhuma programação bluetooth (ou uso!) No linux, mas você está procurando algum tipo de serviço daemon que responda a essas coisas. Para elaborar: um módulo python não será executado sozinho, ele deve ser usado por um processo que já está sendo executado. Isso é um daemon. Pesquisando "bluetooth linux daemon" aparece algumas coisas. Acho que notei que systemdtem um, você presumivelmente precisa configurá-lo para se comportar de maneiras específicas.
goldilocks
@OliverKuchies dê uma olhada no blog.miguelgrinberg.com/post/…
evolutionizer
0

Não vou discutir a implicação de segurança ou não, mas é assim que faço:

  1. Crie um script chamado auto_connect.sh com o seguinte conteúdo:
#!/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
}
  1. Crie o arquivo /path/to/python_script.py com o seguinte conteúdo:
#!/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()
  1. Dependendo do sistema operacional que você está usando, certifique-se de executar o auto_connect.sh na sua inicialização.

O que tudo isso faz:

  1. Define o dispositivo para ser sempre detectável.

  2. Quando um dispositivo é emparelhado, ele o marca automaticamente no dispositivo confiável e se conecta a ele.

  3. Em cada inicialização, ele percorre a lista de dispositivos conhecidos e tenta se conectar a eles.

Esteja ciente de que essa abordagem vai diretamente contra qualquer tipo de segurança, mas pode haver casos de usuários quando você deseja obter exatamente isso.

Emil Borconi
fonte
-1

No Raspberry Pi3 Modelo B, há um bulit em bluetooth e wifi. Usando o servidor OBEX, você pode receber os arquivos de outros dispositivos sem perguntar sempre sobre a solicitação de emparelhamento. É necessário emparelhar pela primeira vez com esse dispositivo e criar um diretório, em que os arquivos são recebidos o tempo todo.

Basta seguir o passo abaixo.

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

Mihit Gandhi
fonte
1
Você leu a pergunta? O OP pergunta especificamente como evitar o emparelhamento manual, porque não haverá tela, e você sugere que ele faça o emparelhamento de qualquer maneira?
Dmitry Grigoryev
É necessário fazer o emparelhamento apenas uma vez, para que, pela primeira vez, você possa se conectar ao monitor para emparelhamento.
Mihit Gandhi 27/09/16
Você só precisa fazer isso uma vez por dispositivo . E se alguém novo quiser participar, isso significa desenterrá-lo de onde estiver e conectá-lo a um monitor e teclado, e é por isso que ele está procurando uma maneira de evitar isso.
Different55