Wykryć, czy w pobliżu znajduje się iPhone / Android?

10

Pracuję zdalnie i dobrze byłoby wiedzieć, kiedy ktoś wyszedł na spotkanie / lunch w moim biurze.

Pomyślałem, że mogę być w stanie pasywnie wykryć, które telefony w pobliżu Raspberry Pi (a następnie opublikować je w Internecie / Dropbox / cokolwiek)

Jaki byłby najłatwiejszy sposób to zrobić? Wykrywanie adresu MAC? Bluetooth?

ACooleman
źródło

Odpowiedzi:

10

Wiele polowań - sporo się nauczyłem - bez powodzenia w wykrywaniu urządzeń innych ludzi bez większego skanowania bezprzewodowego niskiego poziomu - Bluetooth działa na iPhonie, jeśli oba są twoimi urządzeniami:

  1. Skanowanie Wi-Fi może działać na niektórych urządzeniach, ale iOS nie łączy się, gdy ekran jest wyłączony! Mój iPhone 6 można wykryć za pomocą prostego arppolecenia (podaje tabelę numerów ip i mac podłączonych urządzeń w tej samej podsieci), ale dzieje się tak tylko wtedy, gdy ekran telefonu jest podświetlony. Gdy ekran telefonu zasypia - jest poza zasięgiem Wi-Fi! Założę się, że leży to w interesie żywotności baterii.

  2. Klucz sprzętowy Bluetooth działał. Żadnych obliczeń odległości w przeciwieństwie do niektórych fantazyjnych algorytmów - po prostu obecne / nieobecne można wykonać przy bardzo niskim zużyciu energii na rPi i iPhonie. Zainstaluj klucz Bluetooth na rPi jako: ( sudo aptitude install bluetooth bluez-utils bluez-compat). Sprawdź mac swojego urządzenia telefonicznego, umożliwiając jego wyszukiwanie, a następnie wykonaj ( hcitool scan) na rPi. Następnie połącz się z urządzeniem (upewnij się, że można je przeszukiwać) jako: sudo bluez-simple-agent hci0 mac_of_your_devicei powiedz tak po obu stronach. Potem sudo bluez-test-device trusted mac_of_your_device. Teraz oboje się „znają”. Więc zróbsudo hcitool name mac_of_your_devicew swoim ulubionym skrypcie, aby dowiedzieć się, czy iPhone jest w pobliżu. To nie stworzy połączenia - po prostu przywitaj się z nim. Jeśli zwróci nazwę, telefon jest w pobliżu. Jeśli nic nie zwróci - telefonu nie ma w pobliżu lub Bluetooth jest wyłączony. W porównaniu do tworzenia połączeń lub innych metod obliczania odległości - ta metoda oszczędza baterię po obu stronach i ogranicza zanieczyszczenie falami powietrza do minimum.

Ravi Tejwani
źródło
9

Ja i niektórzy z moich przyjaciół opracowaliśmy skaner zbliżeniowy bluetooth, aby otworzyć naszą blokadę drzwi przednich w naszej hackerspace .

Sparowaliśmy wszystkie dozwolone urządzenia i zasadniczo hcitoolsprawdziliśmy, czy jedno ze sparowanych urządzeń znajduje się w pobliżu. Na przykład, jeśli sparowane urządzenie ma adres „00: 00: 00: 00: 00: 00”, należy to zrobić w konsoli wiersza poleceń:

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

Jeśli to zwraca zero, urządzenie znajduje się w pobliżu.

Jednym minusem jest to, że upłynie około 5 sekund, jeśli urządzenie nie będzie w pobliżu.

Mamy opublikował kod źródłowy na Github pod apache licencji open-source.

MadMike
źródło
2
Mogę potwierdzić, że to działa przy użyciu hcitool .... Musisz jednak połączyć polecenia tak jak w powyższym przykładzie. Połączenie jest aktywne tylko przez bardzo krótki czas. W ten sposób możesz dodać bliskość do miksu hcitool rssi ....
Gunnar,
2

Widziałem kilka ustawień używających bluetooth do podobnych przypadków użycia, ale prawdopodobnie będzie to wymagać hakowania. Telefony, które chcesz wykryć, zwykle nie są w trybie wykrywalnym.

Jeśli telefony używają Wi-Fi, prawdopodobnie możesz wykryć pewną bliskość, ale prawdopodobnie oznacza to również, że będziesz musiał je wyszukać na dość niskiej warstwie, ponieważ nie będą one miały dostępu do anteny Wi-Fi i prawdopodobnie połączą się zaszyfrowane. Rzuć okiem na kismet, aby uzyskać bezprzewodową bonanzę na niskim poziomie.

Najprostszym sposobem, aby wykryć, czy ktoś jest w pokoju, czy też nie, choć przypuszczam, byłoby użyć moduł kamery i panaramic lustro.

Bex
źródło
1

Jeśli masz sieć Wi-Fi, z którą się łączą, gdy są w biurze, możesz skanować PI w poszukiwaniu adresów MAC co x okres czasu i aktualizować stronę internetową (Dropbox, cokolwiek) o bieżącym stanie. Prawdopodobnie najbardziej niezawodna trasa.

Możesz być w stanie coś zrobić z Bluetooth i adapterem USB Bluetooth, ale nie mam z tym doświadczenia.

Bez połączenia z pi lub siecią, w której pi jest włączone, nie sądzę, że odniesiesz duży sukces.

Masła
źródło
Miły. Więc jakiej technologii / aplikacji / platformy myślałeś, że użyłbym do skanowania adresów MAC?
ACooleman
Chciałbym to zrobić z nmap, wersją wiersza poleceń i małym niestandardowym kodem Pythona (jestem pewien, że istnieje interfejs API w Pythonie), wykonaj szybkie zapytanie ping / MAC, porównaj to ze wstępnie zbudowaną listą, użyj go, aby zbudować stronę php (HTML?) i podawać ją za pomocą serwera WWW lightppd (Apache?). Ustaw zadanie Pythona tak, aby działało zawsze x okres czasu, a strona internetowa będzie automatycznie odświeżana co y. To fajny pomysł na projekt ... Być może będę musiał spróbować, kiedy skończę wszystkie inne projekty, które są na moim talerzu.
Butters
Być może będziesz w stanie zapytać routera o tablicę ARP lub serwer DHCP ... Może to trochę przyspieszy ...
Butters
1

Przeczytanie powyższych odpowiedzi skłoniło mnie do myślenia o następującej możliwości:

użyj airmon-ng do ciągłego skanowania sieci w poszukiwaniu urządzeń klienckich w sieci Wi-Fi. Dane wyjściowe można zapisać do pliku, więc jeśli plik się zmieni, albo klient wprowadził lub opuścił zakres pi. Posiadanie listy znanych adresów mac pozwala zidentyfikować użytkownika, a ze względu na zmianę pliku możesz wywołać niektóre działania ...

to całkiem ciekawy pomysł! Dzięki!

Arjen

credmp
źródło
Duże sklepy używają tej techniki do monitorowania, w jaki sposób kupujący przeglądają swoje towary, które sztuczny jedwab pomijają itp. Jednak ze względu na przepisy dotyczące prywatności nie zawsze jest legalne powiązanie adresu MAC z osobą w każdym kraju.
Havnar,
1

Pracuję nad tym samym zagadnieniem już od około roku. Sprawiłem, że dość szybko działał na moim komputerze Mac, ale miałem problemy z uruchomieniem go na komputerze. Próbowałem wielu różnych podejść. Mam system automatyki domowej, który włącza ogrzewanie i ciepłą wodę (za pośrednictwem modułu arduino i RF), gdy ja lub mój partner są w domu (to znaczy, że nasze iPhone'y są wykrywalne w domowym WiFi). W końcu użyłem „nslookup”, aby znaleźć adres IP dla iPhone'ów (na wypadek, gdyby adres IP zmienił się, ponieważ są one dynamiczne (ale tak naprawdę nigdy się nie zmieniają na moim routerze)) i „nmap”, aby wykryć, czy iPhone jest włączony sieć. Jeśli iPhone jest w bardzo głębokim śnie, „nmap” nie zawsze znajduje telefon, więc kazałem mu sprawdzić 10 razy, zanim powie, że telefonu nie ma w domu. Poniżej znajduje się część mojego kodu automatyki domowej w Pythonie. Użyłem wątków. Wszelkie pytania z poniższym kodem daj mi znać.

# 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}
        }

i

# 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

i główny kod

   # 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

Kod może nie działać, jeśli skopiujesz go bezpośrednio do własnego skryptu, ponieważ brakuje niektórych części, których nie skopiowałem, aby zachować prostotę i czytelność, ale mam nadzieję, że powyższy kod daje wszystkim poczucie, jak to zrobiłem rzeczy

irishcream24
źródło