File indexing completed on 2024-04-21 16:11:36

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 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0097             int num = m_pin.rightRef(m_pin.length() - 4).toInt();
0098 #else
0099             int num = QStringView(m_pin).right(m_pin.length() - 4).toInt();
0100 #endif
0101             m_pin = QString::number(QRandomGenerator::global()->bounded(RAND_MAX)).left(num);
0102         }
0103 
0104         qCDebug(BLUEDEVIL_WIZARD_LOG) << "PIN: " << m_pin;
0105         return m_pin;
0106     }
0107 
0108     return m_pin;
0109 }
0110 
0111 QDBusObjectPath WizardAgent::objectPath() const
0112 {
0113     return QDBusObjectPath(QStringLiteral("/agent"));
0114 }
0115 
0116 void WizardAgent::requestPinCode(BluezQt::DevicePtr device, const BluezQt::Request<QString> &req)
0117 {
0118     qCDebug(BLUEDEVIL_WIZARD_LOG) << "AGENT-RequestPinCode" << device->ubi();
0119 
0120     Q_EMIT pinRequested(m_pin);
0121     req.accept(m_pin);
0122 }
0123 
0124 void WizardAgent::displayPinCode(BluezQt::DevicePtr device, const QString &pinCode)
0125 {
0126     qCDebug(BLUEDEVIL_WIZARD_LOG) << "AGENT-DisplayPinCode" << device->ubi() << pinCode;
0127 
0128     Q_EMIT pinRequested(pinCode);
0129 }
0130 
0131 void WizardAgent::requestPasskey(BluezQt::DevicePtr device, const BluezQt::Request<quint32> &req)
0132 {
0133     qCDebug(BLUEDEVIL_WIZARD_LOG) << "AGENT-RequestPasskey" << device->ubi();
0134 
0135     Q_EMIT pinRequested(m_pin);
0136     req.accept(m_pin.toUInt());
0137 }
0138 
0139 void WizardAgent::displayPasskey(BluezQt::DevicePtr device, const QString &passkey, const QString &entered)
0140 {
0141     Q_UNUSED(entered);
0142 
0143     qCDebug(BLUEDEVIL_WIZARD_LOG) << "AGENT-DisplayPasskey" << device->ubi() << passkey;
0144 
0145     Q_EMIT pinRequested(passkey);
0146 }
0147 
0148 void WizardAgent::requestConfirmation(BluezQt::DevicePtr device, const QString &passkey, const BluezQt::Request<> &req)
0149 {
0150     qCDebug(BLUEDEVIL_WIZARD_LOG) << "AGENT-RequestConfirmation " << device->ubi() << passkey;
0151 
0152     Q_EMIT confirmationRequested(passkey, req);
0153 }