Detectar se o iphone / Android está próximo?


10

Estou trabalhando remotamente e seria útil saber quando alguém sai para uma reunião / almoço no meu escritório.

Eu pensei que poderia ser capaz de detectar passivamente quais telefones estão perto do raspberry pi (e publicá-los na web / dropbox / o que for)

Qual seria a maneira mais fácil de fazer isso? Detecção de endereço MAC? Bluetooth?

Respostas:


10

Muita caça - aprendida um pouco - não há sorte em detectar dispositivos de outras pessoas sem muita varredura sem fio de baixo nível - o Bluetooth funciona para o iphone se ambos forem seus próprios dispositivos:

  1. A verificação Wi-Fi pode funcionar em alguns dispositivos, mas os iOS não se conectam quando a tela está desligada! Meu iphone 6 pode ser detectado com um arpcomando simples (fornece tabela de números de ip e mac de dispositivos conectados na mesma sub-rede), mas isso aconteceria apenas quando a tela do telefone estivesse acesa. Uma vez que a tela do telefone dorme - ela está fora dos limites no wifi! Aposto que isso é do interesse da vida útil da bateria.

  2. Dongle Bluetooth funcionou. Nenhuma computação à distância é diferente de alguns algoritmos sofisticados - apenas o presente / ausente pode ser feito com muito pouco consumo de energia no rPi e no iPhone. Instale o dongle bluetooth no rPi como: ( sudo aptitude install bluetooth bluez-utils bluez-compat). Descubra o mac do seu dispositivo telefônico, tornando-o pesquisável e, em seguida, faça ( hcitool scan) na rPi. Em seguida, conecte-se ao seu dispositivo (verifique se é pesquisável) como: sudo bluez-simple-agent hci0 mac_of_your_devicee diga sim nos dois lados. Então sudo bluez-test-device trusted mac_of_your_device. Agora os dois "se conhecem". Então façasudo hcitool name mac_of_your_deviceno seu script favorito para descobrir se o iPhone está próximo. Isso não criará uma conexão - apenas diga oi. Se retornar um nome, o telefone está próximo. Se não retornar nada - o telefone não está próximo ou o bluetooth está desligado. Comparado à criação de conexões ou outros métodos de computação à distância, esse método conserva a bateria dos dois lados e mantém a poluição das ondas de ar no mínimo.


9

Eu e alguns amigos meus estamos desenvolvendo um scanner de proximidade por Bluetooth para abrir a fechadura da porta da frente do nosso espaço de hackers .

Emparelhamos todos os dispositivos permitidos e, essencialmente, usamos hcitoolpara testar se um dos dispositivos emparelhados está próximo. Por exemplo, se o dispositivo emparelhado tiver o endereço "00: 00: 00: 00: 00: 00", você faria isso no console da linha de comandos:

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

Se isso retornar zero, o dispositivo está próximo.

Uma desvantagem é que isso levará cerca de 5 segundos para atingir o tempo limite se o dispositivo não estiver próximo.

Temos publicou o código-fonte no Github sob a licença de código aberto Apache.


2
Posso confirmar que isso está funcionando usando hcitool .... No entanto, você deve encadear os comandos como no exemplo dado acima. A conexão está ativa apenas por um período muito curto. Você pode adicionar proximidade à mistura fazendo hcitool rssi ....
Gunnar

2

Vi algumas configurações usando bluetooth para casos de uso semelhantes, mas provavelmente envolverá hackers. Os telefones que você deseja detectar geralmente não estão no modo detectável.

Se os telefones usarem wifi, você provavelmente poderá detectar alguma proximidade, mas isso provavelmente também significa que será necessário procurá-los em uma camada bastante baixa, pois eles não acessarão sua antena wifi e provavelmente se conectarão criptografados. Dê uma olhada no kismet para obter alguns benefícios sem fio de baixo nível.

A maneira mais fácil de detectar se alguém está em uma sala ou não, eu acho, seria usar o módulo da câmera e um espelho panaramico.


1

Se você possui uma rede Wi-Fi à qual eles se conectam quando estão no escritório, o PI pode procurar endereços MAC a cada x período de tempo e atualizar uma página da Web (dropbox, qualquer que seja) com o status atual. Provavelmente a rota mais confiável.

Você pode fazer algo com bluetooth e um adaptador USB Bluetooth, mas não tenho experiência com isso.

Sem eles conectados ao pi, ou à rede em que o pi está, não acho que você terá muito sucesso.


Agradável. Então, qual tecnologia / aplicativo / plataforma você achava que eu usaria para verificar os endereços MAC?
precisa saber é o seguinte

A maneira como eu faria isso é com o nmap, a versão da linha de comando e um pouco de código python personalizado (tenho certeza de que existe uma API python), faça uma consulta rápida de varredura de ping / MAC, compare-a com uma lista pré-criada, use isso para criar uma página php (HTML?) e servi-la usando o servidor web lightppd (Apache?). Defina o trabalho python para executar sempre x períodos de tempo e faça com que a página da Web seja atualizada automaticamente a cada período. É uma ideia legal do projeto ... Talvez eu precise tentar depois de terminar todos os outros projetos que estão no meu prato.
Butters

Você pode ser capaz de consultar o seu router para a tabela ARP, ou você servidor DHCP, bem ... Pode torná-lo um pouco mais rápido ..
Butters

1

A leitura das respostas acima também me levou a pensar na seguinte possibilidade:

use airmon-ng para verificar continuamente a rede em busca de dispositivos clientes no wifi. A saída pode ser gravada em um arquivo, portanto, se o arquivo for alterado, um cliente inseriu ou saiu do intervalo do pi. Ter uma lista de endereços MAC conhecidos permite identificar o usuário e, devido à alteração do arquivo, você pode acionar algumas ações ....

é uma ideia bastante interessante! Obrigado!

Arjen


As grandes lojas usam essa técnica para monitorar como os compradores navegam em seus produtos, qual rayon pulam etc. Mas, devido às leis de privacidade, nem sempre é legal vincular um endereço mac a uma pessoa em todos os países.
Havnar


1

Então, eu estou trabalhando no mesmo problema há cerca de um ano. Consegui fazê-lo funcionar no meu mac rapidamente, mas tive muitos problemas para fazê-lo funcionar corretamente no meu PC. Eu tentei muitas abordagens diferentes. Eu tenho um sistema de automação residencial que liga o aquecimento e a água quente (por meio de um módulo arduino e RF) quando eu ou meu parceiro estamos em casa (ou seja, nossos iPhones são detectáveis ​​no Wi-Fi doméstico). No final, usei 'nslookup' para encontrar o endereço IP dos iPhones (caso o endereço IP tenha mudado por serem dinâmicos (mas na verdade nunca mudam no meu roteador)) e 'nmap' para detectar se o iPhone está ligado a rede. Se o iPhone estiver em sono profundo, o 'nmap' nem sempre encontra o telefone, então eu o verifiquei 10 vezes antes de dizer que o telefone não está em casa. Abaixo está parte do meu código de automação residencial em python. Eu usei rosqueamento. Qualquer dúvida com o código abaixo me avise.

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

e

# 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

e o código 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

O código pode não funcionar se você copiá-lo diretamente para o seu próprio script, pois há algumas partes que não foram copiadas para tentar manter as coisas simples e fáceis de ler, mas espero que o código acima dê a todos uma noção de como eu fiz coisas.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.