sb-ble 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +1 -0
- data/.semver +5 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +130 -0
- data/LICENSE +21 -0
- data/README.org +62 -0
- data/Rakefile +51 -0
- data/bin/rble +0 -0
- data/lib/ble.rb +112 -0
- data/lib/ble/adapter.rb +162 -0
- data/lib/ble/agent.rb +46 -0
- data/lib/ble/char_desc.rb +63 -0
- data/lib/ble/char_registry.rb +142 -0
- data/lib/ble/characteristic.rb +85 -0
- data/lib/ble/db_eddystone.rb +50 -0
- data/lib/ble/db_nordic.rb +26 -0
- data/lib/ble/db_sig_characteristic.rb +142 -0
- data/lib/ble/db_sig_service.rb +59 -0
- data/lib/ble/device.rb +494 -0
- data/lib/ble/notifications.rb +44 -0
- data/lib/ble/service.rb +121 -0
- data/lib/ble/uuid.rb +25 -0
- data/lib/ble/version.rb +15 -0
- data/sb-ble.gemspec +112 -0
- data/spec/ruby-ble_spec.rb +7 -0
- data/spec/spec_helper.rb +29 -0
- metadata +296 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bbab52be19f92ec7202ac18981e9b65ead354a2c
|
4
|
+
data.tar.gz: b695176d8a305d5ac043fa350a5e2d995d8bc699
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: df55d481209aaa635386dfa2deb9f2204824bc23ac44b8adcb55e8b4331c44971f35b90bb88ed5601b215795b630ca3256796c3a69fecb5c210acba58ccdd90f
|
7
|
+
data.tar.gz: 5bb64da90ebf9a2e0ccb14f62c8f6b580f9c01dcb7ff039f28829dc1e64f1145936ee4276035138de31fcafb916ca8a143438f407a4656083f023ddddbd3410b
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.semver
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem "ruby-dbus", "~> 0"
|
4
|
+
gem 'semver2', '~> 3'
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
gem "rspec", "~> 3"
|
8
|
+
gem "yard", "~> 0"
|
9
|
+
gem "rdoc", "~> 3"
|
10
|
+
gem "bundler", "~> 1"
|
11
|
+
gem "juwelier", "~> 2"
|
12
|
+
gem "simplecov", ">= 0"
|
13
|
+
gem "pry", "~> 0"
|
14
|
+
gem "pry-byebug", "~> 3"
|
15
|
+
gem "pry-doc", "~> 0"
|
16
|
+
gem "pry-remote", "~> 0"
|
17
|
+
gem "pry-rescue", "~> 1"
|
18
|
+
gem "pry-stack_explorer", "~> 0"
|
19
|
+
gem 'redcarpet'
|
20
|
+
gem 'github-markup'
|
21
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.4.0)
|
5
|
+
binding_of_caller (0.7.2)
|
6
|
+
debug_inspector (>= 0.0.1)
|
7
|
+
builder (3.2.3)
|
8
|
+
byebug (9.0.6)
|
9
|
+
coderay (1.1.1)
|
10
|
+
debug_inspector (0.0.3)
|
11
|
+
descendants_tracker (0.0.4)
|
12
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
13
|
+
diff-lcs (1.3)
|
14
|
+
docile (1.1.5)
|
15
|
+
faraday (0.9.2)
|
16
|
+
multipart-post (>= 1.2, < 3)
|
17
|
+
git (1.3.0)
|
18
|
+
github-markup (1.6.0)
|
19
|
+
github_api (0.17.0)
|
20
|
+
addressable (~> 2.4.0)
|
21
|
+
descendants_tracker (~> 0.0.4)
|
22
|
+
faraday (~> 0.8, < 0.10)
|
23
|
+
hashie (>= 3.4)
|
24
|
+
mime-types (>= 1.16, < 3.0)
|
25
|
+
oauth2 (~> 1.0)
|
26
|
+
hashie (3.5.5)
|
27
|
+
highline (1.7.8)
|
28
|
+
interception (0.5)
|
29
|
+
json (1.8.6)
|
30
|
+
juwelier (2.4.5)
|
31
|
+
builder
|
32
|
+
bundler (>= 1.13)
|
33
|
+
git (>= 1.2.5)
|
34
|
+
github_api
|
35
|
+
highline (>= 1.6.15)
|
36
|
+
kamelcase (~> 0)
|
37
|
+
nokogiri (>= 1.5.10)
|
38
|
+
psych (~> 2.2)
|
39
|
+
rake
|
40
|
+
rdoc
|
41
|
+
semver2
|
42
|
+
jwt (1.5.6)
|
43
|
+
kamelcase (0.0.0)
|
44
|
+
semver2 (~> 3)
|
45
|
+
method_source (0.8.2)
|
46
|
+
mime-types (2.99.3)
|
47
|
+
mini_portile2 (2.1.0)
|
48
|
+
multi_json (1.12.1)
|
49
|
+
multi_xml (0.6.0)
|
50
|
+
multipart-post (2.0.0)
|
51
|
+
nokogiri (1.7.2)
|
52
|
+
mini_portile2 (~> 2.1.0)
|
53
|
+
oauth2 (1.3.1)
|
54
|
+
faraday (>= 0.8, < 0.12)
|
55
|
+
jwt (~> 1.0)
|
56
|
+
multi_json (~> 1.3)
|
57
|
+
multi_xml (~> 0.5)
|
58
|
+
rack (>= 1.2, < 3)
|
59
|
+
pry (0.10.4)
|
60
|
+
coderay (~> 1.1.0)
|
61
|
+
method_source (~> 0.8.1)
|
62
|
+
slop (~> 3.4)
|
63
|
+
pry-byebug (3.4.2)
|
64
|
+
byebug (~> 9.0)
|
65
|
+
pry (~> 0.10)
|
66
|
+
pry-doc (0.10.0)
|
67
|
+
pry (~> 0.9)
|
68
|
+
yard (~> 0.9)
|
69
|
+
pry-remote (0.1.8)
|
70
|
+
pry (~> 0.9)
|
71
|
+
slop (~> 3.0)
|
72
|
+
pry-rescue (1.4.5)
|
73
|
+
interception (>= 0.5)
|
74
|
+
pry
|
75
|
+
pry-stack_explorer (0.4.9.2)
|
76
|
+
binding_of_caller (>= 0.7)
|
77
|
+
pry (>= 0.9.11)
|
78
|
+
psych (2.2.4)
|
79
|
+
rack (2.0.3)
|
80
|
+
rake (12.0.0)
|
81
|
+
rdoc (3.12.2)
|
82
|
+
json (~> 1.4)
|
83
|
+
redcarpet (3.4.0)
|
84
|
+
rspec (3.6.0)
|
85
|
+
rspec-core (~> 3.6.0)
|
86
|
+
rspec-expectations (~> 3.6.0)
|
87
|
+
rspec-mocks (~> 3.6.0)
|
88
|
+
rspec-core (3.6.0)
|
89
|
+
rspec-support (~> 3.6.0)
|
90
|
+
rspec-expectations (3.6.0)
|
91
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
92
|
+
rspec-support (~> 3.6.0)
|
93
|
+
rspec-mocks (3.6.0)
|
94
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
95
|
+
rspec-support (~> 3.6.0)
|
96
|
+
rspec-support (3.6.0)
|
97
|
+
ruby-dbus (0.13.0)
|
98
|
+
semver2 (3.4.2)
|
99
|
+
simplecov (0.14.1)
|
100
|
+
docile (~> 1.1.0)
|
101
|
+
json (>= 1.8, < 3)
|
102
|
+
simplecov-html (~> 0.10.0)
|
103
|
+
simplecov-html (0.10.1)
|
104
|
+
slop (3.6.0)
|
105
|
+
thread_safe (0.3.6)
|
106
|
+
yard (0.9.9)
|
107
|
+
|
108
|
+
PLATFORMS
|
109
|
+
ruby
|
110
|
+
|
111
|
+
DEPENDENCIES
|
112
|
+
bundler (~> 1)
|
113
|
+
github-markup
|
114
|
+
juwelier (~> 2)
|
115
|
+
pry (~> 0)
|
116
|
+
pry-byebug (~> 3)
|
117
|
+
pry-doc (~> 0)
|
118
|
+
pry-remote (~> 0)
|
119
|
+
pry-rescue (~> 1)
|
120
|
+
pry-stack_explorer (~> 0)
|
121
|
+
rdoc (~> 3)
|
122
|
+
redcarpet
|
123
|
+
rspec (~> 3)
|
124
|
+
ruby-dbus (~> 0)
|
125
|
+
semver2 (~> 3)
|
126
|
+
simplecov
|
127
|
+
yard (~> 0)
|
128
|
+
|
129
|
+
BUNDLED WITH
|
130
|
+
1.14.6
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Fred Mitchell & Sensorberg
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.org
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
* sb-ble
|
2
|
+
:PROPERTIES:
|
3
|
+
:CUSTOM_ID: ruby-ble
|
4
|
+
:END:
|
5
|
+
|
6
|
+
Bluetooth Low Energy for Ruby -- Sensorberg Version
|
7
|
+
[[https://badge.fury.io/rb/ble][[[https://badge.fury.io/rb/ble.svg]]]]
|
8
|
+
|
9
|
+
** Prelimaries
|
10
|
+
This is a fork of a fork. More features are being added here,
|
11
|
+
such as support for advertising.
|
12
|
+
|
13
|
+
** Requirements
|
14
|
+
:PROPERTIES:
|
15
|
+
:CUSTOM_ID: requirements
|
16
|
+
:END:
|
17
|
+
|
18
|
+
- ruby >= 2.3
|
19
|
+
- Dbus
|
20
|
+
- bluez >= 5.36 (available on debian testing)
|
21
|
+
- =bluetoothd= started with option =-E= (experimental)
|
22
|
+
|
23
|
+
** Examples
|
24
|
+
:PROPERTIES:
|
25
|
+
:CUSTOM_ID: examples
|
26
|
+
:END:
|
27
|
+
|
28
|
+
#+BEGIN_SRC ruby
|
29
|
+
# Selecter adapter
|
30
|
+
$a = BLE::Adapter.new('hci0')
|
31
|
+
puts "Info: #{$a.iface} #{$a.address} #{$a.name}"
|
32
|
+
|
33
|
+
# Run discovery
|
34
|
+
$a.start_discovery
|
35
|
+
sleep(2)
|
36
|
+
$a.stop_discovery
|
37
|
+
|
38
|
+
# Get device and connect to it
|
39
|
+
$d = $a['F4:AD:CB:FB:B4:85']
|
40
|
+
$d.connect
|
41
|
+
|
42
|
+
# Get temperature from the environmental sensing service
|
43
|
+
$d[:environmental_sensing, :temperature]
|
44
|
+
|
45
|
+
# Dump device information
|
46
|
+
srv = :device_information
|
47
|
+
$d.characteristics(srv).each {|uuid|
|
48
|
+
info = BLE::Characteristic[uuid]
|
49
|
+
name = info.nil? ? uuid : info[:name]
|
50
|
+
value = $d[srv, uuid] rescue '/!\\ not-readable /!\\'
|
51
|
+
puts "%-30s: %s" % [ name, value ]
|
52
|
+
}
|
53
|
+
#+END_SRC
|
54
|
+
|
55
|
+
** Contributors
|
56
|
+
:PROPERTIES:
|
57
|
+
:CUSTOM_ID: contributors
|
58
|
+
:END:
|
59
|
+
|
60
|
+
- Fred Mitchell (Sensorberg GmbH) LE Advertisement support
|
61
|
+
- Oliver Valls (tramuntanal): Bug fixes / BLE Notification support
|
62
|
+
- Stephane D'Alu
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
|
6
|
+
begin
|
7
|
+
Bundler.setup(:default, :development)
|
8
|
+
rescue Bundler::BundlerError => e
|
9
|
+
$stderr.puts e.message
|
10
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
11
|
+
exit e.status_code
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'rake'
|
15
|
+
require 'semver'
|
16
|
+
|
17
|
+
def s_version
|
18
|
+
SemVer.find.format "%M.%m.%p%s"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'juwelier'
|
22
|
+
|
23
|
+
Juwelier::Tasks.new do |gem|
|
24
|
+
gem.name = "sb-ble"
|
25
|
+
gem.homepage = "http://github.com/flajann2/ruby-ble"
|
26
|
+
gem.license = "MIT"
|
27
|
+
gem.summary = %Q{Bluetooth Low Energy for Ruby -- Sensorberg Version}
|
28
|
+
gem.description = %Q{This supports LE Advertising}
|
29
|
+
gem.email = "frederick.mitchell@sensorberg.com"
|
30
|
+
gem.authors = ["Fred Mitchell & Sensorberg"]
|
31
|
+
gem.version = s_version
|
32
|
+
# dependencies defined in Gemfile
|
33
|
+
end
|
34
|
+
|
35
|
+
Juwelier::RubygemsDotOrgTasks.new
|
36
|
+
require 'rspec/core'
|
37
|
+
require 'rspec/core/rake_task'
|
38
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
39
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Code coverage detail"
|
43
|
+
task :simplecov do
|
44
|
+
ENV['COVERAGE'] = "true"
|
45
|
+
Rake::Task['spec'].execute
|
46
|
+
end
|
47
|
+
|
48
|
+
task :default => :spec
|
49
|
+
|
50
|
+
require 'yard'
|
51
|
+
YARD::Rake::YardocTask.new
|
data/bin/rble
ADDED
File without changes
|
data/lib/ble.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'dbus'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
# https://github.com/mvidner/ruby-dbus/blob/master/doc/Tutorial.md
|
6
|
+
# https://kernel.googlesource.com/pub/scm/bluetooth/bluez/+/refs/heads/master/doc/
|
7
|
+
|
8
|
+
|
9
|
+
#
|
10
|
+
module BLE
|
11
|
+
private
|
12
|
+
# Interfaces
|
13
|
+
I_ADAPTER = 'org.bluez.Adapter1'
|
14
|
+
I_DEVICE = 'org.bluez.Device1'
|
15
|
+
I_AGENT_MANAGER = 'org.bluez.AgentManager1'
|
16
|
+
I_AGENT = 'org.bluez.Agent1'
|
17
|
+
I_GATT_CHARACTERISTIC = 'org.bluez.GattCharacteristic1'
|
18
|
+
I_GATT_SERVICE = 'org.bluez.GattService1'
|
19
|
+
I_PROXIMITY_REPORTER = 'org.bluez.ProximityReporter1'
|
20
|
+
I_PROPERTIES = 'org.freedesktop.DBus.Properties'
|
21
|
+
I_INTROSPECTABLE = 'org.freedesktop.DBus.Introspectable'
|
22
|
+
|
23
|
+
# Errors
|
24
|
+
E_IN_PROGRESS = 'org.bluez.Error.InProgress'
|
25
|
+
E_FAILED = 'org.bluez.Error.Failed'
|
26
|
+
E_NOT_READY = 'org.bluez.Error.NotReady'
|
27
|
+
E_ALREADY_CONNECTED = 'org.bluez.Error.AlreadyConnected'
|
28
|
+
E_NOT_CONNECTED = 'org.bluez.Error.NotConnected'
|
29
|
+
E_DOES_NOT_EXIST = 'org.bluez.Error.DoesNotExist'
|
30
|
+
E_NOT_SUPPORTED = 'org.bluez.Error.NotSupported'
|
31
|
+
E_NOT_AUTHORIZED = 'org.bluez.Error.NotAuthorized'
|
32
|
+
E_INVALID_ARGUMENTS = 'org.bluez.Error.InvalidArguments'
|
33
|
+
E_ALREADY_EXISTS = 'org.bluez.Error.AlreadyExists'
|
34
|
+
E_AUTH_CANCELED = 'org.bluez.Error.AuthenticationCanceled'
|
35
|
+
E_AUTH_FAILED = 'org.bluez.Error.AuthenticationFailed'
|
36
|
+
E_AUTH_REJECTED = 'org.bluez.Error.AuthenticationRejected'
|
37
|
+
E_AUTH_TIMEOUT = 'org.bluez.Error.AuthenticationTimeout'
|
38
|
+
E_AUTH_ATTEMPT_FAILED = 'org.bluez.Error.ConnectionAttemptFailed'
|
39
|
+
E_UNKNOWN_OBJECT = 'org.freedesktop.DBus.Error.UnknownObject'
|
40
|
+
E_INVALID_ARGS = 'org.freedesktop.DBus.Error.InvalidArgs'
|
41
|
+
E_INVALID_SIGNATURE = 'org.freedesktop.DBus.Error.InvalidSignature'
|
42
|
+
|
43
|
+
# Bus
|
44
|
+
DBUS = DBus.system_bus
|
45
|
+
BLUEZ = DBUS.service('org.bluez')
|
46
|
+
|
47
|
+
public
|
48
|
+
# Generic Error class
|
49
|
+
class Error < StandardError ; end
|
50
|
+
# Notify of unimplemented part
|
51
|
+
class NotYetImplemented < Error ; end
|
52
|
+
# Notify that the underlying API object is dead
|
53
|
+
class StalledObject < Error ; end
|
54
|
+
# Notify that execution wass not able to fulill as some requirement
|
55
|
+
# was not ready. Usually you can wait a little and restart the action.
|
56
|
+
class NotReady < Error ; end
|
57
|
+
# Notify that you don't have the necessary authorization to perfrom
|
58
|
+
# the operation
|
59
|
+
class NotAuthorized < Error ; end
|
60
|
+
# Notify that some service/characteristic/... is not found
|
61
|
+
# on this device
|
62
|
+
class NotFound < Error ; end
|
63
|
+
class AccessUnavailable < Error ; end
|
64
|
+
class NotSupported < Error ; end
|
65
|
+
|
66
|
+
|
67
|
+
# Base UUID for GATT services defined with 16bit or 32bit UUID
|
68
|
+
GATT_BASE_UUID="00000000-0000-1000-8000-00805f9b34fb"
|
69
|
+
|
70
|
+
#"DisplayOnly", "DisplayYesNo", "KeyboardOnly",
|
71
|
+
# "NoInputNoOutput" and "KeyboardDisplay" which
|
72
|
+
|
73
|
+
|
74
|
+
def self.registerAgent(agent, service, path)
|
75
|
+
raise NotYetImplemented
|
76
|
+
bus = DBus.session_bus
|
77
|
+
service = bus.request_service("org.ruby.service")
|
78
|
+
|
79
|
+
service.export(BLE::Agent.new(agent_path))
|
80
|
+
|
81
|
+
o_bluez = BLUEZ.object('/org/bluez')
|
82
|
+
o_bluez.introspect
|
83
|
+
o_bluez[I_AGENT_MANAGER].RegisterAgent(agent_path, "NoInputNoOutput")
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
# Check if Bluetooth underlying API is accessible
|
90
|
+
def self.ok?
|
91
|
+
BLUEZ.exists?
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
require_relative 'ble/version'
|
97
|
+
require_relative 'ble/uuid'
|
98
|
+
require_relative 'ble/adapter'
|
99
|
+
require_relative 'ble/char_desc'
|
100
|
+
require_relative 'ble/notifications'
|
101
|
+
require_relative 'ble/device'
|
102
|
+
require_relative 'ble/service'
|
103
|
+
require_relative 'ble/char_registry'
|
104
|
+
require_relative 'ble/characteristic'
|
105
|
+
require_relative 'ble/agent'
|
106
|
+
|
107
|
+
require_relative 'ble/db_sig_service'
|
108
|
+
require_relative 'ble/db_sig_characteristic'
|
109
|
+
require_relative 'ble/db_eddystone'
|
110
|
+
require_relative 'ble/db_nordic'
|
111
|
+
|
112
|
+
|
data/lib/ble/adapter.rb
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
module BLE
|
2
|
+
# Adapter class
|
3
|
+
# Adapter.list
|
4
|
+
# a = Adapter.new('hci0')
|
5
|
+
# a.start_discover ; sleep(10) ; a.stop_discovery
|
6
|
+
# a.devices
|
7
|
+
#
|
8
|
+
class Adapter
|
9
|
+
# Return a list of available unix device name for the
|
10
|
+
# adapter installed on the system.
|
11
|
+
# @return [Array<String>] list of unix device name
|
12
|
+
def self.list
|
13
|
+
o_bluez = BLUEZ.object('/org/bluez')
|
14
|
+
o_bluez.introspect
|
15
|
+
o_bluez.subnodes.reject {|adapter| ['test'].include?(adapter) }
|
16
|
+
end
|
17
|
+
|
18
|
+
# Create a new Adapter
|
19
|
+
#
|
20
|
+
# @param iface [String] name of the Unix device
|
21
|
+
def initialize(iface)
|
22
|
+
@iface = iface.dup.freeze
|
23
|
+
@o_adapter = BLUEZ.object("/org/bluez/#{@iface}")
|
24
|
+
@o_adapter.introspect
|
25
|
+
|
26
|
+
# @o_adapter[I_PROPERTIES]
|
27
|
+
# .on_signal('PropertiesChanged') do |intf, props|
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
end
|
31
|
+
|
32
|
+
# The Bluetooth interface name
|
33
|
+
# @return [String] name of the Unix device
|
34
|
+
def iface
|
35
|
+
@iface
|
36
|
+
end
|
37
|
+
|
38
|
+
# The Bluetooth device address.
|
39
|
+
# @return [String] MAC address of the adapter
|
40
|
+
def address
|
41
|
+
@o_adapter[I_ADAPTER]['Address']
|
42
|
+
end
|
43
|
+
|
44
|
+
# The Bluetooth system name (pretty hostname).
|
45
|
+
# @return [String]
|
46
|
+
def name
|
47
|
+
@o_adapter[I_ADAPTER]['Name']
|
48
|
+
end
|
49
|
+
|
50
|
+
# The Bluetooth friendly name.
|
51
|
+
# In case no alias is set, it will return the system provided name.
|
52
|
+
# @return [String]
|
53
|
+
def alias
|
54
|
+
@o_adapter[I_ADAPTER]['Alias']
|
55
|
+
end
|
56
|
+
|
57
|
+
# Set the alias name.
|
58
|
+
#
|
59
|
+
# When resetting the alias with an empty string, the
|
60
|
+
# property will default back to system name
|
61
|
+
#
|
62
|
+
# @param val [String] new alias name.
|
63
|
+
# @return [void]
|
64
|
+
def alias=(val)
|
65
|
+
@o_adapter[I_ADAPTER]['Alias'] = val.nil? ? '' : val.to_str
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
# Return the device corresponding to the given address.
|
70
|
+
# @note The device object returned has a dependency on the adapter.
|
71
|
+
#
|
72
|
+
# @param address MAC address of the device
|
73
|
+
# @return [Device] a device
|
74
|
+
def [](address)
|
75
|
+
Device.new(@iface, address)
|
76
|
+
end
|
77
|
+
|
78
|
+
# This method sets the device discovery filter for the caller.
|
79
|
+
# When this method is called with +nil+ or an empty list of UUIDs,
|
80
|
+
# filter is removed.
|
81
|
+
#
|
82
|
+
# @todo Need to sync with the adapter-api.txt
|
83
|
+
#
|
84
|
+
# @param uuids a list of uuid to filter on
|
85
|
+
# @param rssi RSSI threshold
|
86
|
+
# @param pathloss pathloss threshold
|
87
|
+
# @param transport [:auto, :bredr, :le]
|
88
|
+
# type of scan to run (default: :le)
|
89
|
+
# @return [self]
|
90
|
+
def filter(uuids, rssi: nil, pathloss: nil, transport: :le)
|
91
|
+
unless [:auto, :bredr, :le].include?(transport)
|
92
|
+
raise ArgumentError,
|
93
|
+
"transport must be one of :auto, :bredr, :le"
|
94
|
+
end
|
95
|
+
filter = { }
|
96
|
+
|
97
|
+
unless uuids.nil? || uuids.empty?
|
98
|
+
filter['UUIDs' ] = DBus.variant('as', uuids)
|
99
|
+
end
|
100
|
+
unless rssi.nil?
|
101
|
+
filter['RSSI' ] = DBus.variant('n', rssi)
|
102
|
+
end
|
103
|
+
unless pathloss.nil?
|
104
|
+
filter['Pathloss' ] = DBus.variant('q', pathloss)
|
105
|
+
end
|
106
|
+
unless transport.nil?
|
107
|
+
filter['Transport'] = DBus.variant('s', transport.to_s)
|
108
|
+
end
|
109
|
+
|
110
|
+
@o_adapter[I_ADAPTER].SetDiscoveryFilter(filter)
|
111
|
+
|
112
|
+
self
|
113
|
+
end
|
114
|
+
|
115
|
+
# Starts the device discovery session.
|
116
|
+
# This includes an inquiry procedure and remote device name resolving.
|
117
|
+
# Use {#stop_discovery} to release the sessions acquired.
|
118
|
+
# This process will start creating device in the underlying api
|
119
|
+
# as new devices are discovered.
|
120
|
+
#
|
121
|
+
# @return [Boolean]
|
122
|
+
def start_discovery
|
123
|
+
@o_adapter[I_ADAPTER].StartDiscovery
|
124
|
+
true
|
125
|
+
rescue DBus::Error => e
|
126
|
+
case e.name
|
127
|
+
when E_IN_PROGRESS then true
|
128
|
+
when E_FAILED then false
|
129
|
+
else raise ScriptError
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# This method will cancel any previous {#start_discovery}
|
134
|
+
# transaction.
|
135
|
+
# @note The discovery procedure is shared
|
136
|
+
# between all discovery sessions thus calling {#stop_discovery}
|
137
|
+
# will only release a single session.
|
138
|
+
#
|
139
|
+
# @return [Boolean]
|
140
|
+
def stop_discovery
|
141
|
+
@o_adapter[I_ADAPTER].StopDiscovery
|
142
|
+
true
|
143
|
+
rescue DBus::Error => e
|
144
|
+
case e.name
|
145
|
+
when E_FAILED then false
|
146
|
+
when E_NOT_READY then false
|
147
|
+
when E_NOT_AUTHORIZED then raise NotAuthorized
|
148
|
+
else raise ScriptError
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
# List of devices MAC address that have been discovered.
|
154
|
+
#
|
155
|
+
# @return [Array<String>] List of devices MAC address.
|
156
|
+
def devices
|
157
|
+
@o_adapter.introspect # Force refresh
|
158
|
+
@o_adapter.subnodes.map {|dev| # Format: dev_aa_bb_cc_dd_ee_ff
|
159
|
+
dev[4..-1].tr('_', ':') }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|