File indexing completed on 2024-04-28 07:48:53

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         QStringView mcc(operatorCode);
0039         if (!operatorCode.isEmpty() && operatorCode.size() > 3) {
0040             mcc = mcc.sliced(0, 3);
0041         }
0042         QString cc = mobileCountryCodeToAlpha2CountryCode(mcc.toInt());
0043         if (cc != countryCode) {
0044             countryCode = cc;
0045         }
0046     }
0047 }
0048 
0049 ModemManager::Modem3gpp::Modem3gpp(const QString &path, QObject *parent)
0050     : Interface(*new Modem3gppPrivate(path, this), parent)
0051 {
0052     Q_D(Modem3gpp);
0053 
0054     qRegisterMetaType<QFlags<MMModem3gppFacility>>();
0055     qRegisterMetaType<MMModem3gppRegistrationState>();
0056 #if MM_CHECK_VERSION(1, 2, 0)
0057     qRegisterMetaType<MMModem3gppSubscriptionState>();
0058 #endif
0059 #ifdef MMQT_STATIC
0060     QDBusConnection::sessionBus().connect(QLatin1String(MMQT_DBUS_SERVICE),
0061                                           d->uni,
0062                                           QLatin1String(DBUS_INTERFACE_PROPS),
0063                                           QStringLiteral("PropertiesChanged"),
0064                                           d,
0065                                           SLOT(onPropertiesChanged(QString, QVariantMap, QStringList)));
0066 #else
0067     QDBusConnection::systemBus().connect(QLatin1String(MMQT_DBUS_SERVICE),
0068                                          d->uni,
0069                                          QLatin1String(DBUS_INTERFACE_PROPS),
0070                                          QStringLiteral("PropertiesChanged"),
0071                                          d,
0072                                          SLOT(onPropertiesChanged(QString, QVariantMap, QStringList)));
0073 #endif
0074 }
0075 
0076 ModemManager::Modem3gpp::~Modem3gpp()
0077 {
0078 }
0079 
0080 QString ModemManager::Modem3gpp::imei() const
0081 {
0082     Q_D(const Modem3gpp);
0083     return d->imei;
0084 }
0085 
0086 MMModem3gppRegistrationState ModemManager::Modem3gpp::registrationState() const
0087 {
0088     Q_D(const Modem3gpp);
0089     return d->registrationState;
0090 }
0091 
0092 QString ModemManager::Modem3gpp::operatorCode() const
0093 {
0094     Q_D(const Modem3gpp);
0095     return d->operatorCode;
0096 }
0097 
0098 QString ModemManager::Modem3gpp::operatorName() const
0099 {
0100     Q_D(const Modem3gpp);
0101     return d->operatorName;
0102 }
0103 
0104 QString ModemManager::Modem3gpp::countryCode() const
0105 {
0106     Q_D(const Modem3gpp);
0107     return d->countryCode;
0108 }
0109 
0110 ModemManager::Modem3gpp::FacilityLocks ModemManager::Modem3gpp::enabledFacilityLocks() const
0111 {
0112     Q_D(const Modem3gpp);
0113     return d->enabledFacilityLocks;
0114 }
0115 
0116 #if MM_CHECK_VERSION(1, 2, 0)
0117 MMModem3gppSubscriptionState ModemManager::Modem3gpp::subscriptionState() const
0118 {
0119     Q_D(const Modem3gpp);
0120     return d->subscriptionState;
0121 }
0122 #endif
0123 
0124 void ModemManager::Modem3gpp::registerToNetwork(const QString &networkId)
0125 {
0126     Q_D(Modem3gpp);
0127     d->modem3gppIface.Register(networkId);
0128 }
0129 
0130 QDBusPendingReply<ModemManager::QVariantMapList> ModemManager::Modem3gpp::scan()
0131 {
0132     Q_D(Modem3gpp);
0133     return d->modem3gppIface.Scan();
0134 }
0135 
0136 void ModemManager::Modem3gpp::setTimeout(int timeout)
0137 {
0138     Q_D(Modem3gpp);
0139     d->modem3gppIface.setTimeout(timeout);
0140 }
0141 
0142 int ModemManager::Modem3gpp::timeout() const
0143 {
0144     Q_D(const Modem3gpp);
0145     return d->modem3gppIface.timeout();
0146 }
0147 
0148 void ModemManager::Modem3gppPrivate::onPropertiesChanged(const QString &interface, const QVariantMap &properties, const QStringList &invalidatedProps)
0149 {
0150     Q_Q(Modem3gpp);
0151     Q_UNUSED(invalidatedProps);
0152     qCDebug(MMQT) << interface << properties.keys();
0153 
0154     if (interface == QLatin1String(MMQT_DBUS_INTERFACE_MODEM_MODEM3GPP)) {
0155         QVariantMap::const_iterator it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_IMEI));
0156         if (it != properties.constEnd()) {
0157             imei = it->toString();
0158             Q_EMIT q->imeiChanged(imei);
0159         }
0160         it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_REGISTRATIONSTATE));
0161         if (it != properties.constEnd()) {
0162             registrationState = (MMModem3gppRegistrationState)it->toUInt();
0163             Q_EMIT q->registrationStateChanged(registrationState);
0164         }
0165         it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_OPERATORCODE));
0166         if (it != properties.constEnd()) {
0167             operatorCode = it->toString();
0168             Q_EMIT q->operatorCodeChanged(operatorCode);
0169             QStringView mcc(operatorCode);
0170             if (!operatorCode.isEmpty() && operatorCode.size() > 3) {
0171                 mcc = mcc.sliced(0, 3);
0172             }
0173             QString cc = mobileCountryCodeToAlpha2CountryCode(mcc.toInt());
0174             if (cc != countryCode) {
0175                 countryCode = cc;
0176                 Q_EMIT q->countryCodeChanged(countryCode);
0177             }
0178         }
0179         it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_OPERATORNAME));
0180         if (it != properties.constEnd()) {
0181             operatorName = it->toString();
0182             Q_EMIT q->operatorNameChanged(operatorName);
0183         }
0184         it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS));
0185         if (it != properties.constEnd()) {
0186             enabledFacilityLocks = (QFlags<MMModem3gppFacility>)it->toUInt();
0187             Q_EMIT q->enabledFacilityLocksChanged(enabledFacilityLocks);
0188         }
0189 #if MM_CHECK_VERSION(1, 2, 0)
0190         it = properties.constFind(QLatin1String(MM_MODEM_MODEM3GPP_PROPERTY_SUBSCRIPTIONSTATE));
0191         if (it != properties.constEnd()) {
0192             subscriptionState = (MMModem3gppSubscriptionState)it->toUInt();
0193             Q_EMIT q->subscriptionStateChanged(subscriptionState);
0194         }
0195 #endif
0196     }
0197 }
0198 
0199 // The logic ported from the Qt wrapper for ofono from Jolla's Sailfish OS
0200 // https://github.com/sailfishos/libqofono/blob/94e793860debe9c73c70de94cc3510e7609137b9/src/qofono.cpp#L2379
0201 
0202 QString ModemManager::Modem3gppPrivate::mobileCountryCodeToAlpha2CountryCode(int mcc) const
0203 {
0204     const int n = sizeof(mccList) / sizeof(mccList[0]);
0205 
0206     int low = 0;
0207     int high = n;
0208 
0209     while (low < high) {
0210         const int mid = (low + high) / 2;
0211         if (mccList[mid].mcc >= mcc) {
0212             high = mid;
0213         } else {
0214             low = mid + 1;
0215         }
0216     }
0217 
0218     if (high < n && mccList[high].mcc == mcc) {
0219         return QString::fromLatin1(mccList[high].cc);
0220     } else {
0221         qCWarning(MMQT) << "Unknown Mobile Country Code:" << mcc;
0222         return QString();
0223     }
0224 }
0225 
0226 #include "moc_modem3gpp.cpp"