Skip to content

Commit

Permalink
Add oFono based cellular network information classes
Browse files Browse the repository at this point in the history
The classes provide the functionality that the closed source
Harmattan CellularQt used to provide.

These classes do not contain any code from CellularQt, only the
interface has been partially replicated based on docs from
http://harmattan-dev.nokia.com/docs/platform-api-reference/xml/daily-docs/libcellular-qt/
  • Loading branch information
Petri M. Gerdt committed Jan 21, 2013
1 parent b52736e commit 5a6cf73
Show file tree
Hide file tree
Showing 14 changed files with 892 additions and 0 deletions.
83 changes: 83 additions & 0 deletions src/server/modemwatcher.cpp
@@ -0,0 +1,83 @@
#include <QDBusInterface>
#include <QDBusReply>

#include <qmlog>

#include "modemwatcher.h"

ModemWatcher::ModemWatcher(const QString objectPath, const QString interface, QObject *parent) :
QObject(parent), m_objectPath(objectPath), m_interface(interface)
{
QDBusConnection::systemBus().connect("org.ofono", m_objectPath,

This comment has been minimized.

Copy link
@saukko

saukko Jan 21, 2013

"org.ofono" <- maybe defines for these constant strings?

"org.ofono.Modem", "PropertyChanged",
this, SLOT(onModemPropertyChanged(QString, QDBusVariant)));

QDBusMessage request = QDBusMessage::createMethodCall("org.ofono", m_objectPath,
"org.ofono.Modem",
"GetProperties");

QDBusReply<QVariantMap> reply = QDBusConnection::systemBus().call(request);
if (reply.error().isValid()) {
log_error("DBus call to interface %s function GetProperties of path %s failed: %s",
m_interface.toStdString().c_str(),
m_objectPath.toStdString().c_str(),
reply.error().message().toStdString().c_str());
} else {
QVariantMap properties = reply;
checkInterfaceAvailability(properties.value("Interfaces"));
}
}

ModemWatcher::~ModemWatcher()
{
QDBusConnection::systemBus().disconnect("org.ofono", m_objectPath,
"org.ofono.Modem", "PropertyChanged",
this, SLOT(onModemPropertyChanged(QString, QDBusVariant)));
}

bool ModemWatcher::interfaceAvailable() const
{
return m_interfaceAvailable;
}

QString ModemWatcher::objectPath() const
{
return m_objectPath;
}

QString ModemWatcher::interface() const
{
return m_interface;
}

// Checks if the interface stored in m_interface is present in
// list of interfaces stored in parameter variant.
// Changes m_interfaceAvailable to reflect interface presence in
// the list: true indicates that the interface is in the list, false
// indicates that it is not. If m_interfaceAvailable was changed,
// then returns true, otherwise returns false.
bool ModemWatcher::checkInterfaceAvailability(QVariant variant)
{
if (variant.type() == QVariant::StringList) {
QStringList list = variant.toStringList();
bool available = list.contains(m_interface);
if (available != m_interfaceAvailable) {
m_interfaceAvailable = available;
return true;
}
}

return false;
}

void ModemWatcher::onModemPropertyChanged(QString name, QDBusVariant value)
{
if (name.compare("Interfaces") == 0) {
if (checkInterfaceAvailability(value.variant())) {
log_debug("interface %s availability changed: %s",
m_interface.toStdString().c_str(),
m_interfaceAvailable ? "available" : "not available");
emit interfaceAvailableChanged(m_interfaceAvailable);
}
}
}
34 changes: 34 additions & 0 deletions src/server/modemwatcher.h
@@ -0,0 +1,34 @@
#ifndef MODEMWATCHER_H
#define MODEMWATCHER_H

#include <QObject>
#include <QVariant>
#include <QDBusVariant>

class QDBusInterface;
class QDBusPendingCallWatcher;

class ModemWatcher : public QObject
{
Q_OBJECT

public:
explicit ModemWatcher(const QString objectPath, const QString interface, QObject *parent = 0);
~ModemWatcher();
bool interfaceAvailable() const;
QString objectPath() const;
QString interface() const;

signals:
void interfaceAvailableChanged(bool available);

private:
QString m_objectPath;
QString m_interface;
bool m_interfaceAvailable;
bool checkInterfaceAvailability(QVariant variant);

private slots:
void onModemPropertyChanged(QString objectPath, QDBusVariant value);
};
#endif // MODEMWATCHER_H
88 changes: 88 additions & 0 deletions src/server/networkoperator.cpp
@@ -0,0 +1,88 @@
#include <QStringList>

#include <qmlog>

#include "networkoperator.h"
#include "networkregistrationwatcher.h"

NetworkOperator::NetworkOperator(QObject *parent) :
QObject(parent), m_mccUpdated(false), m_mncUpdated(false)
{
foreach (const QString objectPath, m_modemManager.getModems())
onModemAdded(objectPath);

QObject::connect(&m_modemManager, SIGNAL(modemAdded(QString)),
this, SLOT(onModemAdded(QString)));

QObject::connect(&m_modemManager, SIGNAL(modemRemoved(QString)),
this, SLOT(onModemRemoved(QString)));
}

QString NetworkOperator::mnc() const
{
return m_mnc;
}

QString NetworkOperator::mcc() const
{
return m_mcc;
}

bool NetworkOperator::isValid() const
{
return !(m_mcc.isEmpty() || m_mnc.isEmpty());
}

void NetworkOperator::onModemAdded(QString objectPath)
{
if (!m_watcherMap.contains(objectPath)) {
NetworkRegistrationWatcher *watcher = new NetworkRegistrationWatcher(objectPath, this);
QObject::connect(watcher, SIGNAL(propertyChanged(QString, QString, QVariant)),
this, SLOT(onWatcherPropertyChanged(QString, QString, QVariant)));
watcher->getProperties();
m_watcherMap.insert(objectPath, watcher);
}
}

void NetworkOperator::onModemRemoved(QString objectPath)
{
if (m_watcherMap.contains(objectPath)) {
NetworkRegistrationWatcher *watcher = m_watcherMap.value(objectPath);
m_watcherMap.remove(objectPath);
delete watcher;
}
}

void NetworkOperator::onWatcherPropertyChanged(QString objectPath, QString name, QVariant value)
{
if (m_currentObjectPath.compare(objectPath) != 0
&& (name.compare("MobileCountryCode") == 0 || name.compare("MobileNetworkCode") == 0)) {
m_currentObjectPath = objectPath;
m_mccUpdated = false;
m_mncUpdated = false;
m_mnc = "";
m_mcc = "";
}

if (name.compare("MobileCountryCode") == 0) {
if (value.type() == QVariant::String) {
m_mcc = value.toString();
m_mccUpdated = true;
}
} else if (name.compare("MobileNetworkCode") == 0) {
if (value.type() == QVariant::String) {
m_mnc = value.toString();
m_mncUpdated = true;
}
}

if (m_mccUpdated && m_mncUpdated) {
m_mccUpdated = false;
m_mncUpdated = false;
log_debug("operator changed: MNC: %s, MCC: %s, modem: %s",
m_mnc.toStdString().c_str(),
m_mcc.toStdString().c_str(),
objectPath.toStdString().c_str());
emit operatorChanged(m_mnc, m_mcc);
}
}
42 changes: 42 additions & 0 deletions src/server/networkoperator.h
@@ -0,0 +1,42 @@
#ifndef NETWORKOPERATOR_H
#define NETWORKOPERATOR_H

#include <QObject>
#include <QMap>
#include <QVariant>

#include "ofonomodemmanager.h"

class NetworkRegistrationWatcher;

// See http://harmattan-dev.nokia.com/docs/platform-api-reference/xml/daily-docs/libcellular-qt/classCellular_1_1NetworkOperator.html
class NetworkOperator : public QObject
{
Q_OBJECT

public:
explicit NetworkOperator(QObject *parent = 0);
QString mnc() const;
QString mcc() const;
bool isValid() const;

signals:
void operatorChanged(const QString &mnc, const QString &mcc);

private:
QString m_mnc;
QString m_mcc;
bool m_mccUpdated;
bool m_mncUpdated;
bool m_valid;
QString m_currentObjectPath;
OfonoModemManager m_modemManager;
QMap<QString, NetworkRegistrationWatcher*> m_watcherMap;

private slots:
void onModemAdded(QString objectPath);
void onModemRemoved(QString objectPath);
void onWatcherPropertyChanged(QString objectPath, QString name, QVariant value);
};

#endif // NETWORKOPERATOR_H
85 changes: 85 additions & 0 deletions src/server/networkregistrationwatcher.cpp
@@ -0,0 +1,85 @@
#include <QDBusInterface>
#include <QDBusPendingCallWatcher>
#include <QDBusReply>
#include <QDBusPendingReply>

#include <qmlog>

#include "networkregistrationwatcher.h"

NetworkRegistrationWatcher::NetworkRegistrationWatcher(const QString path, QObject *parent) :
ModemWatcher(path, "org.ofono.NetworkRegistration", parent)
{
QDBusConnection::systemBus().connect("org.ofono", objectPath(),
interface(), "PropertyChanged",
this, SLOT(onPropertyChanged(QString, QDBusVariant)));

QObject::connect(this, SIGNAL(interfaceAvailableChanged(bool)),
this, SLOT(getPropertiesAsync()));
}

NetworkRegistrationWatcher::~NetworkRegistrationWatcher()
{
QDBusConnection::systemBus().disconnect("org.ofono", objectPath(),
interface(), "PropertyChanged",
this, SLOT(onPropertyChanged(QString, QDBusVariant)));
}

void NetworkRegistrationWatcher::getProperties()
{
if (!interfaceAvailable())
return;

QDBusMessage request = QDBusMessage::createMethodCall("org.ofono", objectPath(), interface(),
"GetProperties");
QDBusReply<QVariantMap> reply = QDBusConnection::systemBus().call(request);
if (reply.error().isValid()) {
log_error("DBus call to interface %s function GetProperties of path %s failed: %s",
interface().toStdString().c_str(),
objectPath().toStdString().c_str(),
reply.error().message().toStdString().c_str());
return;
}

QVariantMap map = reply.value();
foreach (const QString &key, map.keys())
emit propertyChanged(objectPath(), key, map.value(key));
}

void NetworkRegistrationWatcher::getPropertiesAsync()
{
if (!interfaceAvailable())
return;

QDBusInterface dbusInterface("org.ofono", objectPath(), interface(), QDBusConnection::systemBus());
if (dbusInterface.isValid()) {
QDBusPendingCall async = dbusInterface.asyncCall("GetProperties");
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
this, SLOT(getPropertiesAsyncCallback(QDBusPendingCallWatcher*)));
} else {
log_error("Dbus interface %s of path %s is invalid.",
interface().toStdString().c_str(),
objectPath().toStdString().c_str());
}
}

void NetworkRegistrationWatcher::getPropertiesAsyncCallback(QDBusPendingCallWatcher *watcher)
{
QDBusPendingReply<QVariantMap> reply = *watcher;
if (reply.error().isValid()) {
log_error("DBus call to interface %s function GetProperties of path %s failed: %s",
interface().toStdString().c_str(),
objectPath().toStdString().c_str(),
reply.error().message().toStdString().c_str());
} else {
QVariantMap map = reply.argumentAt<0>();
foreach (const QString &key, map.keys())
emit propertyChanged(objectPath(), key, map.value(key));
}
}

void NetworkRegistrationWatcher::onPropertyChanged(QString name, QDBusVariant value)
{
emit propertyChanged(objectPath(), name, value.variant());
}
30 changes: 30 additions & 0 deletions src/server/networkregistrationwatcher.h
@@ -0,0 +1,30 @@
#ifndef NETWORKREGISTRATIONRWATCHER_H
#define NETWORKREGISTRATIONRWATCHER_H

#include <QObject>
#include <QVariantMap>
#include <QDBusVariant>

#include "modemwatcher.h"

class QDBusInterface;
class QDBusPendingCallWatcher;

class NetworkRegistrationWatcher : public ModemWatcher
{
Q_OBJECT
public:
explicit NetworkRegistrationWatcher(const QString objectPath, QObject *parent = 0);
~NetworkRegistrationWatcher();

void getProperties();

signals:
void propertyChanged(QString objectPath, QString name, QVariant value);

private slots:
void onPropertyChanged(QString name, QDBusVariant value);
void getPropertiesAsync();
void getPropertiesAsyncCallback(QDBusPendingCallWatcher *watcher);
};
#endif // NETWORKREGISTRATIONRWATCHER_H

0 comments on commit 5a6cf73

Please sign in to comment.