Détecter si iphone / Android à proximité?


10

Je travaille à distance et il serait utile de savoir quand quelqu'un est sorti pour une réunion / déjeuner dans mon bureau.

J'ai pensé que je pourrais être en mesure de détecter passivement quels téléphones près du Raspberry Pi (puis de les publier sur le Web / Dropbox / peu importe)

Quelle serait la façon la plus simple de procéder? Détection d'adresse MAC? Bluetooth?

Réponses:


10

Beaucoup de chasse - beaucoup appris - pas de chance de détecter les appareils d'autres personnes sans beaucoup de balayage sans fil de bas niveau - Bluetooth fonctionne pour l'iphone si les deux sont vos propres appareils:

  1. La numérisation Wifi peut fonctionner pour certains appareils, mais ceux iOS ne se connectent pas lorsque l'écran est éteint! Mon iphone 6 pourrait être détecté avec une simple arpcommande (donne le tableau des numéros ip et mac des appareils connectés sur le même sous-réseau) mais cela ne se produirait que lorsque l'écran du téléphone est allumé. Une fois que l'écran du téléphone dort - il est hors limites sur le wifi! Je parie que c'est dans l'intérêt de la durée de vie de la batterie.

  2. Le dongle Bluetooth a fonctionné. Aucun calcul de distance contrairement à certains algorithmes sophistiqués - juste présent / absent peut être fait avec très peu de consommation d'énergie sur rPi et iPhone. Installez le dongle bluetooth sur rPi comme: ( sudo aptitude install bluetooth bluez-utils bluez-compat). Découvrez le mac de votre appareil téléphonique en le rendant consultable, puis faites ( hcitool scan) sur rPi. Connectez-vous ensuite à votre appareil (assurez-vous qu'il est consultable) en tant que: sudo bluez-simple-agent hci0 mac_of_your_deviceet dites oui des deux côtés. Alors sudo bluez-test-device trusted mac_of_your_device. Maintenant, ils se «connaissent» tous les deux. Alors faissudo hcitool name mac_of_your_devicedans votre script préféré pour savoir si l'iphone est à proximité. Cela ne créera pas de connexion - mais dites-lui simplement bonjour. S'il renvoie un nom, le téléphone est à proximité. S'il ne renvoie rien - le téléphone n'est pas à proximité ou le Bluetooth est désactivé. Comparée à la création de connexions ou à d'autres méthodes de calcul de distance, cette méthode permet d'économiser la batterie des deux côtés et de réduire la pollution des ondes au minimum.


9

Mes amis et moi-même avons développé un scanner de proximité Bluetooth pour ouvrir la serrure de la porte d'entrée de notre hackerspace .

Nous avons couplé tous les appareils autorisés et avons essentiellement utilisé hcitoolpour tester si l'un des appareils couplés se trouve à proximité. Par exemple, si le périphérique couplé a l'adresse "00: 00: 00: 00: 00: 00", vous le feriez sur la console de ligne de commande:

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

Si cela renvoie zéro, l'appareil est à proximité.

Un inconvénient est que cela prendra environ 5 secondes pour expirer si l'appareil n'est pas à proximité.

Nous avons publié le code source sur Github sous la licence open source apache.


2
Je peux confirmer que cela fonctionne en utilisant hcitool .... Cependant, vous devez enchaîner les commandes comme dans l'exemple donné ci-dessus. La connexion n'est active que très peu de temps. Vous pouvez ajouter de la proximité au mix en faisant hcitool rssi ....
Gunnar

2

J'ai vu certaines configurations utilisant Bluetooth pour des cas d'utilisation similaires, mais cela impliquera probablement un piratage. Les téléphones que vous souhaitez détecter ne sont généralement pas en mode détectable.

Si les téléphones utilisent le wifi, vous pouvez probablement détecter une certaine proximité, mais cela signifiera probablement que vous devrez les rechercher à une couche plutôt basse, car ils n'accéderont pas à votre antenne wifi et ils se connecteront probablement cryptés. Jetez un oeil à kismet pour une aubaine sans fil de bas niveau.

Le moyen le plus simple de détecter si quelqu'un se trouve dans une pièce ou non, cependant, je suppose, serait d'utiliser le module de caméra et un miroir panoramique.


1

Si vous avez un réseau WiFi auquel ils se connectent lorsqu'ils sont au bureau, vous pouvez avoir le PI scan pour les adresses MAC toutes les x périodes et mettre à jour une page Web (boîte de dépôt, peu importe) avec l'état actuel. Probablement l'itinéraire le plus fiable.

Vous pourriez peut-être faire quelque chose avec Bluetooth et un adaptateur Bluetooth USB, mais je n'ai aucune expérience avec cela.

Sans eux connectés au pi ou au réseau sur lequel le pi est connecté, je ne pense pas que vous aurez beaucoup de succès.


Agréable. Alors, quelle technologie / application / plateforme pensiez-vous que j'utiliserais pour scanner les adresses MAC?
ACooleman

La façon dont je le ferais est avec nmap, la version en ligne de commande et un peu de code python personnalisé (je suis sûr qu'il y a une api python), faites une requête ping rapide de balayage / MAC, comparez cela à une liste pré-construite, utilisez-le pour créer une page php (HTML?) et servez-le en utilisant le serveur web lightppd (Apache?). Définissez le travail python pour qu'il s'exécute chaque x période de temps et actualisez automatiquement la page Web toutes les y périodes. C'est une bonne idée de projet ... Je devrais peut-être essayer un peu après avoir terminé tous les autres projets qui sont dans mon assiette.
Butters le

Vous pourrez peut-être interroger votre routeur pour la table ARP, ou votre serveur DHCP aussi ... Pourrait le rendre un peu plus rapide ..
Butters

1

La lecture des réponses ci-dessus m'a également incité à penser à la possibilité suivante:

utilisez airmon-ng pour rechercher en continu sur le réseau des appareils clients sur le wifi. La sortie peut être écrite dans un fichier, donc si le fichier change, un client est entré ou a quitté la plage du pi. Avoir une liste d'adresses mac connues vous permet d'identifier l'utilisateur et en raison du changement de fichier, vous pouvez déclencher certaines actions ....

c'est une idée assez intéressante! Merci!

Arjen


Les grands magasins utilisent cette technique pour surveiller la façon dont les acheteurs parcourent leurs produits, quelle rayonne ils sautent, etc. Mais en raison des lois sur la confidentialité, il n'est pas toujours légal de lier une adresse mac à une personne dans chaque pays.
Havnar


1

Je travaille donc sur le même sujet depuis environ un an maintenant. Je l'ai fait fonctionner sur mon Mac assez rapidement, mais j'ai eu beaucoup de mal à le faire fonctionner correctement sur mon PC. J'ai essayé de nombreuses approches différentes. J'ai un système domotique qui allume le chauffage et l'eau chaude (via un module Arduino et RF) lorsque moi ou mon partenaire sommes à la maison (c'est-à-dire que nos iPhones sont détectables sur le WiFi de la maison). À la fin, j'ai utilisé 'nslookup' pour trouver l'adresse IP des iPhones (au cas où l'adresse IP changerait car ils sont dynamiques (mais ils ne le font jamais sur mon routeur)) et 'nmap' pour détecter si l'iPhone est allumé le réseau. Si l'iPhone est en sommeil très profond, «nmap» ne trouve pas toujours le téléphone, je l'ai donc vérifié 10 fois avant de dire que le téléphone n'est pas à la maison. Ci-dessous fait partie de mon code domotique en python. J'ai utilisé le filetage. Toutes les questions avec le code ci-dessous me le font savoir.

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

et

# 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

et le code principal

   # 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

Le code peut ne pas fonctionner si vous le copiez directement dans votre propre script, car il manque des parties que je n'ai pas copiées pour essayer de garder les choses simples et faciles à lire, mais j'espère que le code ci-dessus donne à chacun une idée de la façon dont je l'ai fait des choses.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.