web-dev-qa-db-fra.com

Comment utiliser bluetoothctl comme hcitool lescan pour signaler des balises de proximité répétées

Je peux utiliser hcitool lescan avec le drapeau --duplicates pour capturer des rapports de publicité LE périodiques (balises de proximité) périodiques à partir de deux périphériques BLE à proximité:

$ Sudo hcitool lescan --duplicates
LE Scan ...
C8:0F:10:29:4D:98 MI1S
C8:0F:10:29:4E:75 MI1S
C8:0F:10:29:4E:75 MI1S
C8:0F:10:29:4D:98 MI1S
C8:0F:10:29:4E:75 MI1S
C8:0F:10:29:4D:98 MI1S
<snip>

Voici à nouveau cette analyse, avec des horodatages ajoutés pour afficher la périodicité:

$ Sudo stdbuf -i0 -o0 -e0 hcitool lescan --duplicates | Perl -nle 'print scalar(localtime), " ", $_'
Wed Apr 13 13:46:45 2016 LE Scan ...
Wed Apr 13 13:46:46 2016 C8:0F:10:29:4E:75 MI1S
Wed Apr 13 13:46:47 2016 C8:0F:10:29:4D:98 MI1S
Wed Apr 13 13:46:48 2016 C8:0F:10:29:4E:75 MI1S
Wed Apr 13 13:46:48 2016 C8:0F:10:29:4D:98 MI1S
Wed Apr 13 13:46:50 2016 C8:0F:10:29:4D:98 MI1S
Wed Apr 13 13:46:52 2016 C8:0F:10:29:4E:75 MI1S
<snip>

Lors de la conférence Linux embarqué et du sommet IoT la semaine dernière (avril 2016), un présentateur travaillant sur la pile BlueZ a déclaré ne plus utiliser hcitool, mais plutôt bluetoothctl.

J'ai essayé cela aujourd'hui, mais il ne montre que le premier rapport de publicité LE pour un périphérique (comme hcitool le fait sans l'option --duplicates):

$ Sudo bluetoothctl
[NEW] Controller 5C:F3:70:62:68:28 BlueZ 5.38 [default]

[bluetooth]# power on
Changing power on succeeded
[CHG] Controller 5C:F3:70:62:68:28 Powered: yes

[bluetooth]# scan on
Discovery started
[CHG] Controller 5C:F3:70:62:68:28 Discovering: yes
[CHG] Device C8:0F:10:29:4E:75 RSSI: -72
[CHG] Device C8:0F:10:29:4D:98 RSSI: -65

[bluetooth]# devices
Device C8:0F:10:29:4D:98 MI1S
Device C8:0F:10:29:4E:75 MI1S

Comment utilisez-vous bluetoothctl pour capturer des rapports publicitaires LE répétés à partir du même appareil, comme le fait hcitool avec l'option --duplicates?

11
jfathman

Je viens de trouver ce qui suit pour moi (Ubuntu 18.04.1, bluez 5.48):

$ bluetoothctl
[bluetooth]# scan on
[bluetooth]# menu scan
[bluetooth]# clear
SetDiscoveryFilter success
[NEW] Device de:ad:be:ef:ca:fe SampleDev
[CHG] Device de:ad:be:ef:ca:fe RSSI: -73
[CHG] Device de:ad:be:ef:ca:fe RSSI: -73
[CHG] Device de:ad:be:ef:ca:fe RSSI: -74

On dirait qu'il existe un filtre d'analyse par défaut actif qui bloque la plupart des publications.

1
Florian Echtler

Merci Florian pour votre suggestion.

Depuis ma publication initiale, j'ai migré vers une distribution Linux intégrée Ubuntu 16.04.4 qui inclut bluez 5.42. Malheureusement, bluetoothctl avec cette version ne reconnaît pas les 'analyses de menu' ou les 'effacer':

[bluetooth]# menu scan
Invalid command

[bluetooth]# clear
Invalid command

Cependant, encouragé par votre mention de "filtre d'analyse par défaut actif qui bloque la plupart des publicités", j'ai expérimenté les commandes disponibles dans ma version de bluetoothctl, comme indiqué dans la sortie de --help, et j'ai obtenu un résultat positif:

root@iot:~# bluetoothctl
[NEW] Controller 00:1A:7D:DA:71:13 iot #1 [default]
[NEW] Controller 70:2C:1F:31:F4:AF iot 

[bluetooth]# set-scan-filter-clear
SetDiscoveryFilter success

[bluetooth]# set-scan-filter-transport le
SetDiscoveryFilter success

[bluetooth]# scan on
Discovery started

[CHG] Controller 00:1A:7D:DA:71:13 Discovering: yes
[NEW] Device 0F:64:64:EE:E7:C4 0F-64-64-EE-E7-C4
[NEW] Device 0D:6F:45:77:87:F3 0D-6F-45-77-87-F3
[NEW] Device 40:CB:C0:F2:96:27 40-CB-C0-F2-96-27
[CHG] Device 0D:6F:45:77:87:F3 RSSI: -71
[CHG] Device FC:F1:36:73:77:B3 RSSI: -57
[CHG] Device 0F:64:64:EE:E7:C4 RSSI: -49

Il faut un peu de frappe dans bluetoothctl pour que celui-ci soit configuré comme je le souhaite et cette saisie est obscurcie par l'activité de journalisation bluetoothctl rapidement dans notre environnement riche en balises. J'ai donc mis en place un script bash qui utilise un heredoc et m'attends à ce que les commandes à bluetoothctl et sed/grep/Perl transmettent le résultat:

$ cat beacon-scan.sh 
#!/bin/bash

# beacon-scan.sh
# Displays beacons including duplicates in real time.
# Uses expect to automate interaction with bluetoothctl.
# Uses sed to remove bluetoothctl colorization escape characters.
# Uses grep to filter out beacon manufacturer data logging.
# Uses Perl to prefix each beacon with a timestamp.

if [ "$(id -u)" != "0" ]; then
    echo "ERROR: must run as root"
    exit 1
fi

(cat <<'END' | /usr/bin/expect

    set Prompt "#"
    set timeout -1

    spawn bluetoothctl

    expect -re $Prompt
    send "scan off\r"

    expect -re $Prompt
    send "remove *\r"

    expect -re $Prompt
    send "set-scan-filter-clear\r"

    expect -re $Prompt
    send "set-scan-filter-transport le\r"

    expect -re $Prompt
    send "scan on\r"

    trap {
        expect -re $Prompt
        send "scan off\r"

        expect -re $Prompt
        send "remove *\r"

        expect -re $Prompt
        send "quit\r"
    } SIGINT

    expect eof

END
) | sed --unbuffered --quiet --expression 's/^.*Device //p' \
  | grep --line-buffered -v ManufacturerData \
  | Perl -nle 'print scalar(localtime), " ", $_'

Ça marche:

$ Sudo ./beacon-scan.sh 
Wed Aug 22 19:34:07 2018 0F:64:64:EE:E7:C4 RSSI: -59
Wed Aug 22 19:34:07 2018 03:46:00:1D:E9:91 03-46-00-1D-E9-91
Wed Aug 22 19:34:07 2018 4E:20:6B:C7:68:D0 RSSI: -55
Wed Aug 22 19:34:07 2018 76:F1:1A:B9:ED:28 RSSI: -57
Wed Aug 22 19:34:07 2018 32:5D:8C:6A:72:C2 32-5D-8C-6A-72-C2
^C

Bluetoothctl signale maintenant les balises qui se répètent, comme lorsque hcitool lescan est exécuté avec le drapeau duplicates.

Je dirai que bluetoothctl serait plus facile à utiliser s'il pouvait être configuré à partir de la ligne de commande sans avoir à le configurer de manière interactive ni à recourir à des scripts plus complexes.

Merci Florian pour votre aide.

1
jfathman