iPhone / Androidが近くにあるかどうかを検出しますか?


10

私はリモートで作業しているので、誰かが私のオフィスで会議や昼食に出かけたときを知ると便利です。

私はラズベリーpiの近くにある電話を受動的に検出できる可能性があると思った(そして、それらをweb / dropboxなどに公開した)

これを行う最も簡単な方法は何でしょうか?MACアドレスの検出?ブルートゥース?

回答:


10

多くの狩猟-かなり学んだ-低レベルのワイヤレススキャンの多くなしで他の人々のデバイスを検出する運がない-両方があなた自身のデバイスである場合、BluetoothはiPhoneで動作します:

  1. 一部のデバイスではWifiスキャンが機能する場合がありますが、画面がオフの場合、iOSデバイスは接続しません。私のiphone 6は簡単なarpコマンド(同じサブネット上に接続されているデバイスのIPおよびMAC番号のテーブルを提供)で検出できましたが、これは電話の画面が点灯している場合にのみ発生します。電話画面がスリープ状態になると、Wi-Fiの範囲外になります。これはバッテリーの寿命のためだと思います。

  2. Bluetoothドングルが機能しました。いくつかの派手なアルゴリズムとは異なり、距離の計算はありません。rPiとiPhoneでは、わずかな電力消費で存在/不在を行うことができます。rPiにBluetoothドングルをインストールします:(sudo aptitude install bluetooth bluez-utils bluez-compat)。電話デバイスのMacを検索可能にしてから、hcitool scanrPiで()を実行します。次に、次のようにデバイスに接続して(検索可能であることを確認します)sudo bluez-simple-agent hci0 mac_of_your_device、両側で「はい」と言います。その後sudo bluez-test-device trusted mac_of_your_device。今、彼らは両方ともお互いを「知っています」。それからsudo hcitool name mac_of_your_deviceお気に入りのスクリプトで、iPhoneが近くにあるかどうかを調べます。これは接続を作成しません-ただそれに挨拶してください。名前を返す場合は、電話が近くにあります。何も返さない場合-電話が近くにないか、Bluetoothがオフになっています。接続や他の距離計算方法をそこに作成するのと比較して-この方法は、両側のバッテリーを節約し、電波の汚染を最小限に抑えます。


9

私と私の友人の何人かは、ハッカースペースのフロントドアロックを開くためのBluetooth近接スキャナーを開発しています

すべての許可されたデバイスをhcitoolペアリングし、ペアリングされたデバイスの1つが近くにあるかどうかをテストするために基本的に使用しました。例として、ペアリングされたデバイスのアドレスが「00:00:00:00:00:00」の場合、コマンドラインコンソールで次のように実行します。

hcitool cc 00:00:00:00:00:00 && hcitool auth 00:00:00:00:00:00 && hcitool dc 00:00:00:00:00:00;

これがゼロを返す場合、デバイスは近接しています。

1つの欠点は、デバイスが近くにない場合、タイムアウトまでに5秒ほどかかることです。

私たちは、Apacheオープンソースライセンスの下でGithubにソースコード公開しています


2
これがを使用して機能していることを確認できますhcitool ...。ただし、上記の例のようにコマンドをチェーンする必要があります。接続はごく短時間だけアクティブになります。を実行することで、ミックスに近接性を追加できhcitool rssi ...ます。
Gunnar

2

同様のユースケースでBluetoothを使用するいくつかのセットアップを見てきましたが、おそらくいくつかのハッキングが含まれます。検出する電話は通常、検出可能モードではありません。

電話がwifiを使用している場合は、おそらくいくつかの近接を検出できますが、これはおそらく、無線LANアンテナにアクセスせず、暗号化されて接続するため、かなり低い層でそれらをスキャンする必要があることを意味します。低レベルのワイヤレスボナンザについては、kismetご覧ください。

最も簡単な、誰かが部屋にあるか、しかし、私は推測するかどうかを検出する方法は、カメラモジュールとpanaramicミラーを用いることであろう。


1

オフィスにいるときに接続するWiFiネットワークがある場合、x期間ごとにMACアドレスのPIスキャンを実行し、現在のステータスでWebページ(ドロップボックスなど)を更新できます。おそらく最も信頼できるルートです。

BluetoothとUSB Bluetoothアダプターで何かできるかもしれませんが、私はその経験がありません。

それらがpiに接続されていない場合、またはpiが存在するネットワークがない場合、私はあなたが大きな成功を収めるとは思いません。


いいね。それで、MACアドレスをスキャンするためにどのような技術/アプリ/プラットフォームを使用すると思いましたか?
ACooleman 2014

私がそれを行う方法は、nmap、コマンドラインバージョン、および小さなカスタムPythonコード(Python APIがあると確信しています)を使用して、すばやくpingスイープ/ MACクエリを実行し、事前に作成されたリストと比較します。これを使用してphp(HTML?)ページを作成し、lightppd(Apache?)Webサーバーを使用して提供します。Pythonジョブをx期間ごとに実行するように設定し、y期間ごとにWebページを自動更新します。それはクールなプロジェクトのアイデアです...私が自分の皿にある他のすべてのプロジェクトを完了した後、私はそれを試さなければならないかもしれません。
バター14

あなたは、あなたにもDHCPサーバのARPテーブル用のルーターを照会することができ、またはかもしれない... ..それは少し速くなるかもしれない
バター

1

上記の回答を読んだことで、次の可能性についても考えました。

airmon-ngを使用して、wifi上のクライアントデバイスのネットワークを継続的にスキャンします。出力はファイルに書き込むことができるため、ファイルが変更された場合、クライアントがpiの範囲に入ったか、範囲外に出ました。既知のMACアドレスのリストがあると、ユーザーを識別でき、ファイルが変更されるため、いくつかのアクションをトリガーできます。

それはかなり興味深いアイデアです!ありがとう!

アリエン


大型店はこの手法を使用して、買い物客が商品をどのように閲覧するか、どのレーヨンをスキップするかなどを監視します。ただし、プライバシー法により、すべての国の人にMACアドレスをリンクすることは必ずしも合法ではありません。
Havnar

1

デバイスがすべて同じネットワーク上にある限り、Raspberry Piを使用してこれを簡単に行うことができます。これが、必要なすべてのコードを含む完全なプロジェクトです...

http://www.element14.com/community/people/mcollinge/blog/2014/09/12/raspberry-pi-network-spy--part-1


提供するリンクには興味深い情報がありますが、質問に対する回答など、回答を改善することができます。
mpromonet 2015

1

それで、私は同じ問題に約1年取り組んできました。Macでかなり早く動作しましたが、自分のPCで正しく動作させるのに多くの問題がありました。私は多くの異なるアプローチを試みてきました。私またはパートナーが家にいるときに(arduinoとRFモジュールを介して)暖房と温水をオンにするホームオートメーションシステムがあります(つまり、iPhoneは家のWiFiで検出可能です)。最後に、「nslookup」を使用してiPhoneのIPアドレスを検索し(IPアドレスが動的であるため変更された場合(ただし、実際にはルーターで変更されない場合))、「nmap」を使用してiPhoneがオンかどうかを検出しましたネットワーク。iPhoneが非常に深いスリープ状態にある場合、「nmap」は常に電話を見つけるわけではないので、電話が自宅にないことを示す前に、10回チェックを行いました。以下は、Pythonでのホームオートメーションコードの一部です。スレッディングを使用しました。以下のコードで質問があれば教えてください。

# Dictionary to store variables to reuse on program restart
    v = {
        'boilerControlCH' : 'HIH', # 'scheduled' or 'HIH' (Honey I'm Home)
        'boilerControlHW' : 'scheduled',
        'thermostatSetPoint' : 20.8,
        'thermostatVariance' : 0.1,
        'morningTime' : datetime(1970,1,1,6,0,0),
        'nightTime' : datetime(1970,1,1,23,0,0),
        'someOneHome' : False,
        'guest' : False,
        'minimumTemperatureOO' : False,
        'minimumTemperature' : 4.0,
        'iPhoneMark' : {'iPhoneHostname' : 'marks-iphone', 'home' : False},
        'iPhoneJessica' : {'iPhoneHostname' :'jessicaesiphone', 'home' : False}
        }

そして

# Check if anyone at home
    def occupancyStatus(person, Bol = False):
        with lockOccupancyStatus:
            someOneHome = False

        if 'iPhone' in person:
            v[person]['home'] = Bol
        elif 'retest' in person:
            pass
        else:
            v[person] = Bol

        if v['guest'] == True:
            someOneHome = True

        for key in v:
            if 'iPhone' in key:
                if v[key]['home'] == True:
                    someOneHome = True

        v['someOneHome'] = someOneHome
        variablesToFile()
    return

そしてメインコード

   # iPhone home status threading code
    class nmapClass(threading.Thread):
        def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        global exitCounter

        nmapThread()
        msg.log('Exited nmapThread')    
        waitEvent.set()
        waitEventAdjustable.set()
        serialDataWaiting.set()
        exitCounter += 1


def nmapThread():
    iPhone = {}
    maxCounts = 10
    for phone in v:
        if 'iPhone' in phone:
            iPhone[phone] = {}
            iPhone[phone]['hostname'] = v[phone]['iPhoneHostname']
            iPhone[phone]['count'] = maxCounts
    #msg.log(iPhone)

    while exitFlag[0] == 0:
        for phone in iPhone:
            if iPhone[phone]['count'] > 0:
                phoneFound = False
                IPAddress = '0.0.0.0'

                # Find iPhones IP address using its hostname
                commandNsloolup = 'nslookup %s' %iPhone[phone]['hostname']
                childNslookup = pexpect.popen_spawn.PopenSpawn(commandNsloolup, timeout = None)
                output = childNslookup.readline()
                while '\r\n' in output:
                    #msg.log(output)
                    if 'Name:' in output:
                        output = childNslookup.readline()
                        if 'Address:' in output:
                            tempStr = output
                            startPoint = tempStr.find('192')
                            tempStr = tempStr[startPoint:]
                            IPAddress = tempStr.replace('\r\n', '')
                            #msg.log(IPAddress)
                    output = childNslookup.readline()


                if IPAddress == '0.0.0.0':
                    pass
                    #msg.error('Error finding IP address for %s' %iPhone[phone]['hostname'], GFI(CF()).lineno)
                else:
                    #commandNmap = 'nmap -PR -sn %s' %IPAddress
                    #commandNmap = 'nmap -p 62078 -Pn %s' %IPAddress # -p specifies ports to try and access, -Pn removes pinging
                    commandNmap = 'nmap -p 62078 --max-rate 100 %s' %IPAddress
                    childNmap = pexpect.popen_spawn.PopenSpawn(commandNmap, timeout = None)
                    output = childNmap.readline()
                    while '\r\n' in output:
                        if 'Host is up' in output:
                            phoneFound = True
                            break
                        output = childNmap.readline()
                    #if phoneFound:
                    #   break


                if phoneFound:              
                    iPhone[phone]['count'] = 0

                    if v[phone]['home'] == False:
                        msg.log('%s\'s iPhone has returned home' %phone)
                        occupancyStatus(phone, True)
                        waitEventAdjustable.set()
                    #else:
                        #msg.log('%s\'s iPhone still at home' %phone)
                else:
                    iPhone[phone]['count'] -= 1

                    if v[phone]['home'] == True and iPhone[phone]['count'] == 0:
                        msg.log('%s\'s iPhone has left home' %phone)
                        occupancyStatus(phone, False)
                        waitEventAdjustable.set()
                    #else:
                        #msg.log('%s\'s iPhone still away from home' %phone)

            elif iPhone[phone]['count'] < 0:
                msg.error('Error with count variable in iPhone dictionary', GFI(CF()).lineno)


        longWait = True
        for phone in iPhone:
            if iPhone[phone]['count'] > 0:
                longWait = False
                #msg.log('%s: %s' %(phone, iPhone[phone]['count']))

        if longWait:
            #msg.log('wait long')               
            # 600 = run every 10 minutes
            waitEvent.wait(timeout=600)
            for phone in iPhone:
                iPhone[phone]['count'] = maxCounts
        else:
            #msg.log('wait short')
            waitEvent.wait(timeout=60)  

    return

単純に読みやすくするためにコピーしていない部分がいくつかあるため、コードを独自のスクリプトに直接コピーすると、コードが機能しない可能性があります。事。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.