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
23namespace BluezQt
24{
25Manager::Manager(QObject *parent)
26 : QObject(parent)
27 , d(new ManagerPrivate(this))
28{
29 Instance::setManager(this);
30}
31
32Manager::~Manager() = default;
33
34InitManagerJob *Manager::init()
35{
36 return new InitManagerJob(this);
37}
38
39bool Manager::isInitialized() const
40{
41 return d->m_initialized;
42}
43
44bool Manager::isOperational() const
45{
46 return d->m_initialized && d->m_bluezRunning && d->m_loaded;
47}
48
49bool Manager::isBluetoothOperational() const
50{
51 return !d->m_bluetoothBlocked && d->m_bluezRunning && d->m_loaded && d->m_usableAdapter;
52}
53
54bool Manager::isBluetoothBlocked() const
55{
56 return d->m_bluetoothBlocked;
57}
58
59void Manager::setBluetoothBlocked(bool blocked)
60{
61 if (blocked) {
62 d->m_rfkill->block();
63 } else {
64 d->m_rfkill->unblock();
65 }
66}
67
68AdapterPtr Manager::usableAdapter() const
69{
70 return d->m_usableAdapter;
71}
72
73QList<AdapterPtr> Manager::adapters() const
74{
75 return d->m_adapters.values();
76}
77
78QList<DevicePtr> Manager::devices() const
79{
80 return d->m_devices.values();
81}
82
83PendingCall *Manager::startService()
84{
85 QDBusMessage msg = QDBusMessage::createMethodCall(Strings::orgFreedesktopDBus(),
86 QStringLiteral("/org/freedesktop/DBus"),
87 Strings::orgFreedesktopDBus(),
88 QStringLiteral("StartServiceByName"));
89 msg << Strings::orgBluez();
90 msg << quint32(0);
91
92 return new PendingCall(DBusConnection::orgBluez().asyncCall(msg), PendingCall::ReturnUint32);
93}
94
95AdapterPtr Manager::adapterForAddress(const QString &address) const
96{
97 for (AdapterPtr adapter : std::as_const(d->m_adapters)) {
98 if (adapter->address() == address) {
99 return adapter;
100 }
101 }
102 return AdapterPtr();
103}
104
105AdapterPtr Manager::adapterForUbi(const QString &ubi) const
106{
107 return d->m_adapters.value(ubi);
108}
109
110DevicePtr Manager::deviceForAddress(const QString &address) const
111{
112 DevicePtr device;
113
114 for (AdapterPtr adapter : std::as_const(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
131DevicePtr Manager::deviceForUbi(const QString &ubi) const
132{
133 return d->m_devices.value(ubi);
134}
135
136PendingCall *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(agent->objectPath().path(), agent)) {
167 qCDebug(BLUEZQT) << "Cannot register object" << agent->objectPath().path();
168 }
169
170 return new PendingCall(d->m_bluezAgentManager->RegisterAgent(agent->objectPath(), capability), PendingCall::ReturnVoid, this);
171}
172
173PendingCall *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(agent->objectPath().path());
182
183 return new PendingCall(d->m_bluezAgentManager->UnregisterAgent(agent->objectPath()), PendingCall::ReturnVoid, this);
184}
185
186PendingCall *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->objectPath()), PendingCall::ReturnVoid, this);
195}
196
197PendingCall *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(profile->objectPath().path(), profile)) {
208 qCDebug(BLUEZQT) << "Cannot register object" << profile->objectPath().path();
209 }
210
211 return new PendingCall(d->m_bluezProfileManager->RegisterProfile(profile->objectPath(), profile->uuid(), profile->d->options),
212 PendingCall::ReturnVoid,
213 this);
214}
215
216PendingCall *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(profile->objectPath().path());
225
226 return new PendingCall(d->m_bluezProfileManager->UnregisterProfile(profile->objectPath()), PendingCall::ReturnVoid, this);
227}
228
229Rfkill *Manager::rfkill() const
230{
231 return d->m_rfkill;
232}
233
234} // namespace BluezQt
235
236#include "moc_manager.cpp"
237

source code of bluez-qt/src/manager.cpp