GithubHelp home page GithubHelp logo

scanbeacon-gem's Introduction

ScanBeacon gem

A ruby gem that allows you to scan for beacon advertisements using IOBluetooth (on Mac OS X), BlueZ (on Linux), or a BlueGiga BLE112 device (on mac or linux)

Example Usage

Install the gem

gem install scan_beacon

Tips for installing & using on Ubuntu

Create your scanner

require 'scan_beacon'
# to scan using the default device on mac or linux
scanner = ScanBeacon::DefaultScanner.new
# to scan using CoreBluetooth on a mac
scanner = ScanBeacon::CoreBluetoothScanner.new
# to scan using BlueZ on Linux (make sure you have privileges)
scanner = ScanBeacon::BlueZScanner.new
# to scan using a BLE112 device
scanner = ScanBeacon::BLE112Scanner.new

Start a scan, yield beacons in a loop

scanner.scan do |beacons|
  beacons.each do |beacon|
    puts beacon.inspect
  end
end

Set a specific scan cycle period

require 'scan_beacon'
scanner = ScanBeacon::BLE112Scanner.new cycle_seconds: 5
scanner.scan do |beacons|
  beacons.each do |beacon|
    puts beacon.inspect
  end
end

Scan once for a set period and then return an array of beacons

scanner = ScanBeacon::CoreBluetoothScanner.new cycle_seconds: 2
beacons = scanner.scan

Add a custom beacon layout

By default, this gem supports AltBeacon and Eddystone advertisements. But you can add a beacon parser to support other major beacon formats as well.

Example:

scanner = ScanBeacon::BLE112Scanner.new
scanner.add_parser( ScanBeacon::BeaconParser.new(:mybeacon, "m:2-3=0000,i:4-19,i:20-21,i:22-23,p:24-24") )
...

Advertise as a beacon on Linux using BlueZ or a Mac using IOBluetooth

Example:

# altbeacon
beacon = ScanBeacon::Beacon.new(
  ids: ["2F234454CF6D4A0FADF2F4911BA9FFA6", 11,11],
  power: -59,
  mfg_id: 0x0118,
  beacon_type: :altbeacon
)
advertiser = ScanBeacon::DefaultAdvertiser.new(beacon: beacon)
advertiser.start
...
advertiser.stop

# Eddystone UID
beacon = ScanBeacon::Beacon.new(
  ids: ["2F234454F4911BA9FFA6", 3],
  power: -20,
  service_uuid: 0xFEAA,
  beacon_type: :eddystone_uid
)
advertiser = ScanBeacon::DefaultAdvertiser.new(beacon: beacon)
advertiser.start
...
advertiser.stop

# Eddystone URL (PhysicalWeb)
beacon = ScanBeacon::EddystoneUrlBeacon.new(
  url: "http://radiusnetworks.com",
  power: -20,
)
advertiser = ScanBeacon::DefaultAdvertiser.new(beacon: beacon)
advertiser.start
...
advertiser.stop

Dependencies

To scan for beacons or advertise, you must have a Linux machine with BlueZ installed, or a Mac, or a BLE112 device plugged in to a USB port (on Mac or Linux).

scanbeacon-gem's People

Contributors

cupakromer avatar davemradnet avatar davidgyoung avatar syoder avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scanbeacon-gem's Issues

Segmentation fault in CoreBluetooth::new_adverts

Hi,

I'm trying your scan_beacon gem. It works fine with Linux. Thanks.
However, I get segmentation faults with Mac (both Mavericks and Sierra).
Gem version is 0.7.10. When I run this simple script:

require 'scan_beacon'

while true
  i = 0
  ScanBeacon::CoreBluetooth::scan do
    advertisements = ScanBeacon::CoreBluetooth::new_adverts
    advertisements.each do |scan|
      data = scan[:data].unpack("C*").map{|c| "%02X" % c}.join
      puts "#{i} #{data}"
      i += 1
    end
  end
  # Sleep does not help
  # sleep 2
end

I get segv about several minutes later like this:

% bundle exec ruby ./beacon_scanner_mac_debug.rb
0 4C0009060200AC151030
(snip)
26 4C000215467FD32695D242F2BBBC5C8F4610B12000080000C9
27 4C0009060200AC151030
(snip)
780 4C0009060200AC151030
781 4C0009060200AC151030
./beacon_scanner_mac_debug.rb:6: [BUG] Segmentation fault at 0x00000000000000
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]

-- Crash Report log information --------------------------------------------
   See Crash Report log file under the one of following:
     * ~/Library/Logs/CrashReporter
     * /Library/Logs/CrashReporter
     * ~/Library/Logs/DiagnosticReports
     * /Library/Logs/DiagnosticReports
   for more details.
Don't forget to include the above Crash Report log file in bug reports.

-- Control frame information -----------------------------------------------
c:0005 p:---- s:0014 e:000013 CFUNC  :new_adverts
c:0004 p:0016 s:0011 e:000010 BLOCK  ./beacon_scanner_mac_debug.rb:6 [FINISH]
c:0003 p:---- s:0008 e:000007 CFUNC  :scan
c:0002 p:0035 s:0005 E:001d08 EVAL   ./beacon_scanner_mac_debug.rb:5 [FINISH]
c:0001 p:0000 s:0002 E:001b50 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
./beacon_scanner_mac_debug.rb:5:in `<main>'
./beacon_scanner_mac_debug.rb:5:in `scan'
./beacon_scanner_mac_debug.rb:6:in `block in <main>'
./beacon_scanner_mac_debug.rb:6:in `new_adverts'

-- Machine register context ------------------------------------------------
 rax: 0x0000000000000000 rbx: 0x0000000000000000 rcx: 0x0000000000000028
 rdx: 0x0000000000000000 rdi: 0x00007ff8a570ba20 rsi: 0x00007ff8a73a85a0
 rbp: 0x000070000af2fbd0 rsp: 0x000070000af2fb60  r8: 0x0000000000000001
  r9: 0x0000000000000000 r10: 0x00007ff8a5700000 r11: 0x0000000039194ccf
 r12: 0x0000000000000008 r13: 0x0000000000000002 r14: 0x00007ff8a572d010
 r15: 0x0fffffffffffffff rip: 0x00007fffcb19a0de rfl: 0x0000000000010246

-- C level backtrace information -------------------------------------------
0   ruby                                0x0000000107f6fb24 rb_vm_bugreport + 388
1   ruby                                0x0000000107e0a34a rb_bug_context + 490
2   ruby                                0x0000000107eddd33 sigsegv + 83
3   libsystem_platform.dylib            0x00007fffe066cbba _sigtramp + 26
4   CoreFoundation                      0x00007fffcb19a0de -[__NSArrayM insertObject:atIndex:] + 1198
5   ???                                 0x0000000000000005 0x0 + 5

-- Other runtime information -----------------------------------------------

* Loaded script: ./beacon_scanner_mac_debug.rb

* Loaded features:
(snip)

zsh: abort      bundle exec ruby ./beacon_scanner_mac_debug.rb

Eddystone UID layout?

I noticed the parser layout used for Eddystone UID, defined here as:

eddystone_uid: "s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19;d:20-21"

has a stray semi-colon in it before the data field instead of a comma. Here's how it's defined in the Android Beacon Library:

EDDYSTONE_UID_LAYOUT = "s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19";

Not sure it's a huge problem since the data field isn't used in the UID scheme, but I think the semi-colon throws off the parsing of the layout.

Problem Installing gem

HI,

I tried a straight install as per the readme but I got a compilation error. core_bluetooth.m:7:9: fatal error: 'CoreBluetooth/CoreBluetooth.h' file not found

I've googled a bit and there are hints that 'CoreBluetooth seem to only be includable through IOBluetooth' ( http://lists.apple.com/archives/bluetooth-dev/2013/May/msg00011.html ) but I've been unable to figure out how to apply this to the install.

Can you help at all ?

Thanks

Parsing advertisement data into elements

Hi there,

tl; dr: I want to offer making a contribution to the gem, in case you are interested and still maintaining it.

thanks for this gem, I am going to use it to scan custom BTLE advertisements I am sending out from an ESP32.

Since my custom advertisements were not yet supported, I first looked into BlueZScanner, to see how advertisements get parsed. While I could immediately see my advertisements using BlueZScanner.each_advertisement, the data looked off:

  • I could see the last few Bytes of my device identifier
  • after that came my custom payload (manufacturer data)

I noticed that the scanner is depending on fixed offsets in the ad_data, which seems to collide with my beacon announcing its device name.

I scribbled together some parsing code, which will (hopefully) correctly unpack the ad_data into separate AD elements:

def scan_with_elements(device_id)
  ScanBeacon::BlueZ.scan(device_id) do |mac, data, rssi|
    yield nil unless data

    elements = []
    while data.size > 0
      length, type = data.unpack('CC')
      elements << {
        type: type,
        data: data[2..length]
      }

      data = data[(length + 1)..-1]
    end
    yield mac, elements, rssi
  end
end

which gives me correct output for my beacon:

[{:type=>9, :data=>"NN Sensor"}, {:type=>255, :data=>"\xFF\xFF\x03\xD7\x00\x8A\x02"}]

Now to my question: Would you be interested in integrating that into your gem? In that case I would try to prepare a pull request that makes this parsing available. However, in case you are not interested, I'd just have a "local" method for my own project.

Disclaimer: I have my Bluetooth LE knowledge from blog articles and I am probably still not knowing all the relevant details...

Eddystone-TLM support - will follow? (not an issue of course)

Hi there and thanks for your work.

I'm currently experimenting with a Raspberry and some beacons with Eddystone format.
My progress would have been diminished if not for this project.

Are there any plans for adding support for Eddystone-TLM too?
It would be even more appreciated :).

Many thanks again,
Sergiu

Can't scan for iBeacon

I have a bunch of iBeacon in a room but when I run my script I don't see any one of them. I had a look at the gem and commented lines 76-78, now it works but I still get an exception sometimes.

Including dashes in uuid breaks advertisement

If you run code like below (note dashes in id1):

beacon = ScanBeacon::Beacon.new(
  ids: ["2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6", 11,11],
  power: -59,
  mfg_id: 0x0118,
  beacon_type: :altbeacon
)
advertiser = ScanBeacon::BlueZAdvertiser.new(beacon: beacon)
advertiser.start

It starts advertising, but the UUID is wrong. You cannot include dashes if you want it to work.

No hurry on fixing this, as there is an obvious workaround to remove dashes.

can not install scan_beacon on Mac OS X 10.10

admins-Mac-mini-4:~ root# gem install scan_beacon
Fetching: scan_beacon-0.5.6.gem (100%)
Building native extensions. This could take a while...
ERROR: Error installing scan_beacon:
ERROR: Failed to build gem native extension.

/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby extconf.rb

creating Makefile

make "DESTDIR="
compiling core_bluetooth.m
core_bluetooth.m:22:19: error: inconsistent number of instance variables specified
NSMutableArray __scans;
^
core_bluetooth.m:28:3: error: use of undeclared identifier '_scans'
_scans = [[NSMutableArray alloc] init];
^
core_bluetooth.m:42:19: error: use of undeclared identifier '_scans'
@synchronized(_scans) {
^
core_bluetooth.m:43:8: error: use of undeclared identifier '_scans'
[_scans addObject: scan];
^
core_bluetooth.m:53:19: error: use of undeclared identifier '_scans'
@synchronized(_scans) {
^
core_bluetooth.m:54:8: error: use of undeclared identifier '_scans'
[_scans addObject: scan];
^
core_bluetooth.m:67:17: error: use of undeclared identifier '_scans'
@synchronized(_scans) {
^
core_bluetooth.m:68:16: error: use of undeclared identifier '_scans'
scanCopy = _scans;
^
core_bluetooth.m:69:5: error: use of undeclared identifier '_scans'
scans = [[NSMutableArray alloc] init];
^
9 errors generated.
make: *
* [core_bluetooth.o] Error 1

Gem files will remain installed in /Library/Ruby/Gems/2.0.0/gems/scan_beacon-0.5.6 for inspection.
Results logged to /Library/Ruby/Gems/2.0.0/gems/scan_beacon-0.5.6/ext/core_bluetooth/gem_make.out
admins-Mac-mini-4:~ root# cd /

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.