Class: ScanBeacon::BLE112Device
- Inherits:
-
Object
- Object
- ScanBeacon::BLE112Device
- Defined in:
- lib/scan_beacon/ble112_device.rb
Defined Under Namespace
Classes: BLE112Response
Constant Summary collapse
- BG_COMMAND =
define a bunch of constants
0- BG_EVENT =
0x80- BG_MSG_CLASS_SYSTEM =
msg classes
0- BG_MSG_CLASS_CONNECTION =
3- BG_MSG_CLASS_GAP =
6- BG_RESET =
messages
0- BG_DISCONNECT =
0- BG_SET_MODE =
1- BG_GET_ADDRESS =
2- BG_GAP_SET_PRIVACY_FLAGS =
0- BG_GAP_SET_ADV_PARAM =
8- BG_GAP_SET_ADV_DATA =
9- BG_DISCOVER =
2- BG_DISCOVER_STOP =
4- BG_SCAN_PARAMS =
7- BG_GAP_DISCOVER_ALL =
constants/enums
2- BG_GAP_NON_DISCOVERABLE =
0- BG_GAP_NON_CONNECTABLE =
0- BG_GAP_USER_DATA =
4- BG_GAP_CONNECTABLE =
2
Class Method Summary collapse
Instance Method Summary collapse
- #configure_port ⇒ Object
- #get_addr ⇒ Object
-
#initialize(port = nil) ⇒ BLE112Device
constructor
A new instance of BLE112Device.
- #open ⇒ Object
- #read ⇒ Object
- #reset ⇒ Object
- #rotate_addr ⇒ Object
- #start_advertising(ad_data, privacy = false) ⇒ Object
- #start_scan ⇒ Object
- #stop_advertising ⇒ Object
- #stop_scan ⇒ Object
Constructor Details
#initialize(port = nil) ⇒ BLE112Device
Returns a new instance of BLE112Device.
38 39 40 |
# File 'lib/scan_beacon/ble112_device.rb', line 38 def initialize(port=nil) @port = port || BLE112Device.find_all.first end |
Class Method Details
.find_all ⇒ Object
30 31 32 33 34 35 36 |
# File 'lib/scan_beacon/ble112_device.rb', line 30 def self.find_all devices = Dir.glob("/dev/{cu.usbmodem,ttyACM}*") devices.select {|device_path| device = self.new(device_path) device.open{ device.get_addr } != nil } end |
Instance Method Details
#configure_port ⇒ Object
53 54 55 56 57 |
# File 'lib/scan_beacon/ble112_device.rb', line 53 def configure_port if RUBY_PLATFORM =~ /linux/ system("stty -F #{@port} 115200 raw -brkint -icrnl -imaxbel -opost -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke") end end |
#get_addr ⇒ Object
59 60 61 62 |
# File 'lib/scan_beacon/ble112_device.rb', line 59 def get_addr response = bg_command(@file, BG_MSG_CLASS_SYSTEM, BG_GET_ADDRESS) response[4..-1].reverse.unpack("H2:H2:H2:H2:H2:H2").join(":") if response.length == 10 end |
#open ⇒ Object
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/scan_beacon/ble112_device.rb', line 42 def open response = nil configure_port File.open(@port, 'r+b') do |file| @file = file response = yield(self) end @file = nil return response end |
#read ⇒ Object
114 115 116 |
# File 'lib/scan_beacon/ble112_device.rb', line 114 def read BLE112Response.new( bg_read(@file) ) end |
#reset ⇒ Object
118 119 120 121 122 123 124 125 |
# File 'lib/scan_beacon/ble112_device.rb', line 118 def reset open do @file.write([BG_COMMAND, 1, BG_MSG_CLASS_SYSTEM, BG_RESET, 0].pack('C*')) end # give time for the device to reboot. # TODO: figure out a way that doesn't involve sleeping arbitrarily. sleep 1 end |
#rotate_addr ⇒ Object
102 103 104 105 106 107 108 |
# File 'lib/scan_beacon/ble112_device.rb', line 102 def rotate_addr # set peripheral into private mode is not needed, as the mac is rotated every time gap_set_mode is called bg_command(@file, BG_MSG_CLASS_GAP, BG_GAP_SET_PRIVACY_FLAGS, [1, 0]) # set gap mode bg_command(@file, BG_MSG_CLASS_GAP, BG_SET_MODE, [BG_GAP_USER_DATA, BG_GAP_CONNECTABLE]) end |
#start_advertising(ad_data, privacy = false) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/scan_beacon/ble112_device.rb', line 81 def start_advertising(ad_data, privacy = false) # disconnect any connections bg_command(@file, BG_MSG_CLASS_CONNECTION, BG_DISCONNECT,0) # set advertising interval 0x00A0 = 100 ms interval, 7 = all channels bg_command(@file, BG_MSG_CLASS_GAP, BG_GAP_SET_ADV_PARAM, [0xA0, 0x00, 0xA0, 0x00, 7]) # set privacy mode (rotate bluetooth address) if privacy bg_command(@file, BG_MSG_CLASS_GAP, BG_GAP_SET_PRIVACY_FLAGS, [1, 0]) end # add flags header ad_data = "\x02\x01\x06" + ad_data ad_data = [0,ad_data.size].pack("C*") + ad_data stop_advertising bg_command(@file, BG_MSG_CLASS_GAP, BG_GAP_SET_ADV_DATA, ad_data.unpack("C*")) bg_command(@file, BG_MSG_CLASS_GAP, BG_SET_MODE, [BG_GAP_USER_DATA, BG_GAP_CONNECTABLE]) end |
#start_scan ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/scan_beacon/ble112_device.rb', line 64 def start_scan # disconnect any connections bg_command(@file, BG_MSG_CLASS_CONNECTION, BG_DISCONNECT,0) # turn off adverts bg_command(@file, BG_MSG_CLASS_GAP, BG_SET_MODE, [BG_GAP_NON_DISCOVERABLE, BG_GAP_NON_CONNECTABLE]) # stop previous scan bg_command(@file, BG_MSG_CLASS_GAP, BG_DISCOVER_STOP) # write new scan params bg_command(@file, BG_MSG_CLASS_GAP, BG_SCAN_PARAMS, [200,200, 0], "S<S<C") # start new scan bg_command(@file, BG_MSG_CLASS_GAP, BG_DISCOVER, BG_GAP_DISCOVER_ALL) end |
#stop_advertising ⇒ Object
110 111 112 |
# File 'lib/scan_beacon/ble112_device.rb', line 110 def stop_advertising bg_command(@file, BG_MSG_CLASS_GAP, BG_SET_MODE, [BG_GAP_NON_DISCOVERABLE, BG_GAP_NON_CONNECTABLE]) end |
#stop_scan ⇒ Object
77 78 79 |
# File 'lib/scan_beacon/ble112_device.rb', line 77 def stop_scan bg_command(@file, BG_MSG_CLASS_GAP, BG_DISCOVER_STOP) end |