File indexing completed on 2024-04-28 11:47:34

0001 /*
0002     SPDX-FileCopyrightText: 2008, 2011 Will Stephenson <wstephenson@kde.org>
0003     SPDX-FileCopyrightText: 2010 Lamarque Souza <lamarque@kde.org>
0004     SPDX-FileCopyrightText: 2013 Lukas Tinkl <ltinkl@redhat.com>
0005     SPDX-FileCopyrightText: 2013-2015 Jan Grulich <jgrulich@redhat.com>
0006 
0007     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0008 */
0009 
0010 #include "modem3gpp.h"
0011 #include "mmdebug_p.h"
0012 #include "modem3gpp_p.h"
0013 #ifdef MMQT_STATIC
0014 #include "dbus/fakedbus.h"
0015 #else
0016 #include "dbus/dbus.h"
0017 #endif
0018 
0019 ModemManager::Modem3gppPrivate::Modem3gppPrivate(const QString &path, Modem3gpp *q)
0020     : InterfacePrivate(path, q)
0021 #ifdef MMQT_STATIC
0022     , modem3gppIface(QLatin1String(MMQT_DBUS_SERVICE), path, QDBusConnection::sessionBus())
0023 #else
0024     , modem3gppIface(QLatin1String(MMQT_DBUS_SERVICE), path, QDBusConnection::systemBus())
0025 #endif
0026     , q_ptr(q)
0027 {
0028     if (modem3gppIface.isValid()) {
0029         imei = modem3gppIface.imei();
0030         registrationState = (MMModem3gppRegistrationState)modem3gppIface.registrationState();
0031         operatorCode = modem3gppIface.operatorCode();
0032         operatorName = modem3gppIface.operatorName();
0033         enabledFacilityLocks = (QFlags<MMModem3gppFacility>)modem3gppIface.enabledFacilityLocks();
0034 #if MM_CHECK_VERSION(1, 2, 0)
0035         subscriptionState = (MMModem3gppSubscriptionState)modem3gppIface.subscriptionState();
0036 #endif
0037 
0038 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
0039         QStringView mcc(operatorCode);
0040         if (!operatorCode.isEmpty() && operatorCode.count() > 3) {
0041             mcc = mcc.sliced(0, 3);
0042         }
0043 #else
0044         QStringRef mcc(&operatorCode, 0, 3);
0045 #endif
0046         QString cc = mobileCountryCodeToAlpha2CountryCode(mcc.toInt());
0047         if (cc != countryCode) {
0048             countryCode = cc;
0049         }
0050     }
0051 }
0052 
0053 ModemManager::Modem3gpp::Modem3gpp(const QString &path, QObject *parent)
0054     : Interface(*new Modem3gppPrivate(path, this), parent)
0055 {
0056     Q_D(Modem3gpp);
0057 
0058     qRegisterMetaType<QFlags<MMModem3gppFacility>>();
0059     qRegisterMetaType<MMModem3gppRegistrationState>();
0060 #if MM_CHECK_VERSION(1, 2, 0)
0061     qRegisterMetaType<MMModem3gppSubscriptionState>();
0062 #endif
0063 #ifdef MMQT_STATIC
0064     QDBusConnection::sessionBus().connect(QLatin1String(MMQT_DBUS_SERVICE),
0065                                           d->uni,
0066                                           QLatin1String(DBUS_INTERFACE_PROPS),
0067                                           QStringLiteral("PropertiesChanged"),
0068                                           d,
0069                                           SLOT(onPropertiesChanged(QString, QVariantMap, QStringList)));
0070 #else
0071     QDBusConnection::systemBus().connect(QLatin1String(MMQT_DBUS_SERVICE),
0072                                          d->uni,
0073                                          QLatin1String(DBUS_INTERFACE_PROPS),
0074                                          QStringLiteral("PropertiesChanged"),
0075                                          d,
0076                                          SLOT(onPropertiesChanged(QString, QVariantMap, QStringList)));
0077 #endif
0078 }
0079 
0080 ModemManager::Modem3gpp::~Modem3gpp()
0081 {
0082 }
0083 
0084 QString ModemManager::Modem3gpp::imei() const
0085 {
0086     Q_D(const Modem3gpp);
0087     return d->imei;
0088 }
0089 
0090 MMModem3gppRegistrationState ModemManager::Modem3gpp::registrationState() const
0091 {
0092     Q_D(const Modem3gpp);
0093     return d->registrationState;
0094 }
0095 
0096 QString ModemManager::Modem3gpp::operatorCode() const
0097 {
0098     Q_D(const Modem3gpp);
0099     return d->operatorCode;
0100 }
0101 
0102 QString ModemManager::Modem3gpp::operatorName() const
0103 {
0104     Q_D(const Modem3gpp);
0105     return d->operatorName;
0106 }
0107 
0108 QString ModemManager::Modem3gpp::countryCode() const
0109 {
0110     Q_D(const Modem3gpp);
0111     return d->countryCode;
0112 }
0113 
0114 ModemManager::Modem3gpp::FacilityLocks ModemManager::Modem3gpp::enabledFacilityLocks() const
0115 {
0116     Q_D(const Modem3gpp);
0117     return d->enabledFacilityLocks;
0118 }
0119 
0120 #if MM_CHECK_VERSION(1, 2, 0)
0121 MMModem3gppSubscriptionState ModemManager::Modem3gpp::subscriptionState() const
0122 {
0123     Q_D(const Modem3gpp);
0124     return d->subscriptionState;
0125 }
0126 #endif
0127 
0128 void ModemManager::Modem3gpp::registerToNetwork(const QString &networkId)
0129 {
0130     Q_D(Modem3gpp);
0131     d->modem3gppIface.Register(networkId);
0132 }
0133 
0134 QDBusPendingReply<ModemManager::QVariantMapList> ModemManager::Modem3gpp::scan()
0135 {
0136     Q_D(Modem3gpp);
0137     return d->modem3gppIface.Scan();
0138 }
0139 
0140 void ModemManager::Modem3gpp::setTimeout(int timeout)
0141 {
0142     Q_D(Modem3gpp);
0143     d->modem3gppIface.setTimeout(timeout);
0144 }
0145 
0146 int ModemManager::Modem3gpp::timeout() const
0147 {
0148     Q_D(const Modem3gpp);
0149     return d->modem3gppIface.timeout();
0150 }
0151 
0152 void ModemManager::Modem3gppPrivate::onPropertiesChanged(const QString &interface, const QVariantMap &properties, const QStringList &invalidatedProps)
0153 {
0154     Q_Q(Modem3gpp);
0155     Q_UNUSED(invalidatedProps);
0156     qCDebug(MMQT) << interface << properties.keys();
0157 
0158     if (interface == QLatin1String(MMQT_DBUS_INTERFACE_MODEM_MODEM3GPP)) {
0159         QVariantMap::const_iterator it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_IMEI));
0160         if (it != properties.constEnd()) {
0161             imei = it->toString();
0162             Q_EMIT q->imeiChanged(imei);
0163         }
0164         it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_REGISTRATIONSTATE));
0165         if (it != properties.constEnd()) {
0166             registrationState = (MMModem3gppRegistrationState)it->toUInt();
0167             Q_EMIT q->registrationStateChanged(registrationState);
0168         }
0169         it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_OPERATORCODE));
0170         if (it != properties.constEnd()) {
0171             operatorCode = it->toString();
0172             Q_EMIT q->operatorCodeChanged(operatorCode);
0173 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
0174             QStringView mcc(operatorCode);
0175             if (!operatorCode.isEmpty() && operatorCode.count() > 3) {
0176                 mcc = mcc.sliced(0, 3);
0177             }
0178 #else
0179             QStringRef mcc(&operatorCode, 0, 3);
0180 #endif
0181             QString cc = mobileCountryCodeToAlpha2CountryCode(mcc.toInt());
0182             if (cc != countryCode) {
0183                 countryCode = cc;
0184                 Q_EMIT q->countryCodeChanged(countryCode);
0185             }
0186         }
0187         it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_OPERATORNAME));
0188         if (it != properties.constEnd()) {
0189             operatorName = it->toString();
0190             Q_EMIT q->operatorNameChanged(operatorName);
0191         }
0192         it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS));
0193         if (it != properties.constEnd()) {
0194             enabledFacilityLocks = (QFlags<MMModem3gppFacility>)it->toUInt();
0195             Q_EMIT q->enabledFacilityLocksChanged(enabledFacilityLocks);
0196         }
0197 #if MM_CHECK_VERSION(1, 2, 0)
0198         it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_SUBSCRIPTIONSTATE));
0199         if (it != properties.constEnd()) {
0200             subscriptionState = (MMModem3gppSubscriptionState)it->toUInt();
0201             Q_EMIT q->subscriptionStateChanged(subscriptionState);
0202         }
0203 #endif
0204     }
0205 }
0206 
0207 // The logic ported from the Qt wrapper for ofono from Jolla's Sailfish OS
0208 // https://github.com/sailfishos/libqofono/blob/94e793860debe9c73c70de94cc3510e7609137b9/src/qofono.cpp#L2379
0209 
0210 QString ModemManager::Modem3gppPrivate::mobileCountryCodeToAlpha2CountryCode(int mcc) const
0211 {
0212     const int n = sizeof(mccList) / sizeof(mccList[0]);
0213 
0214     int low = 0;
0215     int high = n;
0216 
0217     while (low < high) {
0218         const int mid = (low + high) / 2;
0219         if (mccList[mid].mcc >= mcc) {
0220             high = mid;
0221         } else {
0222             low = mid + 1;
0223         }
0224     }
0225 
0226     if (high < n && mccList[high].mcc == mcc) {
0227         return QString::fromLatin1(mccList[high].cc);
0228     } else {
0229         qCWarning(MMQT) << "Unknown Mobile Country Code:" << mcc;
0230         return QString();
0231     }
0232 }
0233 
0234 #include "moc_modem3gpp.cpp"