1 | /* |
2 | * BluezQt - Asynchronous Bluez wrapper library |
3 | * |
4 | * SPDX-FileCopyrightText: 2014 David Rosca <nowrep@gmail.com> |
5 | * |
6 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
7 | */ |
8 | |
9 | #include "manager.h" |
10 | |
11 | #include "adapter.h" |
12 | #include "agent.h" |
13 | #include "agentadaptor.h" |
14 | #include "debug.h" |
15 | #include "initmanagerjob.h" |
16 | #include "manager_p.h" |
17 | #include "pendingcall.h" |
18 | #include "profile.h" |
19 | #include "profile_p.h" |
20 | #include "profileadaptor.h" |
21 | #include "utils.h" |
22 | |
23 | namespace BluezQt |
24 | { |
25 | Manager::Manager(QObject *parent) |
26 | : QObject(parent) |
27 | , d(new ManagerPrivate(this)) |
28 | { |
29 | Instance::setManager(this); |
30 | } |
31 | |
32 | Manager::~Manager() = default; |
33 | |
34 | InitManagerJob *Manager::init() |
35 | { |
36 | return new InitManagerJob(this); |
37 | } |
38 | |
39 | bool Manager::isInitialized() const |
40 | { |
41 | return d->m_initialized; |
42 | } |
43 | |
44 | bool Manager::isOperational() const |
45 | { |
46 | return d->m_initialized && d->m_bluezRunning && d->m_loaded; |
47 | } |
48 | |
49 | bool Manager::isBluetoothOperational() const |
50 | { |
51 | return !d->m_bluetoothBlocked && d->m_bluezRunning && d->m_loaded && d->m_usableAdapter; |
52 | } |
53 | |
54 | bool Manager::isBluetoothBlocked() const |
55 | { |
56 | return d->m_bluetoothBlocked; |
57 | } |
58 | |
59 | void Manager::setBluetoothBlocked(bool blocked) |
60 | { |
61 | if (blocked) { |
62 | d->m_rfkill->block(); |
63 | } else { |
64 | d->m_rfkill->unblock(); |
65 | } |
66 | } |
67 | |
68 | AdapterPtr Manager::usableAdapter() const |
69 | { |
70 | return d->m_usableAdapter; |
71 | } |
72 | |
73 | QList<AdapterPtr> Manager::adapters() const |
74 | { |
75 | return d->m_adapters.values(); |
76 | } |
77 | |
78 | QList<DevicePtr> Manager::devices() const |
79 | { |
80 | return d->m_devices.values(); |
81 | } |
82 | |
83 | PendingCall *Manager::startService() |
84 | { |
85 | QDBusMessage msg = QDBusMessage::createMethodCall(destination: Strings::orgFreedesktopDBus(), |
86 | QStringLiteral("/org/freedesktop/DBus" ), |
87 | interface: Strings::orgFreedesktopDBus(), |
88 | QStringLiteral("StartServiceByName" )); |
89 | msg << Strings::orgBluez(); |
90 | msg << quint32(0); |
91 | |
92 | return new PendingCall(DBusConnection::orgBluez().asyncCall(message: msg), PendingCall::ReturnUint32); |
93 | } |
94 | |
95 | AdapterPtr Manager::adapterForAddress(const QString &address) const |
96 | { |
97 | for (AdapterPtr adapter : std::as_const(t&: d->m_adapters)) { |
98 | if (adapter->address() == address) { |
99 | return adapter; |
100 | } |
101 | } |
102 | return AdapterPtr(); |
103 | } |
104 | |
105 | AdapterPtr Manager::adapterForUbi(const QString &ubi) const |
106 | { |
107 | return d->m_adapters.value(key: ubi); |
108 | } |
109 | |
110 | DevicePtr Manager::deviceForAddress(const QString &address) const |
111 | { |
112 | DevicePtr device; |
113 | |
114 | for (AdapterPtr adapter : std::as_const(t&: d->m_adapters)) { |
115 | DevicePtr oneDevice = adapter->deviceForAddress(address); |
116 | if (!oneDevice) { |
117 | continue; |
118 | } |
119 | |
120 | // Prefer powered adapter |
121 | if (!device) { |
122 | device = oneDevice; |
123 | } else if (adapter->isPowered()) { |
124 | device = oneDevice; |
125 | } |
126 | } |
127 | |
128 | return device; |
129 | } |
130 | |
131 | DevicePtr Manager::deviceForUbi(const QString &ubi) const |
132 | { |
133 | return d->m_devices.value(key: ubi); |
134 | } |
135 | |
136 | PendingCall *Manager::registerAgent(Agent *agent) |
137 | { |
138 | Q_ASSERT(agent); |
139 | |
140 | if (!d->m_bluezAgentManager) { |
141 | return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!" )); |
142 | } |
143 | |
144 | QString capability; |
145 | |
146 | switch (agent->capability()) { |
147 | case Agent::DisplayOnly: |
148 | capability = QStringLiteral("DisplayOnly" ); |
149 | break; |
150 | case Agent::DisplayYesNo: |
151 | capability = QStringLiteral("DisplayYesNo" ); |
152 | break; |
153 | case Agent::KeyboardOnly: |
154 | capability = QStringLiteral("KeyboardOnly" ); |
155 | break; |
156 | case Agent::NoInputNoOutput: |
157 | capability = QStringLiteral("NoInputNoOutput" ); |
158 | break; |
159 | default: |
160 | capability = QStringLiteral("DisplayYesNo" ); |
161 | break; |
162 | } |
163 | |
164 | new AgentAdaptor(agent, this); |
165 | |
166 | if (!DBusConnection::orgBluez().registerObject(path: agent->objectPath().path(), object: agent)) { |
167 | qCDebug(BLUEZQT) << "Cannot register object" << agent->objectPath().path(); |
168 | } |
169 | |
170 | return new PendingCall(d->m_bluezAgentManager->RegisterAgent(agent: agent->objectPath(), capability), PendingCall::ReturnVoid, this); |
171 | } |
172 | |
173 | PendingCall *Manager::unregisterAgent(Agent *agent) |
174 | { |
175 | Q_ASSERT(agent); |
176 | |
177 | if (!d->m_bluezAgentManager) { |
178 | return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!" )); |
179 | } |
180 | |
181 | DBusConnection::orgBluez().unregisterObject(path: agent->objectPath().path()); |
182 | |
183 | return new PendingCall(d->m_bluezAgentManager->UnregisterAgent(agent: agent->objectPath()), PendingCall::ReturnVoid, this); |
184 | } |
185 | |
186 | PendingCall *Manager::requestDefaultAgent(Agent *agent) |
187 | { |
188 | Q_ASSERT(agent); |
189 | |
190 | if (!d->m_bluezAgentManager) { |
191 | return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!" )); |
192 | } |
193 | |
194 | return new PendingCall(d->m_bluezAgentManager->RequestDefaultAgent(agent: agent->objectPath()), PendingCall::ReturnVoid, this); |
195 | } |
196 | |
197 | PendingCall *Manager::registerProfile(Profile *profile) |
198 | { |
199 | Q_ASSERT(profile); |
200 | |
201 | if (!d->m_bluezProfileManager) { |
202 | return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!" )); |
203 | } |
204 | |
205 | new ProfileAdaptor(profile, this); |
206 | |
207 | if (!DBusConnection::orgBluez().registerObject(path: profile->objectPath().path(), object: profile)) { |
208 | qCDebug(BLUEZQT) << "Cannot register object" << profile->objectPath().path(); |
209 | } |
210 | |
211 | return new PendingCall(d->m_bluezProfileManager->RegisterProfile(profile: profile->objectPath(), UUID: profile->uuid(), options: profile->d->options), |
212 | PendingCall::ReturnVoid, |
213 | this); |
214 | } |
215 | |
216 | PendingCall *Manager::unregisterProfile(Profile *profile) |
217 | { |
218 | Q_ASSERT(profile); |
219 | |
220 | if (!d->m_bluezProfileManager) { |
221 | return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!" )); |
222 | } |
223 | |
224 | DBusConnection::orgBluez().unregisterObject(path: profile->objectPath().path()); |
225 | |
226 | return new PendingCall(d->m_bluezProfileManager->UnregisterProfile(profile: profile->objectPath()), PendingCall::ReturnVoid, this); |
227 | } |
228 | |
229 | Rfkill *Manager::rfkill() const |
230 | { |
231 | return d->m_rfkill; |
232 | } |
233 | |
234 | } // namespace BluezQt |
235 | |
236 | #include "moc_manager.cpp" |
237 | |