File indexing completed on 2024-09-29 07:46:22

0001 /*
0002  *   SPDX-FileCopyrightText: 2010 Alex Fiestas <alex@eyeos.org>
0003  *   SPDX-FileCopyrightText: 2010 UFO Coders <info@ufocoders.com>
0004  *
0005  *   SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "wizardagent.h"
0009 #include "bluedevil_wizard.h"
0010 
0011 #include <QDBusObjectPath>
0012 #include <QFile>
0013 #include <QStandardPaths>
0014 #include <QXmlStreamReader>
0015 
0016 #include <KLocalizedString>
0017 #include <KRandom>
0018 
0019 #include <BluezQt/Device>
0020 
0021 WizardAgent::WizardAgent(QObject *parent)
0022     : BluezQt::Agent(parent)
0023 {
0024 }
0025 
0026 QString WizardAgent::pin() const
0027 {
0028     return m_pin;
0029 }
0030 
0031 void WizardAgent::setPin(const QString &pin)
0032 {
0033     m_pin = pin;
0034     m_fromDatabase = false;
0035 }
0036 
0037 bool WizardAgent::isFromDatabase()
0038 {
0039     return m_fromDatabase;
0040 }
0041 
0042 QString WizardAgent::getPin(BluezQt::DevicePtr device)
0043 {
0044     m_fromDatabase = false;
0045     m_pin = QString::number(QRandomGenerator::global()->bounded(RAND_MAX));
0046     m_pin = m_pin.left(6);
0047 
0048     const QString &xmlPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("pin-code-database.xml"));
0049 
0050     QFile file(xmlPath);
0051     if (!file.open(QIODevice::ReadOnly)) {
0052         qCDebug(BLUEDEVIL_WIZARD_LOG) << "Can't open the pin-code-database.xml";
0053         return m_pin;
0054     }
0055 
0056     QXmlStreamReader xml(&file);
0057 
0058     QString deviceType = BluezQt::Device::typeToString(device->type());
0059     if (deviceType == QLatin1String("audiovideo")) {
0060         deviceType = QStringLiteral("audio");
0061     }
0062 
0063     while (!xml.atEnd()) {
0064         xml.readNext();
0065         if (xml.name() != QLatin1String("device")) {
0066             continue;
0067         }
0068         QXmlStreamAttributes attr = xml.attributes();
0069 
0070         if (attr.count() == 0) {
0071             continue;
0072         }
0073 
0074         if (attr.hasAttribute(QLatin1String("type")) && attr.value(QLatin1String("type")) != QLatin1String("any")) {
0075             if (deviceType != attr.value(QLatin1String("type")).toString()) {
0076                 continue;
0077             }
0078         }
0079 
0080         if (attr.hasAttribute(QLatin1String("oui"))) {
0081             if (!device->address().startsWith(attr.value(QLatin1String("oui")).toString())) {
0082                 continue;
0083             }
0084         }
0085 
0086         if (attr.hasAttribute(QLatin1String("name"))) {
0087             if (device->name() != attr.value(QLatin1String("name")).toString()) {
0088                 continue;
0089             }
0090         }
0091 
0092         m_pin = attr.value(QLatin1String("pin")).toString();
0093         m_fromDatabase = true;
0094         if (m_pin.startsWith(QLatin1String("max:"))) {
0095             m_fromDatabase = false;
0096             int num = QStringView(m_pin).right(m_pin.length() - 4).toInt();
0097             m_pin = QString::number(QRandomGenerator::global()->bounded(RAND_MAX)).left(num);
0098         }
0099 
0100         qCDebug(BLUEDEVIL_WIZARD_LOG) << "PIN: " << m_pin;
0101         return m_pin;
0102     }
0103 
0104     return m_pin;
0105 }
0106 
0107 QDBusObjectPath WizardAgent::objectPath() const
0108 {
0109     return QDBusObjectPath(QStringLiteral("/agent"));
0110 }
0111 
0112 void WizardAgent::requestPinCode(BluezQt::DevicePtr device, const BluezQt::Request<QString> &req)
0113 {
0114     qCDebug(BLUEDEVIL_WIZARD_LOG) << "AGENT-RequestPinCode" << device->ubi();
0115 
0116     Q_EMIT pinRequested(m_pin);
0117     req.accept(m_pin);
0118 }
0119 
0120 void WizardAgent::displayPinCode(BluezQt::DevicePtr device, const QString &pinCode)
0121 {
0122     qCDebug(BLUEDEVIL_WIZARD_LOG) << "AGENT-DisplayPinCode" << device->ubi() << pinCode;
0123 
0124     Q_EMIT pinRequested(pinCode);
0125 }
0126 
0127 void WizardAgent::requestPasskey(BluezQt::DevicePtr device, const BluezQt::Request<quint32> &req)
0128 {
0129     qCDebug(BLUEDEVIL_WIZARD_LOG) << "AGENT-RequestPasskey" << device->ubi();
0130 
0131     Q_EMIT pinRequested(m_pin);
0132     req.accept(m_pin.toUInt());
0133 }
0134 
0135 void WizardAgent::displayPasskey(BluezQt::DevicePtr device, const QString &passkey, const QString &entered)
0136 {
0137     Q_UNUSED(entered);
0138 
0139     qCDebug(BLUEDEVIL_WIZARD_LOG) << "AGENT-DisplayPasskey" << device->ubi() << passkey;
0140 
0141     Q_EMIT pinRequested(passkey);
0142 }
0143 
0144 void WizardAgent::requestConfirmation(BluezQt::DevicePtr device, const QString &passkey, const BluezQt::Request<> &req)
0145 {
0146     qCDebug(BLUEDEVIL_WIZARD_LOG) << "AGENT-RequestConfirmation " << device->ubi() << passkey;
0147 
0148     Q_EMIT confirmationRequested(passkey, req);
0149 }
0150 
0151 #include "moc_wizardagent.cpp"