Class: Radbeacon::BluetoothLeDevice
- Inherits:
-
Object
- Object
- Radbeacon::BluetoothLeDevice
- Defined in:
- lib/radbeacon/bluetooth_le_device.rb
Direct Known Subclasses
Constant Summary collapse
- TIMEOUT =
0.5
Instance Attribute Summary collapse
-
#characteristics ⇒ Object
readonly
Returns the value of attribute characteristics.
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
-
#is_connectable ⇒ Object
readonly
Returns the value of attribute is_connectable.
-
#mac_address ⇒ Object
readonly
Returns the value of attribute mac_address.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#values ⇒ Object
readonly
Returns the value of attribute values.
Instance Method Summary collapse
- #can_connect? ⇒ Boolean
- #char_values ⇒ Object
- #characteristics_command ⇒ Object
- #discover_characteristics ⇒ Object
- #display ⇒ Object
- #fetch_characteristics ⇒ Object
-
#initialize(mac_address, name) ⇒ BluetoothLeDevice
constructor
A new instance of BluetoothLeDevice.
Constructor Details
#initialize(mac_address, name) ⇒ BluetoothLeDevice
Returns a new instance of BluetoothLeDevice.
10 11 12 13 14 15 16 17 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 10 def initialize(mac_address, name) @errors = [] @mac_address = mac_address @name = name @is_connectable = false @characteristics = Array.new @values = Hash.new end |
Instance Attribute Details
#characteristics ⇒ Object
Returns the value of attribute characteristics.
6 7 8 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 6 def characteristics @characteristics end |
#errors ⇒ Object
Returns the value of attribute errors.
6 7 8 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 6 def errors @errors end |
#is_connectable ⇒ Object
Returns the value of attribute is_connectable.
6 7 8 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 6 def is_connectable @is_connectable end |
#mac_address ⇒ Object
Returns the value of attribute mac_address.
6 7 8 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 6 def mac_address @mac_address end |
#name ⇒ Object
Returns the value of attribute name.
6 7 8 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 6 def name @name end |
#values ⇒ Object
Returns the value of attribute values.
6 7 8 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 6 def values @values end |
Instance Method Details
#can_connect? ⇒ Boolean
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 36 def can_connect? @errors = [] result = false cmd = "gatttool -b #{@mac_address} --interactive" PTY.spawn(cmd) do |output, input, pid| output.expect(/\[LE\]>/) input.puts "connect" if output.expect(/Connection successful/, TIMEOUT) @is_connectable = true result = true else @errors << "Connection failed" end input.puts "quit" end result end |
#char_values ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 101 def char_values @errors = [] result = false cmd = "gatttool -b #{@mac_address} --interactive" if @characteristics != [] PTY.spawn(cmd) do |output, input, pid| output.expect(/\[LE\]>/) input.puts "connect" if output.expect(/Connection successful/, TIMEOUT) @characteristics.each do |char| input.puts "char-read-hnd #{char['value_handle']}" if output.expect(/Characteristic value\/descriptor: /, TIMEOUT) if value = output.expect(/^[0-9a-f\s]+\n/, TIMEOUT) @values[char['value_handle']] = value.first.strip end end end result = true else @errors << "Fetch characteristic values failed" end input.puts "quit" end else @errors << "No characteristics present" end result end |
#characteristics_command ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 54 def characteristics_command success = true output = nil rout, wout = IO.pipe rerr, werr = IO.pipe characteristics_command_str = "gatttool -b #{@mac_address} --characteristics" pid = Process.spawn(characteristics_command_str, :out => wout, :err => werr) begin Timeout.timeout(5) do Process.wait(pid) end rescue Timeout::Error Process.kill('TERM', pid) success = false end wout.close werr.close stdout = rout.readlines.join("") stderr = rerr.readlines.join("") rout.close rerr.close if success output = [stdout, stderr].join("") end output end |
#discover_characteristics ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 81 def discover_characteristics @errors = [] result = false output = characteristics_command if output && output.strip != "Discover all characteristics failed: Internal application error: I/O" @characteristics = [] output.each_line do |line| result = line.scan(/^handle = (0x[a-f0-9]{4}), char properties = (0x[a-f0-9]{2}), char value handle = (0x[a-f0-9]{4}), uuid = ([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})$/) if !result.empty? characteristic = {"handle" => result[0][0], "properties" => result[0][1], "value_handle" => result[0][2], "uuid" => result[0][3]} @characteristics << characteristic end end result = true else @errors << "Discover characteristics failed" end result end |
#display ⇒ Object
19 20 21 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 19 def display puts "MAC Address: " + @mac_address + " Name: " + @name + " Can connect: " + @is_connectable.to_s end |
#fetch_characteristics ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/radbeacon/bluetooth_le_device.rb', line 23 def fetch_characteristics result = false if self.can_connect? @is_connectable = true if self.discover_characteristics if self.char_values result = true end end end result end |