查看: 12812|回复: 4

用树莓派做个专属iBeacon基站

  [复制链接]
  • TA的每日心情
    开心
    2014-4-16 09:58
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-2-12 09:42:06 | 显示全部楼层 |阅读模式
    分享到:
    一月初,苹果在北美全部254家Apple Store均部署了iBeacon基站。当消费者手持升级了iOS 7并支持低功耗蓝牙(Bluetooth 4.0)的设备走进店铺时,即可收到商店自动推送的消息提示。而现在,得益于硬件运动的发展,我们完全可以用Raspberry Pi自制一个iBeacon基站。
    1.jpg
    iBeacon是什么?
    在今年WWDC上,苹果正式发布了iOS 7,而iBeacon也是该系统的重要特性之一。 种种迹象 表明,iBeacon技术将是苹果未来的重要发展对象之一。
    iBeacon是基于Bluetooth 4.0LE协议开发的技术。在店内部署iBeacon基站后,它可以定位用户在室内的位置,据称精度可以厘米计算。这意味着,当用户走到商店内不同位置的时候,商店可以推送不同的产品信息或打折信息。
    尽管是新技术,但是在苹果推出它的同时,便已经有相应产品了。新创公司 Estimote已经开始为商家提供iBeacon基站产品,它的售价为99美元。
    美国百货商店Macy’s已经部署了iBeacon基站。 据称 ,它会向安装有专为其设计的应用发送大约31字节的数据,其中包含了128位的UUID,可以通过两个16位的识别码来确定用户所在的门店,以及在店内的区域。通过这样的技术,iPhone 5S的用户甚至可以通过扫描指纹直接购买商品。
    用Raspberry Pi制作iBeacon基站
    近日,一位叫Tony Smith的创客用一个Raspberry Pi和一个蓝牙适配器制作了一个iBeacon基站,它还配备了Linux Bluetooth软件栈、BlueZ和多种USB开发包。正如之前所说,iBeacon技术是基于低功耗蓝牙开发的,所以它同样可以支持Android 4.3以上的设备。
    苹果在iOS的Corelocation架构层中定义了一个CLLocationManager类,用以检测在iBeacon基站所覆盖的区域内(iBeacon的信息传输距离最远可达50m左右)的移动设备,即监控触发事件。

    (详细的软硬件开发过程,可以参考 Tony Smith的教程 。)教程见回复!
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2014-4-16 09:58
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

     楼主| 发表于 2014-2-12 09:48:50 | 显示全部楼层
    本帖最后由 nuaa211 于 2014-2-12 09:52 编辑

    Build your OWN Apple iBeacon with a Raspberry Pi
    Spare us five minutes for a short survey about end user computing?
    Feature US department store Macy’s recently said it is implementing iPhone-based tracking tech the better to encourage browsing punters to buy. Of course, Macy has chosen to pitch this as an Apple technology - figuring, presumably, iPhone owners are more receptive to inducements delivered through technology and have more cash to splash than Android fans.
    But the fact is, the system Apple calls iBeacon simply makes use of features already part of the Bluetooth Low Energy (LE) spec.
    This got me thinking: how difficult would it be to build a similar system of my own? Not very hard at all, it turns out. Choose the right kit and it can be quite cheap too. I created my beacon using a £30 Raspberry Pi and a £12 Bluetooth 4.0 USB dongle.
    1.jpg
    Surely this cant be an Apple iBeacon? Yes it can

    Bluetooth LE incorporates a protocol for beacon devices to identify themselves. Each sends out a short packet of data "advertising" which can contain up to 31 bytes of user-defined data. Apples iBeacon specification, such as it is, stores four values in this space: a Proximity128-bit UUID and two 16-bit numbers, Majorand Minor.
    Apple has a good example of how these variables are used: a department store chain - Macys, say - adopts a single UUID for all its beacons. It uses the value of the Major variable to distinguish one shop from another, and the value of the Minor variable to differentiate between beacons in one shops departments.
    Not all Bluetooth dongles are Linux-friendly. A handy resource listing well-behaving ones can be found at the Embedded Linux Wiki. A branded one will set you back around a tenner, generic ones less. I used IoGears GBU521.
    Next, prepare your Pi. You need to install the official Linux Bluetooth software stack, BlueZ, and various USB development packages, some using the apt-get tool at the command line, others by compiling the code.
    First run this:
    sudo apt-get install libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev
    Next install BlueZs source files and compile it. The version at the time of writing was 5.11.
    sudo wget www.kernel.org/pub/linux/bluetooth/bluez-5.11.tar.xz
    sudo unxz bluez-5.11.tar.xz
    sudo tar xvf bluez-5.11.tar
    cd bluez-5.11
    sudo ./configure --disable-systemd
    sudo make
    sudo make install
    This will take a while, but when its done, you can reboot and plug in the dongle.

    Decoding the iBeacon protocol

    Theres no version of the uuidgen utility readily available for the Pi, so I used this website. The 16 pairs of two-digit hexadecimal values - each pair is dubbed an "octet" in the jargon - along with Major and Minor pair of octets, need to be punched into the Pis Bluetooth sub-system using BlueZs hcitool utility:
    sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 [ 92 77 83 0A B2 EB 49 0F A1 DD 7F E3 8C 49 2E DE ] [ 00 00 ] [ 00 00 ] C5 00
    Note that the square brackets are NOT part of the command - Ive added them solely to show where the UUID, Major then Minor codes go. The C5after them is a value representing transmitted power level. Just cut and paste the line above and replace the UUID with your own.
    2.jpg
    Not all Bluetooth dongles are Pi pals

    This is how you decode the command: the "hci0" identifies your Bluetooth dongle, "cmd" tells hcitool to send the following command data to the device. The "0x08" is the Bluetooth command group - the "OGF" in the official parlance - and "0x0008" is the specific command ("OCF"), HCI_LE_Set_Advertising_Data.
    The first "1E" is the number of significantoctets in the advertising data that follow, up to a maximum of 31. The non-significant part should only comprise pairs of zeroes to take the number of octets up to 31 and which, to save power, are not transmitted.
    The ad data is split into groups, each formatted with a single octet providing the number of remaining octets in the group - essentially it tells the Bluetooth sub-system how further along the list of octets is the next group. Its followed by a single octet which defines the type of data, and then any number of octets holding the data itself. You can put as many of these groups into the advertising data packet as you can fit into the 31 octets allowed.
    In my example, the first "02" in the sequence says the first block of ad data is two octets long. The next octet, "01" says the advertising octet(s) following are Bluetooth flags, and the "1A" is the binary value derived when certain of those flags are set.
    1Asays the next group is 26 octets long, and the "FF" identifies the group as manufacturer-specific data. The Bluetooth 4.0 specification says the next two octets have to expose the manufacturer: the "4C 00" is Apples Bluetooth manufacturer ID.


    3.jpg
    In the Zone: location notification on a Metawatch smartwatch
    Im not yet sure what the "02" and "15" signify, but as I say, the Proximity UUID, Major and Minor values, and the power level complete the 26 octets of manufacturer data - and the 30 octets of the entire advertising data.
    The hcitool command formats the iBeacon advertising signal. Telling the Pi to begin sending out that signal requires the following command:
    sudo hciconfig hci0 leadv
    You can disable LE beacon activity with the command:
    sudo hciconfig hci0 noleadv
    Update If you dont see your beacon after issuing the leadv command, try sudo hciconfig hci0 noscan which stops the dongle looking for other Bluetooth devices. This can interfere with the beacon operation.
    And its an obvious next step to create scripts to set all this up and activate LE advertising whenever the Pi boots up, but I wont be covering that here. If youd like to do that, theres a very good tutorial written by Washington DC-based Radius Networks here.

    Building a beacon monitor app

    If youd just like to cut to the chase and start coding iBeacon support into apps, Radius is selling pre-configured Pis as iBeacon development kits with one or two on-board dongles. Prices start at $100 (£61).
    With the Pi running as a beacon, the next stage is to create an app that will look for it and notify you when youre there. I chose to work up an iOS app - Im exploring Apples iBeacon, after all - but it should be possible to code it up in Android 4.3, which added Bluetooth LE support to the Google OS.
    Apple added it to iOS 7, released back in September. iOSs existing CoreLocation framwork defines a CLLocationManager class that provides an interface for detecting iBeacons and a mechanism for dealing with events triggered by moving into and out a beacons zone of coverage, an extension of CLLocationManagers already available ability to work with geographical regions.
    CLLocationManager also defines methods for checking whether the device the app is running on has an OS and hardware able to handle Bluetooth LE: [CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]] returns a Boolean true if the device is beacon savvy.
    Pass that test and a well-behaved app will then double-check that iOSLocation Services have been enabled and that the app has permission to access them. It can then start looking for beacons with the Proximity UUID, Major and Minor values punched into the Pi earlier:
    {
        ...

        CLBeaconRegion *beaconRegion;
        NSUUID *beaconUUID;
        NSString *beaconIdent;

        ...

        beaconUUID = [[NSUUID alloc] initWithUUIDString:  @"9277830A-B2EB-490F-A1DD-7FE38C492EDE"];
        beaconIdent = @"Vulture.Zone.1";
        beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID major:0 minor:0 identifier:beaconIdent];

        ...

        [appLocationManager startMonitoringForRegion:beaconRegion];

        ...
    }

    CoreLocation provides two handy delegate methods for dealing with events triggered by the beacon monitor: - (void)locationManager  :     (CLLocationManager *)manager didEnterRegion:  (CLRegion *)region and - (void)locationManager:  (CLLocationManager *)manager didExitRegion:  (CLRegion *)region. The object that owns the CLLocationManager must adhere to the CLLocationManagerDelegate protocol if its to receive these messages.
    These two methods provide an easy way to alert the user he or she has entered the zone and to trigger actions accordingly. My test app, for instance, grabs a block of HTML code from El Regs server and presents it in a UIWebView: Special Offer! The Editor will buy you a pint if you present this code..., that kind of thing.


    4.jpg
    Running the app: Were too far away (left) but then...

    iOS scans for regions even when the app that initiated the monitoring isnt running. The app is automatically run in the background if the beacon is detected in those circumstances. Likewise, its woken from sleep if it is merely napping. You can control whether messages triggered when beacon region boundaries are crossed are delayed while the iDevices screen is off: the CLBeaconRegion object created above has a Boolean property, notifyEntryStateOnDisplay, you can use to enable this behaviour. It also has a Boolean property called notifyOnEntry, inherited from CLBeaconRegions superclass CLRegion, which youll need to set to NO in this case.
    Once the phone knows its inside a beacons sphere of influence, the app can call the - (void)locationManager:  (CLLocationManager *   )manager didRangeBeacons:  (NSArray *   )beacons inRegion:   (CLBeaconRegion  *   )region method to get a list of nearby beacons and from each entry, a beacons UUID, Major and Minor values to help identify which they are and, thanks to each beacons proximity property, roughly how close it is.
    To keep things tidy, I added an switch to disable beacon scanning. By way of inter-object notifications, it calls [appLocationManager stopMonitoringForRegion:beaconRegion] to take the currently defined beacon off the system-wide monitoring list.


    5.jpg
    ...and heres a message from our (nearby) sponsor

    Once all this is up and running, and the Pi-hosted iBeacon is operating in the background, its easy to test the system by walking out of range of the beacon and then turning round and coming back.
    Android users keen to try this out without coding their own beacon detector can check out Radius NetworksiBeacon Locate app in Google Play. Theres an iOS version in iTunes too. Radius also has an open-source library of iBeacon compatibility code for Android if you want to incorporate iBeacon support into an app of your own.



    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2014-4-16 09:58
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

     楼主| 发表于 2014-2-12 11:02:39 | 显示全部楼层
    本帖最后由 nuaa211 于 2014-2-12 11:04 编辑

    Build your OWN Apple iBeacon with a Raspberry Pi
    Spare us five minutes for a short survey about end user computing?
    Feature US department store Macys recently said it is implementing iPhone-based tracking tech the better to encourage browsing punters to buy. Of course, Macy has chosen to pitch this as an Apple technology - figuring, presumably, iPhone owners are more receptive to inducements delivered through technology and have more cash to splash than Android fans.
    But the fact is, the system Apple calls iBeacon simply makes use of features already part of the Bluetooth Low Energy (LE) spec.
    This got me thinking: how difficult would it be to build a similar system of my own? Not very hard at all, it turns out. Choose the right kit and it can be quite cheap too. I created my beacon using a £30 Raspberry Pi and a £12 Bluetooth 4.0 USB dongle.
    1.jpg
    Surely this can’t be an Apple iBeacon? Yes it can

    Bluetooth LE incorporates a protocol for beacon devices to identify themselves. Each sends out a short packet of data "advertising" which can contain up to 31 bytes of user-defined data. Apple’s iBeacon specification, such as it is, stores four values in this space: a “Proximity” 128-bit UUID and two 16-bit numbers, “Major” and “Minor”.
    Apple has a good example of how these variables are used: a department store chain - Macy’s, say - adopts a single UUID for all its beacons. It uses the value of the Major variable to distinguish one shop from another, and the value of the Minor variable to differentiate between beacons in one shop’s departments.
    Not all Bluetooth dongles are Linux-friendly. A handy resource listing well-behaving ones can be found at the Embedded Linux Wiki. A branded one will set you back around a tenner, generic ones less. I used IoGear’s GBU521.
    Next, prepare your Pi. You need to install the official Linux Bluetooth software stack, BlueZ, and various USB development packages, some using the apt-get tool at the command line, others by compiling the code.
    First run this:
    sudo apt-get install libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev
    Next install BlueZ’s source files and compile it. The version at the time of writing was 5.11.
    sudo wget www.kernel.org/pub/linux/bluetooth/bluez-5.11.tar.xzsudo unxz bluez-5.11.tar.xzsudo tar xvf bluez-5.11.tarcd bluez-5.11sudo ./configure --disable-systemdsudo makesudo make install
    This will take a while, but when it’s done, you can reboot and plug in the dongle.

    Decoding the iBeacon protocol

    There’s no version of the uuidgen utility readily available for the Pi, so I used this website. The 16 pairs of two-digit hexadecimal values - each pair is dubbed an "octet" in the jargon - along with Major and Minor pair of octets, need to be punched into the Pi’s Bluetooth sub-system using BlueZ’s hcitool utility:
    sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 [ 92 77 83 0A B2 EB 49 0F A1 DD 7F E3 8C 49 2E DE ] [ 00 00 ] [ 00 00 ] C5 00
    Note that the square brackets are NOT part of the command - I’ve added them solely to show where the UUID, Major then Minor codes go. The ‘C5’ after them is a value representing transmitted power level. Just cut and paste the line above and replace the UUID with your own.

    2.jpg
    Not all Bluetooth dongles are Pi pals

    This is how you decode the command: the "hci0" identifies your Bluetooth dongle, "cmd" tells hcitool to send the following command data to the device. The "0x08" is the Bluetooth command group - the "OGF" in the official parlance - and "0x0008" is the specific command ("OCF"), HCI_LE_Set_Advertising_Data.
    The first "1E" is the number of significantoctets in the advertising data that follow, up to a maximum of 31. The non-significant part should only comprise pairs of zeroes to take the number of octets up to 31 and which, to save power, are not transmitted.
    The ad data is split into groups, each formatted with a single octet providing the number of remaining octets in the group - essentially it tells the Bluetooth sub-system how further along the list of octets is the next group. Its followed by a single octet which defines the type of data, and then any number of octets holding the data itself. You can put as many of these groups into the advertising data packet as you can fit into the 31 octets allowed.
    In my example, the first "02" in the sequence says the first block of ad data is two octets long. The next octet, "01" says the advertising octet(s) following are Bluetooth flags, and the "1A" is the binary value derived when certain of those flags are set.
    1Asays the next group is 26 octets long, and the "FF" identifies the group as manufacturer-specific data. The Bluetooth 4.0 specification says the next two octets have to expose the manufacturer: the "4C 00" is Apples Bluetooth manufacturer ID.


    3.jpg
    In the Zone: location notification on a Metawatch smartwatch
    Im not yet sure what the "02" and "15" signify, but as I say, the Proximity UUID, Major and Minor values, and the power level complete the 26 octets of manufacturer data - and the 30 octets of the entire advertising data.
    The hcitool command formats the iBeacon advertising signal. Telling the Pi to begin sending out that signal requires the following command:
    sudo hciconfig hci0 leadv
    You can disable LE beacon activity with the command:
    sudo hciconfig hci0 noleadv
    Update If you dont see your beacon after issuing the leadv command, try sudo hciconfig hci0 noscan which stops the dongle looking for other Bluetooth devices. This can interfere with the beacon operation.
    And its an obvious next step to create scripts to set all this up and activate LE advertising whenever the Pi boots up, but I wont be covering that here. If youd like to do that, theres a very good tutorial written by Washington DC-based Radius Networks here.

    Building a beacon monitor app

    If youd just like to cut to the chase and start coding iBeacon support into apps, Radius is selling pre-configured Pis as iBeacon development kits with one or two on-board dongles. Prices start at $100 (£61).
    With the Pi running as a beacon, the next stage is to create an app that will look for it and notify you when youre there. I chose to work up an iOS app - Im exploring Apples iBeacon, after all - but it should be possible to code it up in Android 4.3, which added Bluetooth LE support to the Google OS.
    Apple added it to iOS 7, released back in September. iOSs existing CoreLocation framwork defines a CLLocationManager class that provides an interface for detecting iBeacons and a mechanism for dealing with events triggered by moving into and out a beacons zone of coverage, an extension of CLLocationManagers already available ability to work with geographical regions.
    CLLocationManager also defines methods for checking whether the device the app is running on has an OS and hardware able to handle Bluetooth LE: [CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]] returns a Boolean true if the device is beacon savvy.
    Pass that test and a well-behaved app will then double-check that iOSLocation Services have been enabled and that the app has permission to access them. It can then start looking for beacons with the Proximity UUID, Major and Minor values punched into the Pi earlier:
    {
        ...

        CLBeaconRegion *beaconRegion;
        NSUUID *beaconUUID;
        NSString *beaconIdent;

        ...

        beaconUUID = [[NSUUID alloc] initWithUUIDString: @"9277830A-B2EB-490F-A1DD-7FE38C492EDE"];
        beaconIdent = @"Vulture.Zone.1";
        beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID major:0 minor:0 identifier:beaconIdent];

        ...

        [appLocationManager startMonitoringForRegion:beaconRegion];

        ...
    }

    CoreLocation provides two handy delegate methods for dealing with events triggered by the beacon monitor: - (void)locationManager: (CLLocationManager *)manager didEnterRegion: (CLRegion *)region and - (void)locationManager: (CLLocationManager *)manager didExitRegion: (CLRegion *)region. The object that owns the CLLocationManager must adhere to the CLLocationManagerDelegate protocol if its to receive these messages.
    These two methods provide an easy way to alert the user he or she has entered the zone and to trigger actions accordingly. My test app, for instance, grabs a block of HTML code from El Regs server and presents it in a UIWebView: Special Offer! The Editor will buy you a pint if you present this code..., that kind of thing.


    4.jpg
    Running the app: Were too far away (left) but then...

    iOS scans for regions even when the app that initiated the monitoring isnt running. The app is automatically run in the background if the beacon is detected in those circumstances. Likewise, its woken from sleep if it is merely napping. You can control whether messages triggered when beacon region boundaries are crossed are delayed while the iDevices screen is off: the CLBeaconRegion object created above has a Boolean property, notifyEntryStateOnDisplay, you can use to enable this behaviour. It also has a Boolean property called notifyOnEntry, inherited from CLBeaconRegions superclass CLRegion, which youll need to set to NO in this case.
    Once the phone knows its inside a beacons sphere of influence, the app can call the - (void)locationManager:   (CLLocationManager *)manager didRangeBeacons: (NSArray *)beacons inRegion:  (CLBeaconRegion *)region method to get a list of nearby beacons and from each entry, a beacons UUID, Major and Minor values to help identify which they are and, thanks to each beacons proximity property, roughly how close it is.
    To keep things tidy, I added an switch to disable beacon scanning. By way of inter-object notifications, it calls [appLocationManager stopMonitoringForRegion:beaconRegion] to take the currently defined beacon off the system-wide monitoring list.


    5.jpg
    ...and heres a message from our (nearby) sponsor

    Once all this is up and running, and the Pi-hosted iBeacon is operating in the background, its easy to test the system by walking out of range of the beacon and then turning round and coming back.
    Android users keen to try this out without coding their own beacon detector can check out Radius NetworksiBeacon Locate app in Google Play. Theres an iOS version in iTunes too. Radius also has an open-source library of iBeacon compatibility code for Android if you want to incorporate iBeacon support into an app of your own.



    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2012-11-23 16:50
  • 签到天数: 15 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2014-2-14 10:18:30 | 显示全部楼层
    iBeacon这是好应用,不过现在实用性还差一点,期待进一步的发展
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2014-2-28 13:06:06 | 显示全部楼层
    iBeacon这是好应用,不过现在实用性还差一点,期待进一步的发展
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-5-9 10:56 , Processed in 0.167273 second(s), 26 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.