scan_beacon 0.6.8 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +19 -9
- data/ext/core_bluetooth/core_bluetooth.m +60 -0
- data/ext/core_bluetooth/extconf.rb +1 -0
- data/lib/scan_beacon/beacon.rb +2 -2
- data/lib/scan_beacon/beacon_parser.rb +14 -4
- data/lib/scan_beacon/ble112_advertiser.rb +1 -1
- data/lib/scan_beacon/ble112_device.rb +3 -19
- data/lib/scan_beacon/bluez_advertiser.rb +1 -0
- data/lib/scan_beacon/bluez_scanner.rb +1 -0
- data/lib/scan_beacon/core_bluetooth_advertiser.rb +27 -0
- data/lib/scan_beacon/core_bluetooth_scanner.rb +1 -0
- data/lib/scan_beacon/eddystone_url_beacon.rb +72 -0
- data/lib/scan_beacon/generic_advertiser.rb +3 -2
- data/lib/scan_beacon/version.rb +1 -1
- data/lib/scan_beacon.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b38f927f67bef75a626e0509245b4588b7cd62a
|
4
|
+
data.tar.gz: 6bffd5d1c56c0a5c560d1c403d66898ac9ec1053
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da91c39c519a4d065c0ad22f29bb4d876350ecb03cfda92b13907f0bf5953df5e45e788742c81e590123c612ec6d9c4b9b40fa282559d0f61ffc75475a8b8ba5
|
7
|
+
data.tar.gz: 3840835c733003843718246959c5d76c913a44f70f0b0f7dbe35827b2a317bfcb0b16db9c6774d6abdf511c6caa5eff1bbe77c54c48d3b04c88bff6622eb81c1
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# ScanBeacon gem
|
2
2
|
|
3
|
-
A ruby gem that allows you to scan for beacon advertisements using
|
3
|
+
A ruby gem that allows you to scan for beacon advertisements using IOBluetooth (on Mac OS X) or a BlueGiga BLE112 device (on mac or linux)
|
4
4
|
|
5
5
|
# Example Usage
|
6
6
|
|
@@ -13,12 +13,14 @@ gem install scan_beacon
|
|
13
13
|
## Create your scanner
|
14
14
|
``` ruby
|
15
15
|
require 'scan_beacon'
|
16
|
+
# to scan using the default device on mac or linux
|
17
|
+
scanner = ScanBeacon::DefaultScanner.new
|
16
18
|
# to scan using CoreBluetooth on a mac
|
17
19
|
scanner = ScanBeacon::CoreBluetoothScanner.new
|
18
|
-
# to scan using a BLE112 device
|
19
|
-
scanner = ScanBeacon::BLE112Scanner.new
|
20
20
|
# to scan using BlueZ on Linux (make sure you have privileges)
|
21
21
|
scanner = ScanBeacon::BlueZScanner.new
|
22
|
+
# to scan using a BLE112 device
|
23
|
+
scanner = ScanBeacon::BLE112Scanner.new
|
22
24
|
```
|
23
25
|
|
24
26
|
## Start a scan, yield beacons in a loop
|
@@ -57,7 +59,7 @@ scanner.add_parser( ScanBeacon::BeaconParser.new(:mybeacon, "m:2-3=0000,i:4-19,i
|
|
57
59
|
...
|
58
60
|
```
|
59
61
|
|
60
|
-
## Advertise as a beacon on Linux using BlueZ
|
62
|
+
## Advertise as a beacon on Linux using BlueZ or a Mac using IOBluetooth
|
61
63
|
Example:
|
62
64
|
``` ruby
|
63
65
|
# altbeacon
|
@@ -67,7 +69,7 @@ beacon = ScanBeacon::Beacon.new(
|
|
67
69
|
mfg_id: 0x0118,
|
68
70
|
beacon_type: :altbeacon
|
69
71
|
)
|
70
|
-
advertiser = ScanBeacon::
|
72
|
+
advertiser = ScanBeacon::DefaultAdvertiser.new(beacon: beacon)
|
71
73
|
advertiser.start
|
72
74
|
...
|
73
75
|
advertiser.stop
|
@@ -79,7 +81,17 @@ beacon = ScanBeacon::Beacon.new(
|
|
79
81
|
service_uuid: 0xFEAA,
|
80
82
|
beacon_type: :eddystone_uid
|
81
83
|
)
|
82
|
-
advertiser = ScanBeacon::
|
84
|
+
advertiser = ScanBeacon::DefaultAdvertiser.new(beacon: beacon)
|
85
|
+
advertiser.start
|
86
|
+
...
|
87
|
+
advertiser.stop
|
88
|
+
|
89
|
+
# Eddystone URL (PhysicalWeb)
|
90
|
+
beacon = ScanBeacon::EddystoneUrlBeacon.new(
|
91
|
+
url: "http://radiusnetworks.com",
|
92
|
+
power: -20,
|
93
|
+
)
|
94
|
+
advertiser = ScanBeacon::DefaultAdvertiser.new(beacon: beacon)
|
83
95
|
advertiser.start
|
84
96
|
...
|
85
97
|
advertiser.stop
|
@@ -87,6 +99,4 @@ advertiser.stop
|
|
87
99
|
|
88
100
|
|
89
101
|
# Dependencies
|
90
|
-
To scan for beacons, 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).
|
91
|
-
|
92
|
-
To advertise as a beacon, you must have a Linux machine with BlueZ installed.
|
102
|
+
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).
|
@@ -3,6 +3,7 @@
|
|
3
3
|
// Include the Ruby headers and goodies
|
4
4
|
#include "ruby.h"
|
5
5
|
#import <Foundation/Foundation.h>
|
6
|
+
#import <IOBluetooth/IOBluetooth.h>
|
6
7
|
#import <CoreBluetooth/CoreBluetooth.h>
|
7
8
|
|
8
9
|
// Defining a space for information and references about the module to be stored internally
|
@@ -14,6 +15,19 @@ VALUE method_scan();
|
|
14
15
|
VALUE method_new_adverts();
|
15
16
|
VALUE new_scan_hash(NSString* device, NSData *data, NSNumber *rssi, NSData *service_uuid);
|
16
17
|
|
18
|
+
VALUE method_set_advertisement_data(VALUE klass, VALUE data);
|
19
|
+
VALUE method_start_advertising();
|
20
|
+
VALUE method_stop_advertising();
|
21
|
+
|
22
|
+
// define some hidden methods so we can call them more easily
|
23
|
+
@interface IOBluetoothHostController ()
|
24
|
+
- (int)BluetoothHCILESetAdvertiseEnable:(unsigned char)arg1;
|
25
|
+
- (int)BluetoothHCILESetAdvertisingData:(unsigned char)arg1 advertsingData:(char *)arg2;
|
26
|
+
- (int)BluetoothHCILESetAdvertisingParameters:(unsigned short)arg1 advertisingIntervalMax:(unsigned short)arg2 advertisingType:(unsigned char)arg3 ownAddressType:(unsigned char)arg4 directAddressType:(unsigned char)arg5 directAddress:(struct BluetoothDeviceAddress { unsigned char x1[6]; }*)arg6 advertisingChannelMap:(unsigned char)arg7 advertisingFilterPolicy:(unsigned char)arg8;
|
27
|
+
- (int)BluetoothHCILESetScanParameters:(unsigned char)arg1 LEScanInterval:(unsigned short)arg2 LEScanWindow:(unsigned short)arg3 ownAddressType:(unsigned char)arg4 scanningFilterPolicy:(unsigned char)arg5;
|
28
|
+
- (int)BluetoothHCILESetScanEnable:(unsigned char)arg1 filterDuplicates:(unsigned char)arg2;
|
29
|
+
@end
|
30
|
+
|
17
31
|
@interface BLEDelegate : NSObject <CBCentralManagerDelegate> {
|
18
32
|
@private
|
19
33
|
NSMutableArray *_scans;
|
@@ -61,6 +75,15 @@ VALUE new_scan_hash(NSString* device, NSData *data, NSNumber *rssi, NSData *serv
|
|
61
75
|
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
|
62
76
|
{
|
63
77
|
[central scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @(YES)}];
|
78
|
+
|
79
|
+
// set custom scan params to achieve better scanning performance
|
80
|
+
IOBluetoothHostController * device = IOBluetoothHostController.defaultController;
|
81
|
+
[device BluetoothHCILESetScanParameters:0x01
|
82
|
+
LEScanInterval:200
|
83
|
+
LEScanWindow:200
|
84
|
+
ownAddressType:0x00
|
85
|
+
scanningFilterPolicy:0x00];
|
86
|
+
[device BluetoothHCILESetScanEnable:0x01 filterDuplicates:0x00];
|
64
87
|
}
|
65
88
|
|
66
89
|
- (NSArray *) scans
|
@@ -90,6 +113,10 @@ void Init_core_bluetooth()
|
|
90
113
|
rb_define_singleton_method(cb_module, "scan", method_scan, 0);
|
91
114
|
rb_define_singleton_method(cb_module, "new_adverts", method_new_adverts, 0);
|
92
115
|
|
116
|
+
rb_define_singleton_method(cb_module, "set_advertisement_data", method_set_advertisement_data, 1);
|
117
|
+
rb_define_singleton_method(cb_module, "start_advertising", method_start_advertising, 0);
|
118
|
+
rb_define_singleton_method(cb_module, "stop_advertising", method_stop_advertising, 0);
|
119
|
+
|
93
120
|
sym_device = ID2SYM(rb_intern("device"));
|
94
121
|
sym_data = ID2SYM(rb_intern("data"));
|
95
122
|
sym_rssi = ID2SYM(rb_intern("rssi"));
|
@@ -149,4 +176,37 @@ VALUE method_scan()
|
|
149
176
|
return Qnil;
|
150
177
|
}
|
151
178
|
|
179
|
+
VALUE method_set_advertisement_data(VALUE klass, VALUE data)
|
180
|
+
{
|
181
|
+
IOBluetoothHostController *device = [IOBluetoothHostController defaultController];
|
182
|
+
char flags_and_data[40];
|
183
|
+
memcpy(flags_and_data, "\x02\x01\x1A", 3);
|
184
|
+
memcpy(flags_and_data+3, RSTRING_PTR(data), RSTRING_LEN(data));
|
185
|
+
// NOTE: Mac OS X has a typo in the method definition. This may get fixed in the future.
|
186
|
+
[device BluetoothHCILESetAdvertisingData: RSTRING_LEN(data)+3 advertsingData: flags_and_data];
|
187
|
+
return Qnil;
|
188
|
+
}
|
189
|
+
|
190
|
+
VALUE method_start_advertising()
|
191
|
+
{
|
192
|
+
IOBluetoothHostController *device = [IOBluetoothHostController defaultController];
|
193
|
+
[device BluetoothHCILESetAdvertisingParameters: 0x00A0
|
194
|
+
advertisingIntervalMax: 0x00A0 // 100ms
|
195
|
+
advertisingType: 0x03
|
196
|
+
ownAddressType: 0x00
|
197
|
+
directAddressType: 0x00
|
198
|
+
directAddress: (void*)"\x00\x00\x00\x00\x00\x00"
|
199
|
+
advertisingChannelMap: 0x07 // all 3 channels
|
200
|
+
advertisingFilterPolicy: 0x00];
|
201
|
+
[device BluetoothHCILESetAdvertiseEnable: 1];
|
202
|
+
return Qnil;
|
203
|
+
}
|
204
|
+
|
205
|
+
VALUE method_stop_advertising()
|
206
|
+
{
|
207
|
+
IOBluetoothHostController *device = [IOBluetoothHostController defaultController];
|
208
|
+
[device BluetoothHCILESetAdvertiseEnable: 0];
|
209
|
+
return Qnil;
|
210
|
+
}
|
211
|
+
|
152
212
|
#endif // TARGET_OS_MAC
|
@@ -10,6 +10,7 @@ dir_config(extension_name)
|
|
10
10
|
if RUBY_PLATFORM =~ /darwin/
|
11
11
|
$DLDFLAGS << " -framework Foundation"
|
12
12
|
$DLDFLAGS << " -framework CoreBluetooth"
|
13
|
+
$DLDFLAGS << " -framework IOBluetooth"
|
13
14
|
else
|
14
15
|
# don't compile the code on non-mac platforms because
|
15
16
|
# CoreBluetooth wont be there, and we may not even have
|
data/lib/scan_beacon/beacon.rb
CHANGED
@@ -3,7 +3,7 @@ require 'set'
|
|
3
3
|
module ScanBeacon
|
4
4
|
class Beacon
|
5
5
|
|
6
|
-
attr_accessor :mac, :ids, :power, :beacon_types, :data, :mfg_id, :service_uuid
|
6
|
+
attr_accessor :mac, :ids, :power, :beacon_types, :data, :mfg_id, :service_uuid, :rssis
|
7
7
|
|
8
8
|
def initialize(opts={})
|
9
9
|
@ids = opts[:ids] || []
|
@@ -12,7 +12,7 @@ module ScanBeacon
|
|
12
12
|
@mfg_id = opts[:mfg_id]
|
13
13
|
@service_uuid = opts[:service_uuid]
|
14
14
|
@beacon_types = Set.new [opts[:beacon_type]]
|
15
|
-
@rssis = []
|
15
|
+
@rssis = opts[:rssis] || []
|
16
16
|
end
|
17
17
|
|
18
18
|
def ==(obj)
|
@@ -2,7 +2,8 @@ module ScanBeacon
|
|
2
2
|
class BeaconParser
|
3
3
|
DEFAULT_LAYOUTS = {
|
4
4
|
altbeacon: "m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25",
|
5
|
-
eddystone_uid: "s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19;d:20-21"
|
5
|
+
eddystone_uid: "s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19;d:20-21",
|
6
|
+
eddystone_url: "s:0-1=feaa,m:2-2=10,p:3-3:-41,i:4-21v",
|
6
7
|
}
|
7
8
|
AD_TYPE_MFG = 0xff
|
8
9
|
AD_TYPE_SERVICE = 0x03
|
@@ -36,6 +37,9 @@ module ScanBeacon
|
|
36
37
|
end: range_end.to_i,
|
37
38
|
length: range_end.to_i - range_start.to_i + 1,
|
38
39
|
}
|
40
|
+
if range_end.end_with? 'v'
|
41
|
+
field_params[:var_length] = true
|
42
|
+
end
|
39
43
|
field_params[:expected] = [expected].pack("H*") unless expected.nil?
|
40
44
|
case field_type
|
41
45
|
when 'm'
|
@@ -100,14 +104,19 @@ module ScanBeacon
|
|
100
104
|
end
|
101
105
|
|
102
106
|
def generate_ad(beacon)
|
103
|
-
length = [@matchers, @ids, @power, @data_fields].flatten.map {|elem| elem[:
|
107
|
+
length = [@matchers, @ids, @power, @data_fields].flatten.map {|elem| elem[:start] }.max + 1
|
104
108
|
ad = ("\x00" * length).force_encoding("ASCII-8BIT")
|
105
109
|
@matchers.each do |matcher|
|
106
110
|
ad[matcher[:start]..matcher[:end]] = matcher[:expected]
|
107
111
|
end
|
108
112
|
@ids.each_with_index do |id, index|
|
109
|
-
|
110
|
-
|
113
|
+
if id[:var_length]
|
114
|
+
id_bytes = Beacon::Field.new(hex: beacon.ids[index]).bytes
|
115
|
+
ad[id[:start]..id[:start]+id_bytes.size] = id_bytes
|
116
|
+
else
|
117
|
+
id_bytes = Beacon::Field.field_with_length(beacon.ids[index], id[:length]).bytes
|
118
|
+
ad[id[:start]..id[:end]] = id_bytes
|
119
|
+
end
|
111
120
|
end
|
112
121
|
@data_fields.each_with_index do |field, index|
|
113
122
|
unless beacon.data[index].nil?
|
@@ -116,6 +125,7 @@ module ScanBeacon
|
|
116
125
|
end
|
117
126
|
end
|
118
127
|
ad[@power[:start]..@power[:end]] = [beacon.power].pack('c')
|
128
|
+
length = ad.size
|
119
129
|
if @ad_type == AD_TYPE_SERVICE
|
120
130
|
"\x03\x03".force_encoding("ASCII-8BIT") + [beacon.service_uuid].pack("S<") + [length+1].pack('C') + BT_EIR_SERVICE_DATA + ad
|
121
131
|
elsif @ad_type == AD_TYPE_MFG
|
@@ -137,26 +137,10 @@ module ScanBeacon
|
|
137
137
|
device_count = possible_devices.count
|
138
138
|
possible_devices.each do |device_path|
|
139
139
|
File.open(device_path, 'r+b') do |file|
|
140
|
-
file.write([BG_COMMAND,
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
# wait for them to show up again, but only wait for up to 5 secs
|
145
|
-
sleep 1
|
146
|
-
wait_count = 0
|
147
|
-
while possible_devices.count < device_count && wait_count < 50
|
148
|
-
sleep 0.1
|
149
|
-
wait_count += 1
|
150
|
-
end
|
151
|
-
|
152
|
-
# try to open them - if we get a busy, wait and try again
|
153
|
-
possible_devices.each do |device_path|
|
154
|
-
begin
|
155
|
-
File.open(device_path, 'r+b') {|f| f.close }
|
156
|
-
rescue Errno::EBUSY
|
157
|
-
sleep 0.1
|
158
|
-
retry
|
140
|
+
file.write([BG_COMMAND, 0, BG_MSG_CLASS_GAP, BG_DISCOVER_STOP].pack('C*'))
|
159
141
|
end
|
142
|
+
# open and close the file to clear the buffer
|
143
|
+
File.open(device_path, 'r+b') {|file| }
|
160
144
|
end
|
161
145
|
end
|
162
146
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ScanBeacon
|
2
|
+
class CoreBluetoothAdvertiser < GenericIndividualAdvertiser
|
3
|
+
|
4
|
+
def initialize(opts = {})
|
5
|
+
super
|
6
|
+
end
|
7
|
+
|
8
|
+
def ad=(value)
|
9
|
+
@ad = value
|
10
|
+
CoreBluetooth.set_advertisement_data @ad
|
11
|
+
end
|
12
|
+
|
13
|
+
def start
|
14
|
+
CoreBluetooth.start_advertising
|
15
|
+
end
|
16
|
+
|
17
|
+
def stop
|
18
|
+
CoreBluetooth.stop_advertising
|
19
|
+
end
|
20
|
+
|
21
|
+
def inspect
|
22
|
+
"<CoreBluetoothAdvertiser ad=#{@ad.inspect}>"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
DefaultAdvertiser = CoreBluetoothAdvertiser
|
27
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module ScanBeacon
|
2
|
+
# Convenience class for constructing & advertising Eddystone-URL frames
|
3
|
+
class EddystoneUrlBeacon < Beacon
|
4
|
+
|
5
|
+
SCHEMES = {"http://www." => "\x00",
|
6
|
+
"https://www." => "\x01",
|
7
|
+
"http://" => "\x02",
|
8
|
+
"https://" => "\x03"}
|
9
|
+
|
10
|
+
EXPANSIONS = {".com/" => "\x00",
|
11
|
+
".org/" => "\x01",
|
12
|
+
".edu/" => "\x02",
|
13
|
+
".net/" => "\x03",
|
14
|
+
".info/" => "\x04",
|
15
|
+
".biz/" => "\x05",
|
16
|
+
".gov/" => "\x06",
|
17
|
+
".com" => "\x07",
|
18
|
+
".org" => "\x08",
|
19
|
+
".edu" => "\x09",
|
20
|
+
".net" => "\x0a",
|
21
|
+
".info" => "\x0b",
|
22
|
+
".biz" => "\x0c",
|
23
|
+
".gov" => "\x0d"}
|
24
|
+
|
25
|
+
def initialize(opts = {})
|
26
|
+
opts[:service_uuid] ||= 0xFEAA
|
27
|
+
opts[:beacon_type] ||= :eddystone_url
|
28
|
+
super opts
|
29
|
+
self.url = opts[:url] if opts[:url]
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.from_beacon(beacon)
|
33
|
+
new(ids: beacon.ids, power: beacon.power, rssis: beacon.rssis)
|
34
|
+
end
|
35
|
+
|
36
|
+
def url
|
37
|
+
@url ||= self.class.decompress_url( self.ids[0].to_s )
|
38
|
+
end
|
39
|
+
|
40
|
+
def url=(new_url)
|
41
|
+
@url = new_url
|
42
|
+
self.ids = [self.class.compress_url(@url)]
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.compress_url(url)
|
46
|
+
scheme, scheme_code = SCHEMES.find {|k, v| url.start_with? k}
|
47
|
+
raise ArgumentError, "Invalid URL" if scheme.nil?
|
48
|
+
compressed_url = scheme_code + url[scheme.size..-1]
|
49
|
+
EXPANSIONS.each do |k,v|
|
50
|
+
compressed_url.gsub! k,v
|
51
|
+
end
|
52
|
+
raise ArgumentError, "URL too long" if compressed_url.size > 18
|
53
|
+
compressed_url.force_encoding("ASCII-8BIT").unpack("H*")[0]
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.decompress_url(hex)
|
57
|
+
compressed_url_string = [hex].pack("H*")
|
58
|
+
scheme_code = compressed_url_string[0]
|
59
|
+
scheme, scheme_code = SCHEMES.find {|k,v| v == scheme_code}
|
60
|
+
raise ArgumentError, "Invalid URL" if scheme.nil?
|
61
|
+
decompressed_url = scheme + compressed_url_string[1..-1]
|
62
|
+
EXPANSIONS.each do |k,v|
|
63
|
+
decompressed_url.gsub! v,k
|
64
|
+
end
|
65
|
+
decompressed_url
|
66
|
+
end
|
67
|
+
|
68
|
+
def inspect
|
69
|
+
"<EddystoneUrlBeacon url=\"#{url}\" rssi=#{rssi}, scans=#{ad_count}, power=#{@power}>"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -6,12 +6,13 @@ module ScanBeacon
|
|
6
6
|
def initialize(opts = {})
|
7
7
|
self.beacon = opts[:beacon]
|
8
8
|
self.parser = opts[:parser]
|
9
|
+
self.ad = opts[:ad] if opts[:ad]
|
9
10
|
if beacon
|
10
11
|
self.parser ||= BeaconParser.default_parsers.find {|parser| parser.beacon_type == beacon.beacon_types.first}
|
11
12
|
end
|
12
13
|
@advertising = false
|
13
14
|
end
|
14
|
-
|
15
|
+
|
15
16
|
def start(with_rotation = false)
|
16
17
|
raise NotImplementedError
|
17
18
|
end
|
@@ -24,4 +25,4 @@ module ScanBeacon
|
|
24
25
|
raise NotImplementedError
|
25
26
|
end
|
26
27
|
end
|
27
|
-
end
|
28
|
+
end
|
data/lib/scan_beacon/version.rb
CHANGED
data/lib/scan_beacon.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "scan_beacon/version"
|
2
2
|
require "scan_beacon/beacon"
|
3
|
+
require "scan_beacon/eddystone_url_beacon"
|
3
4
|
require "scan_beacon/beacon/field"
|
4
5
|
require "scan_beacon/beacon_parser"
|
5
6
|
require "scan_beacon/generic_scanner"
|
@@ -12,6 +13,7 @@ case RUBY_PLATFORM
|
|
12
13
|
when /darwin/
|
13
14
|
require "scan_beacon/core_bluetooth"
|
14
15
|
require "scan_beacon/core_bluetooth_scanner"
|
16
|
+
require "scan_beacon/core_bluetooth_advertiser"
|
15
17
|
when /linux/
|
16
18
|
require "scan_beacon/bluez"
|
17
19
|
require "scan_beacon/bluez_scanner"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scan_beacon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Radius Networks
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -99,7 +99,9 @@ files:
|
|
99
99
|
- lib/scan_beacon/ble112_scanner.rb
|
100
100
|
- lib/scan_beacon/bluez_advertiser.rb
|
101
101
|
- lib/scan_beacon/bluez_scanner.rb
|
102
|
+
- lib/scan_beacon/core_bluetooth_advertiser.rb
|
102
103
|
- lib/scan_beacon/core_bluetooth_scanner.rb
|
104
|
+
- lib/scan_beacon/eddystone_url_beacon.rb
|
103
105
|
- lib/scan_beacon/generic_advertiser.rb
|
104
106
|
- lib/scan_beacon/generic_individual_advertiser.rb
|
105
107
|
- lib/scan_beacon/generic_scanner.rb
|