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 63 64 |
# File 'lib/scan_beacon/ble112_device.rb', line 59 def get_addr # use a timeout here because we're using this to detect BLE112s and if it # isn't one, it may not respond right away response = bg_command(@file, BG_MSG_CLASS_SYSTEM, BG_GET_ADDRESS,nil,nil,0.2) 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
116 117 118 119 120 |
# File 'lib/scan_beacon/ble112_device.rb', line 116 def read data = bg_read(@file, 0.2) return nil if data.nil? BLE112Response.new( data ) end |
#reset ⇒ Object
122 123 124 125 126 127 128 129 |
# File 'lib/scan_beacon/ble112_device.rb', line 122 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
104 105 106 107 108 109 110 |
# File 'lib/scan_beacon/ble112_device.rb', line 104 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
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/scan_beacon/ble112_device.rb', line 83 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
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/scan_beacon/ble112_device.rb', line 66 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
112 113 114 |
# File 'lib/scan_beacon/ble112_device.rb', line 112 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
79 80 81 |
# File 'lib/scan_beacon/ble112_device.rb', line 79 def stop_scan bg_command(@file, BG_MSG_CLASS_GAP, BG_DISCOVER_STOP) end |