Commit 835c65da authored by Lamarque Souza's avatar Lamarque Souza
Browse files

Try to unlock (PIN/PUK) and enable modem before connecting to Gsm

connections.

BUG: 264083
parent aabca85c
......@@ -41,6 +41,11 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include <interfaceconnection.h>
#include <vpninterfaceconnection.h>
#ifdef COMPILE_MODEM_MANAGER_SUPPORT
#include <solid/control/networkgsminterface.h>
#include <solid/control/modeminterface.h>
#endif
#include "busconnection.h"
#include "exportedconnection.h"
#include "exportedconnectionsecrets.h"
......@@ -232,6 +237,21 @@ void NMDBusSettingsService::interfaceConnectionActivated()
deviceToActivateOn = ic->deviceUni();
}
#ifdef COMPILE_MODEM_MANAGER_SUPPORT
// Enable modem before connecting.
Solid::Control::GsmNetworkInterface *iface = qobject_cast<Solid::Control::GsmNetworkInterface *>(Solid::Control::NetworkManager::findNetworkInterface(deviceToActivateOn));
if (iface) {
Solid::Control::ModemGsmCardInterface *modem = iface->getModemCardIface();
if (modem && !modem->enabled()) {
// Try to pin-unlock the modem.
QMetaObject::invokeMethod(modem, "unlockRequiredChanged", Qt::DirectConnection,
Q_ARG(QString, modem->unlockRequired()));
kDebug() << "Trying to enable modem";
modem->enable(true);
}
}
#endif
Solid::Control::NetworkManager::activateConnection(deviceToActivateOn,
QString::fromLatin1("%1 %2")
.arg(ic->property("NMDBusService").toString(), ic->property("NMDBusObjectPath").toString()),
......
......@@ -5,6 +5,8 @@ include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../../solidcontrolfuture
${CMAKE_CURRENT_SOURCE_DIR}/../libs/client
${CMAKE_CURRENT_SOURCE_DIR}/../../backends/NetworkManager
${CMAKE_CURRENT_SOURCE_DIR}/../../libs
)
## next target: internals layer library
......
......@@ -67,8 +67,15 @@ set(knmservice_SRCS
# sort logic for activatables
sortedactivatablelist.cpp
# dialog to ask for PIN code
pindialog.cpp
)
kde4_add_ui_files(knmservice_SRCS
# Ask for PIN unlock code
pinwidget.ui
)
qt4_add_dbus_adaptor(
knmservice_SRCS
......
......@@ -20,6 +20,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include <KToolInvocation>
#include <KStandardDirs>
#include <KLocale>
#include "networkinterfacemonitor.h"
......@@ -34,7 +35,15 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "wirelessnetworkinterfaceactivatableprovider.h"
#ifdef COMPILE_MODEM_MANAGER_SUPPORT
#include <KAuth/Action>
#include <kauthactionreply.h>
#include <KMessageBox>
#include <solid/control/modeminterface.h>
#include <solid/control/modemmanager.h>
#include "gsmnetworkinterfaceactivatableprovider.h"
#include "pindialog.h"
#endif
class NetworkInterfaceMonitorPrivate
......@@ -63,6 +72,17 @@ NetworkInterfaceMonitor::NetworkInterfaceMonitor(ConnectionList * connectionList
foreach (Solid::Control::NetworkInterface * iface, Solid::Control::NetworkManager::networkInterfaces()) {
networkInterfaceAdded(iface->uni());
}
#ifdef COMPILE_MODEM_MANAGER_SUPPORT
dialog = 0;
QObject::connect(Solid::Control::ModemManager::notifier(),
SIGNAL(modemInterfaceAdded(const QString&)),
this, SLOT(modemInterfaceAdded(const QString&)));
foreach (Solid::Control::ModemInterface * iface, Solid::Control::ModemManager::modemInterfaces()) {
modemInterfaceAdded(iface->udi());
}
#endif
}
NetworkInterfaceMonitor::~NetworkInterfaceMonitor()
......@@ -88,7 +108,7 @@ void NetworkInterfaceMonitor::networkInterfaceAdded(const QString & uni)
} else if (iface->type() == Solid::Control::NetworkInterface::Bluetooth) {
kDebug() << "Bluetooth interface added";
provider = new GsmNetworkInterfaceActivatableProvider(d->connectionList, d->activatableList, qobject_cast<Solid::Control::GsmNetworkInterface*>(iface), this);
#endif
#endif
} else if (iface->type() == Solid::Control::NetworkInterface::Gsm) {
kDebug() << "Gsm interface added";
provider = new GsmNetworkInterfaceActivatableProvider(d->connectionList, d->activatableList, qobject_cast<Solid::Control::GsmNetworkInterface*>(iface), this);
......@@ -133,4 +153,80 @@ void NetworkInterfaceMonitor::networkInterfaceRemoved(const QString & uni)
delete provider;
}
#ifdef COMPILE_MODEM_MANAGER_SUPPORT
void NetworkInterfaceMonitor::modemInterfaceAdded(const QString & udi)
{
Solid::Control::ModemGsmCardInterface * modem = qobject_cast<Solid::Control::ModemGsmCardInterface *>(Solid::Control::ModemManager::findModemInterface(udi, Solid::Control::ModemInterface::GsmCard));
if (!modem) {
return;
}
connect(modem, SIGNAL(unlockRequiredChanged(const QString &)), SLOT(requestPin(const QString &)));
if (dialog || modem->unlockRequired().isEmpty()) {
return;
}
// Using queued invokation to prevent kded stalling here until user enter the pin.
QMetaObject::invokeMethod(modem, "unlockRequiredChanged", Qt::QueuedConnection,
Q_ARG(QString, modem->unlockRequired()));
}
void NetworkInterfaceMonitor::requestPin(const QString & unlockRequired)
{
kDebug() << "unlockRequired == " << unlockRequired;
if (unlockRequired.isEmpty() || unlockRequired == QLatin1String("sim-puk2") ||
unlockRequired == QLatin1String("sim-pin2")) {
return;
}
Solid::Control::ModemGsmCardInterface * modem = qobject_cast<Solid::Control::ModemGsmCardInterface *>(sender());
if (!modem) {
return;
}
// PinDialog already running.
if (dialog) {
kDebug() << "PinDialog already running";
return;
}
if (unlockRequired == QLatin1String("sin-pin")) {
dialog = new PinDialog(PinDialog::Pin);
} else if (unlockRequired == QLatin1String("sin-puk")) {
dialog = new PinDialog(PinDialog::PinPuk);
} else {
kWarning() << "Unhandled unlock request for '" << unlockRequired << "'";
return;
}
if (dialog->exec() != QDialog::Accepted) {
goto OUT;
}
{
// See /usr/share/polkit-1/actions/org.freedesktop.modem-manager.policy
// KAuth is the KDE's Polkit wrapper.
KAuth::Action action(QLatin1String("org.freedesktop.ModemManager.Device.Control"));
KAuth::ActionReply reply = action.execute(QLatin1String("org.freedesktop.ModemManager.Device"));
if (reply.failed()) {
KMessageBox::error(0, i18n("Unlock failed. Error code is %1/%2 (%3).").arg(QString::number(reply.type()), QString::number(reply.errorCode()), reply.errorDescription()), i18n("Error"));
goto OUT;
}
}
kDebug() << "Sending unlock code";
if (dialog->type() == PinDialog::Pin) {
modem->sendPin(dialog->pin());
} else if (dialog->type() == PinDialog::PinPuk) {
modem->sendPuk(dialog->puk(), dialog->pin());
}
OUT:
delete dialog;
dialog = 0;
}
#endif
// vim: sw=4 sts=4 et tw=100
......@@ -29,6 +29,10 @@ class ConnectionList;
class ActivatableList;
class NetworkInterfaceMonitorPrivate;
#ifdef COMPILE_MODEM_MANAGER_SUPPORT
class PinDialog;
#endif
/**
* Monitors network hardware and maintains NetworkInterfaceActivatableProviders for them
*/
......@@ -42,8 +46,15 @@ public:
public Q_SLOTS:
void networkInterfaceAdded(const QString &);
void networkInterfaceRemoved(const QString &);
#ifdef COMPILE_MODEM_MANAGER_SUPPORT
void modemInterfaceAdded(const QString&);
void requestPin(const QString &);
#endif
private:
NetworkInterfaceMonitorPrivate * d_ptr;
#ifdef COMPILE_MODEM_MANAGER_SUPPORT
PinDialog * dialog;
#endif
};
#endif // NETWORKINTERFACEMONITOR_H
/*
Copyright 2011 Lamarque Souza <lamarque@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef COMPILE_MODEM_MANAGER_SUPPORT
#include "pindialog.h"
#include "ui_pinwidget.h"
#include <QVBoxLayout>
#include <KDebug>
#include <kwindowsystem.h>
PinDialog::PinDialog(const Type type, QWidget *parent)
: KDialog(parent), m_type(type)
{
QWidget *w = new QWidget();
ui = new Ui::PinWidget();
ui->setupUi(w);
ui->pin->setEchoMode(QLineEdit::Password);
ui->errorMessage->setHidden(true);
QRect desktop = KGlobalSettings::desktopGeometry(topLevelWidget());
setMinimumWidth(qMin(1000, qMax(sizeHint().width(), desktop.width() / 4)));
pixmapLabel = new QLabel( mainWidget() );
pixmapLabel->setAlignment( Qt::AlignLeft | Qt::AlignTop );
ui->gridLayout->addWidget( pixmapLabel, 0, 0 );
pixmapLabel->setPixmap( KIcon("dialog-password").pixmap(KIconLoader::SizeHuge) );
setButtons( KDialog::Ok | KDialog::Cancel);
setDefaultButton( KDialog::Ok );
button(KDialog::Ok)->setText(i18nc("As in 'Unlock cell phone with this pin code'", "Unlock"));
setMainWidget(w);
if (m_type == PinPuk) {
setWindowTitle(i18n("SIM PIN unlock required"));
ui->title->setText(i18n("SIM PIN Unlock Required"));
ui->prompt->setText(i18n("The mobile broadband device '%s' requires a SIM PIN PUK code before it can be used."));
ui->pukLabel->setText(i18n("PUK code:"));
ui->pinLabel->setText(i18n("New PIN code:"));
ui->pin2Label->setText(i18n("Re-enter new PIN code:"));
ui->chkShowPass->setText(i18n("Show PIN/PUK code"));
ui->puk->setFocus();
ui->pukLabel->show();
ui->pin2Label->show();
} else {
setWindowTitle(i18n("SIM PIN unlock required"));
ui->title->setText(i18n("SIM PIN Unlock Required"));
ui->prompt->setText(i18n("The mobile broadband device '%s' requires a SIM PIN code before it can be used."));
ui->pinLabel->setText(i18n("PIN code:"));
ui->chkShowPass->setText(i18n("Show PIN code"));
ui->pin->setFocus();
ui->pukLabel->hide();
ui->pin2Label->hide();
}
KWindowSystem::setState( winId(), NET::KeepAbove );
KWindowSystem::setOnAllDesktops( winId(), true );
KWindowSystem::activateWindow( winId());
move((desktop.width() - width()) / 2, (desktop.height() - height()) / 2);
connect(ui->chkShowPass, SIGNAL(stateChanged(int)), this, SLOT(chkShowPassToggled()));
}
PinDialog::~PinDialog()
{
}
void PinDialog::chkShowPassToggled()
{
bool on = ui->chkShowPass->isChecked();
ui->pin->setEchoMode(on ? QLineEdit::Normal : QLineEdit::Password);
ui->pin2->setEchoMode(on ? QLineEdit::Normal : QLineEdit::Password);
ui->puk->setEchoMode(on ? QLineEdit::Normal : QLineEdit::Password);
}
PinDialog::Type PinDialog::type() const
{
return m_type;
}
QString PinDialog::pin() const
{
return ui->pin->text();
}
QString PinDialog::puk() const
{
return ui->puk->text();
}
#endif
/*
Copyright 2011 Lamarque Souza <lamarque@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef COMPILE_MODEM_MANAGER_SUPPORT
#ifndef PINDIALOG_H
#define PINDIALOG_H
#include <QWidget>
#include "ui_pinwidget.h"
#include <KDialog>
#include <KLocale>
#include <KPushButton>
class PinWidget;
class PinDialog : public KDialog
{
Q_OBJECT
public:
enum Type {Pin, PinPuk};
PinDialog(const Type type = Pin, QWidget *parent=0);
~PinDialog();
Type type() const;
QString pin() const;
QString puk() const;
protected Q_SLOTS:
void chkShowPassToggled();
protected:
Ui::PinWidget * ui;
QLabel* pixmapLabel;
private:
Type m_type;
};
#endif
#endif
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PinWidget</class>
<widget class="QWidget" name="PinWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>218</height>
</rect>
</property>
<property name="windowTitle">
<string>SIM PIN unlock required</string>
</property>
<layout class="QVBoxLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="QLabel" name="title">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>10</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>SIM PIN unlock required</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter|Qt::AlignHCenter|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="prompt">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>10</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>The mobile broadband device '%s' requires a SIM PIN code before it can be used.</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>400</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="KTitleWidget" name="errorMessage"/>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="pukLabel">
<property name="text">
<string>PUK code:</string>
</property>
<property name="buddy">
<cstring>puk</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KLineEdit" name="puk">
<property name="inputMask">
<string>99999999; </string>
</property>
<property name="passwordMode">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="pinLabel">
<property name="text">
<string>New PIN code:</string>
</property>
<property name="buddy">
<cstring>pin</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KLineEdit" name="pin">
<property name="inputMask">
<string>99990000; </string>
</property>
<property name="passwordMode">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="pin2Label">
<property name="text">
<string>Re-enter PIN code:</string>
</property>
<property name="buddy">
<cstring>pin2</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="KLineEdit" name="pin2">
<property name="inputMask">
<string>99990000; </string>
</property>
<property name="passwordMode">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="chkShowPass">
<property name="text">
<string>Show PIN/PUK code</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KTitleWidget</class>
<extends>QWidget</extends>
<header>ktitlewidget.h</header>
</customwidget>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>pin</tabstop>
<tabstop>chkShowPass</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment