File indexing completed on 2024-05-19 05:28:34
0001 // SPDX-FileCopyrightText: 2021 Nicolas Fella <nicolas.fella@gmx.de> 0002 // 0003 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 0005 #include "modemcontroller.h" 0006 0007 #include <ModemManagerQt/Manager> 0008 0009 ModemController &ModemController::instance() 0010 { 0011 static ModemController instance; 0012 return instance; 0013 } 0014 0015 ModemController::ModemController() 0016 : QObject() 0017 { 0018 connect(ModemManager::notifier(), &ModemManager::Notifier::modemAdded, this, [this](const QString &udi) { 0019 init(udi); 0020 }); 0021 } 0022 0023 std::optional<QDBusPendingReply<QDBusObjectPath>> ModemController::createMessage(ModemManager::ModemMessaging::Message m) 0024 { 0025 if (!m_msgManager) { 0026 return {}; 0027 } 0028 0029 return m_msgManager->createMessage(m); 0030 } 0031 0032 void ModemController::init(std::optional<QString> modemPath) 0033 { 0034 if (modemPath) { 0035 m_modem = ModemManager::findModemDevice(*modemPath); 0036 } else { 0037 ModemManager::ModemDevice::List devices = ModemManager::modemDevices(); 0038 if (!devices.isEmpty()) { 0039 m_modem = devices.first(); 0040 } 0041 } 0042 0043 if (!m_modem) { 0044 qWarning() << "Could not find modem" << modemPath.value_or(QString()); 0045 return; 0046 } 0047 0048 if (m_modem->hasInterface(ModemManager::ModemDevice::GsmInterface)) { 0049 m_modem3gpp = m_modem->interface(ModemManager::ModemDevice::GsmInterface).objectCast<ModemManager::Modem3gpp>(); 0050 countryCode = m_modem3gpp->countryCode(); 0051 qDebug() << "Country Code:" << countryCode; 0052 0053 connect(m_modem3gpp.get(), &ModemManager::Modem3gpp::countryCodeChanged, this, [this](const QString &code) { 0054 countryCode = code; 0055 Q_EMIT countryCodeChanged(code); 0056 qDebug() << "country code changed" << code; 0057 }); 0058 0059 if (countryCode.isEmpty()) { 0060 qWarning() << "Country code is null! Phone numbers may not be interpreted correctly"; 0061 } 0062 } 0063 0064 m_interface = m_modem->modemInterface(); 0065 0066 connect(m_interface.get(), &ModemManager::Modem::bearerAdded, this, [this](const QString &bearer) { 0067 m_bearer = m_interface->findBearer(bearer); 0068 0069 QList<QSharedPointer<ModemManager::Bearer>> bearers = m_interface->listBearers(); 0070 for (const ModemManager::Bearer::Ptr &item : bearers) { 0071 if (item->uni() != bearer) { 0072 item->disconnect(); 0073 m_interface->deleteBearer(item->uni()); 0074 } 0075 } 0076 0077 // whether or not the bearer is connected and thus whether packet data communication using this bearer is possible 0078 connect(m_bearer.data(), &ModemManager::Bearer::connectedChanged, this, [this](bool isConnected) { 0079 Q_EMIT modemDataConnectedChanged(isConnected); 0080 qDebug() << "bearer connected:" << isConnected; 0081 }); 0082 0083 // In some devices, packet data service will be suspended while the device is handling other communication, like a voice call 0084 connect(m_bearer.data(), &ModemManager::Bearer::suspendedChanged, this, [this](bool isSuspended) { 0085 Q_EMIT modemDataConnectedChanged(!isSuspended); 0086 qDebug() << "bearer suspended:" << isSuspended; 0087 }); 0088 0089 dnsServers = getDNS(m_bearer); 0090 qDebug() << "dns:" << dnsServers; 0091 connect(m_bearer.data(), &ModemManager::Bearer::ip4ConfigChanged, this, [this, bearers](const ModemManager::IpConfig &ipv4Config) { 0092 dnsServers = getDNS(m_bearer); 0093 qDebug() << "dns4 updated:" << dnsServers; 0094 }); 0095 0096 connect(m_bearer.data(), &ModemManager::Bearer::ip6ConfigChanged, this, [this, bearers](const ModemManager::IpConfig &ipv6Config) { 0097 dnsServers = getDNS(m_bearer); 0098 qDebug() << "dns6 updated:" << dnsServers; 0099 }); 0100 0101 ifaceName = m_bearer->interface(); 0102 qDebug() << "interface:" << ifaceName; 0103 connect(m_bearer.data(), &ModemManager::Bearer::interfaceChanged, this, [this](const QString &iface) { 0104 ifaceName = iface; 0105 qDebug() << "interface changed:" << ifaceName; 0106 }); 0107 }); 0108 0109 connect(m_modem.get(), &ModemManager::ModemDevice::interfaceAdded, this, [this](ModemManager::ModemDevice::InterfaceType type) { 0110 if (type == ModemManager::ModemDevice::MessagingInterface) { 0111 initMessaging(); 0112 } 0113 }); 0114 0115 if (m_modem->hasInterface(ModemManager::ModemDevice::MessagingInterface)) { 0116 initMessaging(); 0117 } 0118 0119 connect(m_interface.get(), &ModemManager::Modem::stateChanged, this, [this](MMModemState oldState, MMModemState newState, MMModemStateChangeReason reason) { 0120 Q_UNUSED(oldState); 0121 Q_UNUSED(reason); 0122 if (newState == MMModemState::MM_MODEM_STATE_CONNECTED) { 0123 Q_EMIT modemConnected(); 0124 Q_EMIT modemDataConnectedChanged(m_bearer ? m_bearer->isConnected() : false); 0125 } 0126 }); 0127 } 0128 0129 void ModemController::initMessaging() 0130 { 0131 Q_ASSERT(m_modem); 0132 Q_ASSERT(m_modem->hasInterface(ModemManager::ModemDevice::MessagingInterface)); 0133 0134 m_msgManager = m_modem->messagingInterface(); 0135 0136 connect(m_msgManager.get(), &ModemManager::ModemMessaging::messageAdded, this, &ModemController::slotMessageAdded, Qt::UniqueConnection); 0137 0138 Q_EMIT modemConnected(); 0139 } 0140 0141 void ModemController::slotMessageAdded(const QString &uni, bool received) 0142 { 0143 // true if the message was received from the network, as opposed to being added locally 0144 if (!received) { 0145 return; 0146 } 0147 0148 ModemManager::Sms::Ptr msg = m_msgManager->findMessage(uni); 0149 Q_ASSERT(msg); 0150 0151 if (msg->state() == MMSmsState::MM_SMS_STATE_RECEIVING) { 0152 connect(msg.get(), &ModemManager::Sms::dataChanged, this, [this, msg]() { 0153 if (msg->state() == MMSmsState::MM_SMS_STATE_RECEIVED) { 0154 if (!msg->data().isEmpty()) { 0155 Q_EMIT messageAdded(msg); 0156 } 0157 } 0158 }); 0159 connect(msg.get(), &ModemManager::Sms::textChanged, this, [this, msg]() { 0160 if (msg->state() == MMSmsState::MM_SMS_STATE_RECEIVED) { 0161 if (!msg->text().isEmpty()) { 0162 Q_EMIT messageAdded(msg); 0163 } 0164 } 0165 }); 0166 } else { 0167 Q_EMIT messageAdded(msg); 0168 } 0169 } 0170 0171 void ModemController::deleteMessage(const QString &uni) 0172 { 0173 if (!m_msgManager) { 0174 return; 0175 } 0176 0177 m_msgManager->deleteMessage(uni); 0178 } 0179 0180 ModemManager::Sms::List ModemController::messages() 0181 { 0182 if (!m_msgManager) { 0183 ModemManager::Sms::List list; 0184 return list; 0185 } 0186 0187 return m_msgManager->messages(); 0188 } 0189 0190 QString ModemController::ownNumber() 0191 { 0192 if (!m_interface) { 0193 return QString(); 0194 } 0195 0196 const QStringList numbers = m_interface->ownNumbers(); 0197 0198 if (!numbers.isEmpty()) { 0199 if (numbers.startsWith(QStringLiteral("+"))) { 0200 return numbers.first(); 0201 } 0202 return QStringLiteral("+") + numbers.first(); 0203 } 0204 0205 return QString(); 0206 } 0207 0208 QString ModemController::getDNS(QSharedPointer<ModemManager::Bearer> bearer) 0209 { 0210 QStringList dnsServerList = {bearer->ip4Config().dns1(), 0211 bearer->ip4Config().dns2(), 0212 bearer->ip4Config().dns3(), 0213 bearer->ip6Config().dns1(), 0214 bearer->ip6Config().dns2(), 0215 bearer->ip6Config().dns3()}; 0216 0217 // remove empty items 0218 dnsServerList.removeAll(QString()); 0219 0220 return dnsServerList.join(QStringLiteral(",")); 0221 }