Skip to content

Commit

Permalink
Merge branch 'jb45378' into 'master'
Browse files Browse the repository at this point in the history
Add API for accessing connman VPNs

See merge request mer-core/libconnman-qt!36
  • Loading branch information
llewelld committed Oct 9, 2019
2 parents 7a0002f + b2a883e commit 21bfdf2
Show file tree
Hide file tree
Showing 18 changed files with 1,939 additions and 10 deletions.
18 changes: 18 additions & 0 deletions libconnman-qt/connman_service.xml
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="net.connman.Service">
<method name="GetProperties">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
<arg name="properties" type="a{sv}" direction="out"/>
</method>
<method name="SetProperty">
<arg name="name" type="s" direction="in"/>
<arg name="value" type="v" direction="in"/>
</method>
<signal name="PropertyChanged">
<arg name="name" type="s"/>
<arg name="value" type="v"/>
</signal>
</interface>
</node>
26 changes: 26 additions & 0 deletions libconnman-qt/connman_vpn_connection.xml
@@ -0,0 +1,26 @@
<?xml version="1.0"?>
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="net.connman.vpn.Connection">
<method name="GetProperties">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
<arg name="properties" type="a{sv}" direction="out"/>
</method>
<method name="SetProperty">
<arg name="name" type="s" direction="in"/>
<arg name="value" type="v" direction="in"/>
</method>
<method name="ClearProperty">
<arg name="name" type="s" direction="in"/>
</method>
<method name="Connect"/>
<method name="Connect2">
<arg name="dbus_sender" type="s" direction="in"/>
</method>
<method name="Disconnect"/>
<signal name="PropertyChanged">
<arg name="name" type="s"/>
<arg name="value" type="v"/>
</signal>
</interface>
</node>
32 changes: 32 additions & 0 deletions libconnman-qt/connman_vpn_manager.xml
@@ -0,0 +1,32 @@
<?xml version="1.0"?>
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="net.connman.vpn.Manager">
<method name="Create">
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
<arg name="properties" type="a{sv}" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="Remove">
<arg name="identifier" type="o" direction="in"/>
</method>
<method name="GetConnections">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="PathPropertiesArray"/>
<arg name="connections" type="a(oa{sv})" direction="out"/>
</method>
<method name="RegisterAgent">
<arg name="path" type="o" direction="in"/>
</method>
<method name="UnregisterAgent">
<arg name="path" type="o" direction="in"/>
</method>
<signal name="ConnectionAdded">
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
<arg name="identifier" type="o"/>
<arg name="properties" type="a{sv}"/>
</signal>
<signal name="ConnectionRemoved">
<arg name="identifier" type="o"/>
</signal>
</interface>
</node>
34 changes: 26 additions & 8 deletions libconnman-qt/libconnman-qt.pro
Expand Up @@ -4,7 +4,7 @@ QT -= gui
CONFIG += qt create_pc create_prl link_pkgconfig

isEmpty(VERSION) {
VERSION = 1.2.20
VERSION = 1.2.21
message("VERSION is unset, assuming $$VERSION")
}

Expand Down Expand Up @@ -38,10 +38,17 @@ CONFIG(debug, debug|release) {
TARGET = $$qtLibraryTarget(connman-$$TARGET_SUFFIX)
headers.path = $$INSTALL_ROOT$$PREFIX/include/connman-$$TARGET_SUFFIX

custom_dbus_interface.files = \
connman_service.xml \
connman_vpn_manager.xml \
connman_vpn_connection.xml
custom_dbus_interface.header_flags = -i qdbusxml2cpp_dbus_types.h

DBUS_INTERFACES = \
connman_clock.xml \
connman_session.xml \
connman_technology.xml \
custom_dbus_interface

PUBLIC_HEADERS += \
networkmanager.h \
Expand All @@ -53,13 +60,24 @@ PUBLIC_HEADERS += \
useragent.h \
sessionagent.h \
networksession.h \
counter.h
counter.h \
vpnconnection.h \
vpnconnection_p.h \
vpnmanager.h \
vpnmanager_p.h \
vpnmodel.h \
vpnmodel_p.h

HEADERS += \
$$PUBLIC_HEADERS \
libconnman_p.h \
marshalutils.h \
qdbusxml2cpp_dbus_types.h \
connman_vpn_manager_interface.h \
connman_vpn_connection_interface.h

SOURCES += \
marshalutils.cpp \
networkmanager.cpp \
networktechnology.cpp \
networkservice.cpp \
Expand All @@ -69,7 +87,10 @@ SOURCES += \
useragent.cpp \
sessionagent.cpp \
networksession.cpp \
counter.cpp
counter.cpp \
vpnconnection.cpp \
vpnmanager.cpp \
vpnmodel.cpp

target.path = $$INSTALL_ROOT$$PREFIX/lib

Expand All @@ -81,8 +102,5 @@ QMAKE_PKGCONFIG_INCDIR = $$headers.path

INSTALLS += target headers

OTHER_FILES = connman_service.xml \
connman_technology.xml \
connman_clock.xml \
connman_session.xml \
connman_notification.xml
OTHER_FILES = connman_notification.xml \
DBUS_INTERFACES
175 changes: 175 additions & 0 deletions libconnman-qt/marshalutils.cpp
@@ -0,0 +1,175 @@
/*
* Copyright (c) 2016 - 2019 Jolla Ltd.
* Copyright (c) 2019 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
* "Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Nemo Mobile nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
*/

#include <QDebug>
#include "vpnconnection.h"

#include "marshalutils.h"

template<typename T>
inline QVariant extract(const QDBusArgument &arg)
{
T rv;
arg >> rv;
return QVariant::fromValue(rv);
}

template<typename T>
inline QVariant extractArray(const QDBusArgument &arg)
{
QVariantList rv;

arg.beginArray();
while (!arg.atEnd()) {
rv.append(extract<T>(arg));
}
arg.endArray();

return QVariant::fromValue(rv);
}

QVariantMap MarshalUtils::propertiesToQml(const QVariantMap &fromDBus)
{
QVariantMap rv;

QVariantMap providerProperties;

for (QVariantMap::const_iterator it = fromDBus.cbegin(), end = fromDBus.cend(); it != end; ++it) {
QString key(it.key());
QVariant value(it.value());

if (key.indexOf(QChar('.')) != -1) {
providerProperties.insert(key, value);
continue;
}

// QML properties must be lowercased
QChar &initial(*key.begin());
initial = initial.toLower();

// Some properties must be extracted manually
if (key == QStringLiteral("iPv4") ||
key == QStringLiteral("iPv6")) {
// iPv4 becomes ipv4 and iPv6 becomes ipv6
key = key.toLower();
value = extract<QVariantMap>(value.value<QDBusArgument>());
} else if (key == QStringLiteral("serverRoutes") ||
key == QStringLiteral("userRoutes")) {
value = extractArray<QVariantMap>(value.value<QDBusArgument>());
}

rv.insert(key, convertToQml(key, value));
}

if (!providerProperties.isEmpty()) {
rv.insert(QStringLiteral("providerProperties"), QVariant::fromValue(providerProperties));
}

return rv;
}

// Conversion to/from DBus/QML
QHash<QString, QList<QPair<QVariant, QVariant> > > MarshalUtils::propertyConversions()
{
QHash<QString, QList<QPair<QVariant, QVariant> > > rv;

QList<QPair<QVariant, QVariant> > states;
states.push_back(qMakePair(QVariant::fromValue(QString("idle")), QVariant::fromValue(static_cast<int>(VpnConnection::Idle))));
states.push_back(qMakePair(QVariant::fromValue(QString("failure")), QVariant::fromValue(static_cast<int>(VpnConnection::Failure))));
states.push_back(qMakePair(QVariant::fromValue(QString("configuration")), QVariant::fromValue(static_cast<int>(VpnConnection::Configuration))));
states.push_back(qMakePair(QVariant::fromValue(QString("ready")), QVariant::fromValue(static_cast<int>(VpnConnection::Ready))));
states.push_back(qMakePair(QVariant::fromValue(QString("disconnect")), QVariant::fromValue(static_cast<int>(VpnConnection::Disconnect))));
rv.insert(QString("state"), states);

return rv;
}

QVariant MarshalUtils::convertValue(const QString &key, const QVariant &value, bool toDBus)
{
static const QHash<QString, QList<QPair<QVariant, QVariant> > > conversions(propertyConversions());

auto it = conversions.find(key.toLower());
if (it != conversions.end()) {
const QList<QPair<QVariant, QVariant> > &list(it.value());
auto lit = std::find_if(list.cbegin(), list.cend(), [value, toDBus](const QPair<QVariant, QVariant> &pair) { return value == (toDBus ? pair.second : pair.first); });
if (lit != list.end()) {
return toDBus ? (*lit).first : (*lit).second;
} else {
qDebug() << "No conversion found for" << (toDBus ? "QML" : "DBus") << "value:" << value << key;
}
}

return value;
}

QVariant MarshalUtils::convertToQml(const QString &key, const QVariant &value)
{
return convertValue(key, value, false);
}

QVariant MarshalUtils::convertToDBus(const QString &key, const QVariant &value)
{
return convertValue(key, value, true);
}

QVariantMap MarshalUtils::propertiesToDBus(const QVariantMap &fromQml)
{
QVariantMap rv;

for (QVariantMap::const_iterator it = fromQml.cbegin(), end = fromQml.cend(); it != end; ++it) {
QString key(it.key());
QVariant value(it.value());

if (key == QStringLiteral("providerProperties")) {
const QVariantMap providerProperties(value.value<QVariantMap>());
for (QVariantMap::const_iterator pit = providerProperties.cbegin(), pend = providerProperties.cend(); pit != pend; ++pit) {
rv.insert(pit.key(), pit.value());
}
continue;
}

// The DBus properties are capitalized
QChar &initial(*key.begin());
initial = initial.toUpper();

if (key == QStringLiteral("Ipv4") ||
key == QStringLiteral("Ipv6")) {
// Ipv4 becomes IPv4 and Ipv6 becomes IPv6
key[1] = 'P';
}

rv.insert(key, convertToDBus(key, value));
}

return rv;
}

62 changes: 62 additions & 0 deletions libconnman-qt/marshalutils.h
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2016 - 2019 Jolla Ltd.
* Copyright (c) 2019 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
* "Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Nemo Mobile nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
*/

#ifndef MARSHALUTILS_H
#define MARSHALUTILS_H

#include <QVariant>
#include <QDBusArgument>

namespace MarshalUtils
{
template <typename Argument>
inline Argument demarshallArgument(const QVariant &argument)
{
if (argument.userType() == qMetaTypeId<QDBusArgument>()) {
Argument demarshalled;
argument.value<QDBusArgument>() >> demarshalled;
return demarshalled;
} else {
return argument.value<Argument>();
}

}

QVariantMap propertiesToQml(const QVariantMap &fromDBus);
QHash<QString, QList<QPair<QVariant, QVariant> > > propertyConversions();
QVariant convertValue(const QString &key, const QVariant &value, bool toDBus);
QVariant convertToQml(const QString &key, const QVariant &value);
QVariant convertToDBus(const QString &key, const QVariant &value);
QVariantMap propertiesToDBus(const QVariantMap &fromQml);
}

#endif // MARSHALUTILS_H

0 comments on commit 21bfdf2

Please sign in to comment.