簡體   English   中英

使用MAC地址檢測特定藍牙設備的存在

[英]Detecting presence of particular bluetooth device with MAC address

我的最終目標是當我的iphone或卵石手表在附近時,讓我的覆盆子pi檢測到。 我現在專注於鵝卵石,因為我相信iphone隨機化MAC地址。 我有鵝卵石手表的靜態MAC地址。

我的問題是如何通過藍牙檢測MAC地址的存在?

我已經嘗試過hcitool rssi [mac address]或l2ping [mac address]但是在響應之前,兩者都需要在手表上確認連接。 我希望它是自動的......

我也嘗試過hcitool掃描,但這需要一段時間,大概是它正在經歷所有可能性。 我只是想搜索特定的Mac地址。

編輯:我只是嘗試了“hcitool名稱[Mac地址]”,它返回設備的名稱,如果沒有,它返回一個“null”,所以這是想法...是否有一個python相當於此?

我是python的新手,所以希望有人可以指出我如何簡單地ping mac地址並看看RSSI值有多強?

Apple iDevices確實使用具有藍牙低功耗(BLE)的私有可解析地址。 它們每隔約15分鍾循環到一個不同的地址。 只有具有所謂的身份解析密鑰的配對設備才能“解密”這些看似隨機的地址並將它們關聯回配對設備。

所以要用你的iPhone做這樣的事情,你需要將它與你的覆盆子pi配對。 然后你可以做的是制作一個簡單的iOS應用程序,宣傳一些數據(無關緊要,因為當應用程序背景時,只有iOS本身才能將數據放入廣告數據包中)。 在樹莓hcitool lescan ,您可以使用hcitool lescan掃描BLE廣告。 如果可以使用IRK解析廣告的地址,則可以肯定地知道它是iPhone。 我不確定hcitool是否可以開箱即用任何IRK數學,但是藍牙規范很好地規定了解析算法。

Pebble目前確實使用固定地址。 但是,只有當它與應該連接的手機斷開連接時才會進行廣告宣傳。 因此,對於您的用例,使用其BLE廣告並不是非常有用。 目前,Pebble SDK中沒有API允許Pebble上的應用程序通告數據。


FWIW,你提到的命令僅對藍牙2.1(“經典”)有用,並且可能僅在其他設備可被發現時才有用(基本上從不,除非它在設置/藍牙菜單中)。

感謝Chris,我構建了自己的腳本,可以檢測我的手機是否在范圍內並鎖定/解鎖屏幕,如果設備在超時5秒后仍然離開。 它有點快速和骯臟,但對我有用:)

#!/bin/bash
#################################################################
# Check if Bluetooth device is in range and lock/unlock screen. #
#################################################################

MAC=AA:BB:CC:DD:EE:FF
TIMEOUT=5
DEBUG=0

LASTSEEN=0
STATUS=0
PREVSTATUS=0
while true; do
    DT="[$(date '+%F %T')]"
    pgrep xscreensaver >/dev/null || xscreensaver -no-splash >/dev/null     2>&1 &
    if [ -z "$RSSI" ]; then
        sudo hcitool cc $MAC 2>/dev/null
    fi
    RSSI=$(sudo hcitool rssi $MAC 2>/dev/null | cut -d ' ' -f4)

    [ $DEBUG -gt 0 ] && echo "$DT RSSI: $RSSI"

    if [[ -n "$RSSI" && $RSSI -gt 0  ]]; then
        LASTSEEN=$(date '+%s')
    fi

    if [[ $RSSI -eq 0 && $((`date '+%s'`-$LASTSEEN)) -gt $TIMEOUT ]]; then
        STATUS=0
        [ $DEBUG -gt 0 ] && echo "$DT Status: $STATUS Lastseen: $LASTSEEN     Timeout: $((`date '+%s'`-$LASTSEEN))"
    else
        STATUS=1
        [ $DEBUG -gt 0 ] && echo "$DT Status: $STATUS Lastseen: $LASTSEEN     Timeout: $((`date '+%s'`-$LASTSEEN))"
    fi

    if [ $STATUS -ne $PREVSTATUS ]; then
        PREVSTATUS=$STATUS
        if [ $STATUS -gt 0 ]; then
            [ $DEBUG -gt 0 ] && echo "$DT UnLock"
            pgrep xscreensaver >/dev/null && xscreensaver-command     -deactivate
            xset dpms force on
            pgrep xscreensaver >/dev/null && pkill xscreensaver
        else    
            [ $DEBUG -gt 0 ] && echo "$DT Lock"
            pgrep xscreensaver >/dev/null && xscreensaver-command -lock
        fi
    fi

    [ $DEBUG -gt 0 ] && sleep 1
done

可能需要在/ etc / sudoers中添加一行:

username ALL = NOPASSWD: /usr/bin/hcitool

也許這有助於某人。 干杯!

=========================

更新26.09.2017!

我稍微更新了一下,寫了一個Python腳本,通過DBus檢測連接的藍牙設備。 因此,BT設備應首先配對。 如果連接丟失,該腳本還會嘗試重新連接到設備。 這是因為有些設備不能自行重新連接(就像我的手機一樣)。 此腳本不讀取RSSI信號強度,因為我的系統上的DBus不報告它(不知道為什么)。 因為我在Gnome下我使用org.gnome.ScreenSaver作為DBus接口來鎖定屏幕。 如果您使用的是KDE或者您希望在代碼中更改此內容的任何內容。

#!/usr/local/bin/python3
# encoding: utf-8
'''
bluescreen -- Locks your screen
bluescreen is a little python script which locks your screen as long as a bluetooth device is disconnected.
It also unlocks the screen when you return.
It uses the DBus to check if the device is connected and it locks the screen through DBus message calls.
The script uses the first BT adapter found in the system, mainly "hci0". This might be incorrect on some systems.
If so, check the source code below and do the necessary changes.

@author:     Evil2000
@copyright:  2017 Evil2000
@license:    LGPL
@contact:    evil.2000@web.de
@deffield    updated: 26.09.2017
'''

import time
import dbus
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GObject as gobject
from pprint import pprint

'''
Debug flag should be clear
1 = Verbose
2 = Debug
'''
DEBUG = 0

'''
The BT MAC address of the device to monitor
'''
MAC = "11:22:33:AA:BB:CC"

''' =================================================================================================================== '''

# Replace : with _ in device MAC address
DEV_ID = MAC.replace(":", "_")
# Access the DBus main loop
dbus_loop = DBusGMainLoop()
# Connect to the system bus
sysbus = dbus.SystemBus(mainloop=dbus_loop)
# Retrieve the device BlueZ object
device = sysbus.get_object('org.bluez', "/org/bluez/hci0/dev_" + DEV_ID)

# Read the property if the device is connected
deviceConnected = device.Get("org.bluez.Device1", "Connected", dbus_interface='org.freedesktop.DBus.Properties')

if DEBUG > 1:
    pprint(deviceConnected)

# Connect to the session bus
sesbus = dbus.SessionBus(mainloop=dbus_loop)
# Get the screen saver object
sSaver = sesbus.get_object('org.gnome.ScreenSaver', "/org/gnome/ScreenSaver")

# Lock the screen and start the screen saver (i.e. turn off the screen) if it isn't already
def lockScreen():
    if not sSaver.GetActive(dbus_interface='org.gnome.ScreenSaver'):
        if DEBUG:
            print("["+time.strftime('%Y-%m-%d %H:%M:%S')+"] Locking Screen")
        sSaver.Lock(dbus_interface='org.gnome.ScreenSaver')

# Try to connect to the device if it got disconnected. This is called from gobject.timeout_add_seconds() below
def tryConnect():
    if not deviceConnected:
        if DEBUG:
            print("["+time.strftime('%Y-%m-%d %H:%M:%S')+"] Trying device reconnect")
        device.Connect(dbus_interface='org.bluez.Device1')
    return True

# The callback function from connect_to_signal. This handles the events sent by the DBus.
def cb(*args, **kwargs):
    iface = args[0]
    chgprop = args[1]
    #extra = args[2]
    if DEBUG > 1:
        pprint(iface)
        pprint(chgprop)

    # chgprop contains a dictionary with the "Connected" key
    # If it is present and the interface in which the event triggered is Device1, then...
    if iface == "org.bluez.Device1" and "Connected" in chgprop:
        # ... lock screen if device is NOT connected, otherwise disable the screen saver
        if chgprop['Connected'] == True:
            print("["+time.strftime('%Y-%m-%d %H:%M:%S')+"] connected")
            deviceConnected = True
            sSaver.SetActive(False, dbus_interface='org.gnome.ScreenSaver')
        else:
            print("["+time.strftime('%Y-%m-%d %H:%M:%S')+"] disconnected")
            deviceConnected = False
            lockScreen()

# Register a callback function which is triggered if the properties of the bluetooth device changes.
device.connect_to_signal("PropertiesChanged", cb, dbus_interface=None, interface_keyword='iface', member_keyword='member', path_keyword='path', sender_keyword="sender", destination_keyword="dest", message_keyword="message")

# Every 3 seconds, call the tryConnect function
gobject.timeout_add_seconds(3, tryConnect)

# Now, start the main loop.
loop = gobject.MainLoop()
loop.run()

# EOF

檢查PyBluez

為了檢測附近的設備,PyBluez網站上有一個示例腳本。 查詢inquiry.py

另一個想法是使用你已經嘗試過的hcitool ,但使用子進程讓所有東西都是Python。

我在iPhone 7和Raspberry Pi上使用此代碼,效果很好。 iPhone藍牙MAC地址是靜態的。

#!/bin/bash

sudo hcitool cc AA:BB:CC:DD:EE:FF 2> /dev/null

while true
do
    bt=$(hcitool rssi AA:BB:CC:DD:EE:FF 2> /dev/null)
    if [ "$bt" == "" ]; then
        sudo hcitool cc AA:BB:CC:DD:EE:FF  2> /dev/null
        bt=$(hcitool rssi AA:BB:CC:DD:EE:FF 2> /dev/null)
    fi

    echo "$bt"
done

謝謝大家,感謝你的答案,來自我的樹莓派:

1)避免sudo

sudo setcap cap_net_raw+ep /usr/bin/hcitool 

2)找到一個設備

hcitool cc "$mac" 2>/dev/null && hcitool rssi "$mac" 2>/dev/null && echo "found $mac"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM