检测iphone / Android是否在附近?


10

我正在远程工作,因此很容易知道何时有人出去在我的办公室开会/共进午餐。

我以为我可能能够被动地检测到树莓派附近的哪些手机(然后将它们发布到Web / Dropbox /等等)

最简单的方法是什么?MAC地址检测?蓝牙?

Answers:


10

大量的猎物-学到了很多-没有大量的低级无线扫描就没有运气来检测其他人的设备-如果蓝牙和iPhone都是您自己的设备,则可用于iphone:

  1. Wifi扫描可能适用于某些设备,但是在屏幕关闭时,iOS的设备无法连接!我的iphone 6可以通过简单的arp命令检测到(在同一子网中提供连接设备的ip和mac编号表),但这仅在手机屏幕点亮时才会发生。手机屏幕进入休眠状态后,它就无法进入wifi了!我敢打赌这是为了延长电池寿命。

  2. 蓝牙加密狗工作正常。与现有的一些高级算法不同,没有距离计算-在rPi和iPhone上只需很少的功耗就可以完成当前/不存在的计算。在rPi上将蓝牙加密狗安装为:(sudo aptitude install bluetooth bluez-utils bluez-compat)。通过使其可搜索来找出电话设备的mac,然后hcitool scan在rPi上执行()。然后以下列方式连接到您的设备(确保其可搜索):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是否在附近。这不会创建连接-只是打个招呼。如果返回名称,则电话在附近。如果未返回任何内容-手机不在附近或蓝牙已关闭。与在那里建立连接或其他距离计算方法相比,此方法可节省两侧电池,并将电波污染降至最低。


9

我和我的一些朋友一直在开发一种蓝牙接近扫描仪,以打开我们黑客空间的前门锁。

我们已经对所有允许的设备hcitool进行了配对,实际上是用来测试配对设备中的一个是否在附近。例如,如果配对的设备的地址为“ 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;

如果返回零,则表明设备在附近。

缺点是,如果设备不在附近,这将需要约5秒钟的超时时间。

我们已根据apache开源许可在Github发布了源代码


2
我可以确认正在使用hcitool ...。但是,您必须像上面给出的示例一样链接命令。连接仅在很短的时间内处于活动状态。您可以通过执行添加接近度hcitool rssi ...
Gunnar

2

我已经看到一些针对类似用例使用蓝牙的设置,但可能会涉及一些黑客行为。您要检测的电话通常不处于可发现模式。

如果电话使用wifi,则您可能会检测到一定距离,但这也可能意味着您将不得不在较低的层进行扫描,因为它们将无法访问wifi天线,并且可能会进行加密连接。看看基斯迈特(Kismet),了解一些低级别的无线财富。

不过,我猜想,检测某人是否在房间里的最简单方法是使用摄像头模块和全景镜。


1

如果您有一个WiFi网络,当他们在办公室时可以连接到该WiFi网络,则可以让PI每隔x个时间段扫描一次MAC地址,并以当前状态更新网页(投递箱,无论如何)。可能是最可靠的路线。

您也许可以使用蓝牙和USB蓝牙适配器进行某些操作,但是我对此没有经验。

如果没有将它们连接到pi或pi所处的网络,我认为您不会取得很大的成功。


真好 那么,您认为我将使用哪种技术/应用程序/平台来扫描MAC地址?
ACooleman

我的方式是使用nmap,命令行版本和一些自定义python代码(我确定有python api),进行快速ping扫描/ MAC查询,并将其与预先构建的列表进行比较,使用它来构建一个php(HTML?)页面并使用lightppd(Apache?)Web服务器为其提供服务。将python作业设置为每隔x个时间段运行一次,并使网页每隔y个时间段自动刷新一次。这是一个很酷的项目构想...在完成所有其他项目之后,我可能不得不试一试。
黄油

你也许可以查询你的路由器的ARP表,或者你的DHCP服务器,以及...可能会使它再快一点..
巴特斯

1

阅读以上答案也使我开始思考以下可能性:

使用airmon-ng连续扫描网络中wifi上的客户端设备。可以将输出写入文件,因此,如果文件更改,则客户端已输入或离开pi的范围。拥有已知的mac地址列表可让您识别用户,由于文件更改,您可能会触发某些操作...。

这是一个很有趣的想法!谢谢!

Arjen


大型商店使用此技术来监视购物者浏览商品的方式,跳过的人造丝等。但是,由于隐私法的限制,将mac地址链接到每个国家/地区的人并不总是合法的。
哈夫纳2014年


1

所以我已经在同一个问题上工作了大约一年。我很快就可以在Mac上运行它,但是要在PC上正常运行却遇到了很多麻烦。我尝试了许多不同的方法。我有一个家庭自动化系统,当我或我的伴侣在家时(即可以在家庭WiFi上检测到我们的iPhone),该系统可以打开暖气和热水(通过arduino和RF模块)。最后,我使用“ 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

如果直接将其复制到自己的脚本中,则该代码可能无法正常工作,因为有些地方我还没有复制,因此为了使事情保持简单易读,我没有进行复制,但是希望上面的代码能使大家对我的做法有所了解东西。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.