-
Notifications
You must be signed in to change notification settings - Fork 4
/
bluetooth.lua
executable file
·119 lines (103 loc) · 3.14 KB
/
bluetooth.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/lua
local ldbus = require "ldbus"
local inspect = require "inspect"
local conn = assert( ldbus.bus.get("system") )
local M = {} -- public interface
function string.starts(String, Start)
return string.sub(String, 1, string.len(Start))==Start
end
function string.trim(s)
if s then
return (s:gsub("^%s*(.-)%s*$", "%1"))
else
return ""
end
end
local function read(riter)
local first = true
local results = {}
while first or riter:next() do
first = false
if riter:get_arg_type() == "a" then -- array
local ret = read(riter:recurse())
table.insert(results, ret)
elseif riter:get_arg_type() == "e" then -- dict_entry
local ret = read(riter:recurse())
results[ret[1]] = ret[2]
elseif riter:get_arg_type() == "r" then -- struct
local ret = read(riter:recurse())
table.insert(results, ret)
elseif riter:get_arg_type() == "v" then -- variant
local ret = read(riter:recurse())
table.insert(results, ret[1])
else -- basic type
local ret = riter:get_basic()
table.insert(results, ret)
end
end
return results
end
local function dbus_method_call(destination, path, interface, method)
local msg = assert(ldbus.message.new_method_call(destination, path, interface, method), "Message Null")
local iter = ldbus.message.iter.new()
msg:iter_init_append(iter)
local reply = assert(conn:send_with_reply_and_block(msg))
if not reply:iter_init(iter) then
return nil
end
return read(iter)
end
local function dbus_method_call_noreply(destination, path, interface, method)
local msg = assert(ldbus.message.new_method_call(destination, path, interface, method), "Message Null")
local iter = ldbus.message.iter.new()
msg:iter_init_append(iter)
return conn:send(msg)
end
function M.devices()
local r = dbus_method_call("org.bluez", "/", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects")
local devs = {}
for k, v in pairs(r[1]) do
if string.starts(k, "/org/bluez/hci0/") and v["org.bluez.Device1"] ~= nil then
devs[k] = v["org.bluez.Device1"]
devs[k].Name = string.trim(devs[k].Name)
devs[k].Alias = string.trim(devs[k].Alias)
if devs[k].Icon == nil then
devs[k].Icon = "unknown"
end
end
end
return devs
end
function M.device_connect(path) dbus_method_call("org.bluez", path, "org.bluez.Device1", "Connect") end
function M.device_disconnect(path) dbus_method_call("org.bluez", path, "org.bluez.Device1", "Disconnect") end
M.dbus_method_call = dbus_method_call
if arg ~= nil and arg[1] ~= nil then
local ok = true
local err
if arg[1] == "connect" then
ok, err = pcall(M.device_connect, arg[2])
elseif arg[1] == "disconnect" then
ok, err = pcall(M.device_disconnect, arg[2])
elseif arg[1] == "list" then
print(inspect(M.devices()))
end
if not ok then
print(err:match(": (.+)"))
else
print("OK")
end
else
return M
end
--[[
Usage as module:
local bluetooth = require "bluetooth"
local inspect = require('inspect')
print(inspect(bluetooth.devices()))
Usage via cli:
bluetooth.lua list
bluetooth.lua connect/disconnect PATH
eg:
./bluetooth.lua connect /org/bluez/hci0/dev_C8_84_47_03_CF_ED
./bluetooth.lua disconnect /org/bluez/hci0/dev_C8_84_47_03_CF_ED
--]]