File indexing completed on 2024-05-05 03:52:30

0001 /*
0002  * BluezQt - Asynchronous Bluez wrapper library
0003  *
0004  * SPDX-FileCopyrightText: 2014 David Rosca <nowrep@gmail.com>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007  */
0008 
0009 #include "manager.h"
0010 
0011 #include "adapter.h"
0012 #include "agent.h"
0013 #include "agentadaptor.h"
0014 #include "debug.h"
0015 #include "initmanagerjob.h"
0016 #include "manager_p.h"
0017 #include "pendingcall.h"
0018 #include "profile.h"
0019 #include "profile_p.h"
0020 #include "profileadaptor.h"
0021 #include "utils.h"
0022 
0023 namespace BluezQt
0024 {
0025 Manager::Manager(QObject *parent)
0026     : QObject(parent)
0027     , d(new ManagerPrivate(this))
0028 {
0029     Instance::setManager(this);
0030 }
0031 
0032 Manager::~Manager() = default;
0033 
0034 InitManagerJob *Manager::init()
0035 {
0036     return new InitManagerJob(this);
0037 }
0038 
0039 bool Manager::isInitialized() const
0040 {
0041     return d->m_initialized;
0042 }
0043 
0044 bool Manager::isOperational() const
0045 {
0046     return d->m_initialized && d->m_bluezRunning && d->m_loaded;
0047 }
0048 
0049 bool Manager::isBluetoothOperational() const
0050 {
0051     return !d->m_bluetoothBlocked && d->m_bluezRunning && d->m_loaded && d->m_usableAdapter;
0052 }
0053 
0054 bool Manager::isBluetoothBlocked() const
0055 {
0056     return d->m_bluetoothBlocked;
0057 }
0058 
0059 void Manager::setBluetoothBlocked(bool blocked)
0060 {
0061     if (blocked) {
0062         d->m_rfkill->block();
0063     } else {
0064         d->m_rfkill->unblock();
0065     }
0066 }
0067 
0068 AdapterPtr Manager::usableAdapter() const
0069 {
0070     return d->m_usableAdapter;
0071 }
0072 
0073 QList<AdapterPtr> Manager::adapters() const
0074 {
0075     return d->m_adapters.values();
0076 }
0077 
0078 QList<DevicePtr> Manager::devices() const
0079 {
0080     return d->m_devices.values();
0081 }
0082 
0083 PendingCall *Manager::startService()
0084 {
0085     QDBusMessage msg = QDBusMessage::createMethodCall(Strings::orgFreedesktopDBus(),
0086                                                       QStringLiteral("/org/freedesktop/DBus"),
0087                                                       Strings::orgFreedesktopDBus(),
0088                                                       QStringLiteral("StartServiceByName"));
0089     msg << Strings::orgBluez();
0090     msg << quint32(0);
0091 
0092     return new PendingCall(DBusConnection::orgBluez().asyncCall(msg), PendingCall::ReturnUint32);
0093 }
0094 
0095 AdapterPtr Manager::adapterForAddress(const QString &address) const
0096 {
0097     for (AdapterPtr adapter : std::as_const(d->m_adapters)) {
0098         if (adapter->address() == address) {
0099             return adapter;
0100         }
0101     }
0102     return AdapterPtr();
0103 }
0104 
0105 AdapterPtr Manager::adapterForUbi(const QString &ubi) const
0106 {
0107     return d->m_adapters.value(ubi);
0108 }
0109 
0110 DevicePtr Manager::deviceForAddress(const QString &address) const
0111 {
0112     DevicePtr device;
0113 
0114     for (AdapterPtr adapter : std::as_const(d->m_adapters)) {
0115         DevicePtr oneDevice = adapter->deviceForAddress(address);
0116         if (!oneDevice) {
0117             continue;
0118         }
0119 
0120         // Prefer powered adapter
0121         if (!device) {
0122             device = oneDevice;
0123         } else if (adapter->isPowered()) {
0124             device = oneDevice;
0125         }
0126     }
0127 
0128     return device;
0129 }
0130 
0131 DevicePtr Manager::deviceForUbi(const QString &ubi) const
0132 {
0133     return d->m_devices.value(ubi);
0134 }
0135 
0136 PendingCall *Manager::registerAgent(Agent *agent)
0137 {
0138     Q_ASSERT(agent);
0139 
0140     if (!d->m_bluezAgentManager) {
0141         return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!"));
0142     }
0143 
0144     QString capability;
0145 
0146     switch (agent->capability()) {
0147     case Agent::DisplayOnly:
0148         capability = QStringLiteral("DisplayOnly");
0149         break;
0150     case Agent::DisplayYesNo:
0151         capability = QStringLiteral("DisplayYesNo");
0152         break;
0153     case Agent::KeyboardOnly:
0154         capability = QStringLiteral("KeyboardOnly");
0155         break;
0156     case Agent::NoInputNoOutput:
0157         capability = QStringLiteral("NoInputNoOutput");
0158         break;
0159     default:
0160         capability = QStringLiteral("DisplayYesNo");
0161         break;
0162     }
0163 
0164     new AgentAdaptor(agent, this);
0165 
0166     if (!DBusConnection::orgBluez().registerObject(agent->objectPath().path(), agent)) {
0167         qCDebug(BLUEZQT) << "Cannot register object" << agent->objectPath().path();
0168     }
0169 
0170     return new PendingCall(d->m_bluezAgentManager->RegisterAgent(agent->objectPath(), capability), PendingCall::ReturnVoid, this);
0171 }
0172 
0173 PendingCall *Manager::unregisterAgent(Agent *agent)
0174 {
0175     Q_ASSERT(agent);
0176 
0177     if (!d->m_bluezAgentManager) {
0178         return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!"));
0179     }
0180 
0181     DBusConnection::orgBluez().unregisterObject(agent->objectPath().path());
0182 
0183     return new PendingCall(d->m_bluezAgentManager->UnregisterAgent(agent->objectPath()), PendingCall::ReturnVoid, this);
0184 }
0185 
0186 PendingCall *Manager::requestDefaultAgent(Agent *agent)
0187 {
0188     Q_ASSERT(agent);
0189 
0190     if (!d->m_bluezAgentManager) {
0191         return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!"));
0192     }
0193 
0194     return new PendingCall(d->m_bluezAgentManager->RequestDefaultAgent(agent->objectPath()), PendingCall::ReturnVoid, this);
0195 }
0196 
0197 PendingCall *Manager::registerProfile(Profile *profile)
0198 {
0199     Q_ASSERT(profile);
0200 
0201     if (!d->m_bluezProfileManager) {
0202         return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!"));
0203     }
0204 
0205     new ProfileAdaptor(profile, this);
0206 
0207     if (!DBusConnection::orgBluez().registerObject(profile->objectPath().path(), profile)) {
0208         qCDebug(BLUEZQT) << "Cannot register object" << profile->objectPath().path();
0209     }
0210 
0211     return new PendingCall(d->m_bluezProfileManager->RegisterProfile(profile->objectPath(), profile->uuid(), profile->d->options),
0212                            PendingCall::ReturnVoid,
0213                            this);
0214 }
0215 
0216 PendingCall *Manager::unregisterProfile(Profile *profile)
0217 {
0218     Q_ASSERT(profile);
0219 
0220     if (!d->m_bluezProfileManager) {
0221         return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!"));
0222     }
0223 
0224     DBusConnection::orgBluez().unregisterObject(profile->objectPath().path());
0225 
0226     return new PendingCall(d->m_bluezProfileManager->UnregisterProfile(profile->objectPath()), PendingCall::ReturnVoid, this);
0227 }
0228 
0229 Rfkill *Manager::rfkill() const
0230 {
0231     return d->m_rfkill;
0232 }
0233 
0234 } // namespace BluezQt
0235 
0236 #include "moc_manager.cpp"