summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/bearer/icd/dbusdispatcher.cpp631
-rw-r--r--src/plugins/bearer/icd/dbusdispatcher.h111
-rw-r--r--src/plugins/bearer/icd/iapconf.cpp245
-rw-r--r--src/plugins/bearer/icd/iapconf.h74
-rw-r--r--src/plugins/bearer/icd/iapmonitor.cpp130
-rw-r--r--src/plugins/bearer/icd/iapmonitor.h68
-rw-r--r--src/plugins/bearer/icd/icd.pro16
-rw-r--r--src/plugins/bearer/icd/maemo_icd.cpp849
-rw-r--r--src/plugins/bearer/icd/maemo_icd.h174
-rw-r--r--src/plugins/bearer/icd/proxyconf.cpp412
-rw-r--r--src/plugins/bearer/icd/proxyconf.h73
-rw-r--r--src/plugins/bearer/icd/qicdengine.cpp14
-rw-r--r--src/plugins/bearer/icd/qicdengine.h2
-rw-r--r--src/plugins/bearer/icd/qnetworksession_impl.cpp12
-rw-r--r--src/plugins/bearer/icd/wlan-utils.h110
15 files changed, 2915 insertions, 6 deletions
diff --git a/src/plugins/bearer/icd/dbusdispatcher.cpp b/src/plugins/bearer/icd/dbusdispatcher.cpp
new file mode 100644
index 0000000..3d588dc
--- /dev/null
+++ b/src/plugins/bearer/icd/dbusdispatcher.cpp
@@ -0,0 +1,631 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QDebug>
+#include <QtCore>
+#include <poll.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <glib.h>
+#include "dbusdispatcher.h"
+
+namespace Maemo {
+
+/*!
+ \class DBusDispatcher
+
+ \brief DBusDispatcher is a class, which is able to send DBUS method call
+ messages and receive unicast signals from DBUS object.
+*/
+
+class DBusDispatcherPrivate
+{
+public:
+ DBusDispatcherPrivate(const QString& service,
+ const QString& path,
+ const QString& interface,
+ const QString& signalPath)
+ : service(service), path(path), interface(interface),
+ signalPath(signalPath), connection(0)
+ {
+ memset(&signal_vtable, 0, sizeof(signal_vtable));
+ }
+
+ ~DBusDispatcherPrivate()
+ {
+ foreach(DBusPendingCall *call, pending_calls) {
+ dbus_pending_call_cancel(call);
+ dbus_pending_call_unref(call);
+ }
+ }
+
+ QString service;
+ QString path;
+ QString interface;
+ QString signalPath;
+ struct DBusConnection *connection;
+ QList<DBusPendingCall *> pending_calls;
+ struct DBusObjectPathVTable signal_vtable;
+};
+
+static bool constantVariantList(const QVariantList& variantList) {
+ // Special case, empty list == empty struct
+ if (variantList.isEmpty()) {
+ return false;
+ } else {
+ QVariant::Type type = variantList[0].type();
+ // Iterate items in the list and check if they are same type
+ foreach(QVariant variant, variantList) {
+ if (variant.type() != type) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static QString variantToSignature(const QVariant& argument,
+ bool constantList = true) {
+ switch (argument.type()) {
+ case QVariant::Bool:
+ return "b";
+ case QVariant::ByteArray:
+ return "ay";
+ case QVariant::Char:
+ return "y";
+ case QVariant::Int:
+ return "i";
+ case QVariant::UInt:
+ return "u";
+ case QVariant::StringList:
+ return "as";
+ case QVariant::String:
+ return "s";
+ case QVariant::LongLong:
+ return "x";
+ case QVariant::ULongLong:
+ return "t";
+ case QVariant::List:
+ {
+ QString signature;
+ QVariantList variantList = argument.toList();
+ if (!constantList) {
+ signature += DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
+ foreach(QVariant listItem, variantList) {
+ signature += variantToSignature(listItem);
+ }
+ signature += DBUS_STRUCT_END_CHAR_AS_STRING;
+ } else {
+ if (variantList.isEmpty())
+ return "";
+ signature = "a" + variantToSignature(variantList[0]);
+ }
+
+ return signature;
+ }
+ default:
+ qDebug() << "Unsupported variant type: " << argument.type();
+ break;
+ }
+
+ return "";
+}
+
+static bool appendVariantToDBusMessage(const QVariant& argument,
+ DBusMessageIter *dbus_iter) {
+ int idx = 0;
+ DBusMessageIter array_iter;
+ QStringList str_list;
+ dbus_bool_t bool_data;
+ dbus_int32_t int32_data;
+ dbus_uint32_t uint32_data;
+ dbus_int64_t int64_data;
+ dbus_uint64_t uint64_data;
+ char *str_data;
+ char char_data;
+
+ switch (argument.type()) {
+
+ case QVariant::Bool:
+ bool_data = argument.toBool();
+ dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_BOOLEAN,
+ &bool_data);
+ break;
+
+ case QVariant::ByteArray:
+ str_data = argument.toByteArray().data();
+ dbus_message_iter_open_container(dbus_iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_BYTE_AS_STRING, &array_iter);
+ dbus_message_iter_append_fixed_array(&array_iter,
+ DBUS_TYPE_BYTE,
+ &str_data,
+ argument.toByteArray().size());
+ dbus_message_iter_close_container(dbus_iter, &array_iter);
+ break;
+
+ case QVariant::Char:
+ char_data = argument.toChar().toAscii();
+ dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_BYTE,
+ &char_data);
+ break;
+
+ case QVariant::Int:
+ int32_data = argument.toInt();
+ dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_INT32,
+ &int32_data);
+ break;
+
+ case QVariant::String:
+ str_data = argument.toString().toLatin1().data();
+ dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_STRING,
+ &str_data);
+ break;
+
+ case QVariant::StringList:
+ str_list = argument.toStringList();
+ dbus_message_iter_open_container(dbus_iter, DBUS_TYPE_ARRAY,
+ "s", &array_iter);
+ for (idx = 0; idx < str_list.size(); idx++) {
+ str_data = str_list.at(idx).toLatin1().data();
+ dbus_message_iter_append_basic(&array_iter,
+ DBUS_TYPE_STRING,
+ &str_data);
+ }
+ dbus_message_iter_close_container(dbus_iter, &array_iter);
+ break;
+
+ case QVariant::UInt:
+ uint32_data = argument.toUInt();
+ dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_UINT32,
+ &uint32_data);
+ break;
+
+ case QVariant::ULongLong:
+ uint64_data = argument.toULongLong();
+ dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_UINT64,
+ &uint64_data);
+ break;
+
+ case QVariant::LongLong:
+ int64_data = argument.toLongLong();
+ dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_INT64,
+ &int64_data);
+ break;
+
+ case QVariant::List:
+ {
+ QVariantList variantList = argument.toList();
+ bool constantList = constantVariantList(variantList);
+ DBusMessageIter array_iter;
+
+ // List is mapped either as an DBUS array (all items same type)
+ // DBUS struct (variable types) depending on constantList
+ if (constantList) {
+ // Resolve the signature for the first item
+ QString signature = "";
+ if (!variantList.isEmpty()) {
+ signature = variantToSignature(
+ variantList[0],
+ constantVariantList(variantList[0].toList()));
+ }
+
+ // Mapped as DBUS array
+ dbus_message_iter_open_container(dbus_iter, DBUS_TYPE_ARRAY,
+ signature.toAscii(),
+ &array_iter);
+
+ foreach(QVariant listItem, variantList) {
+ appendVariantToDBusMessage(listItem, &array_iter);
+ }
+
+ dbus_message_iter_close_container(dbus_iter, &array_iter);
+ } else {
+ // Mapped as DBUS struct
+ dbus_message_iter_open_container(dbus_iter, DBUS_TYPE_STRUCT,
+ NULL,
+ &array_iter);
+
+ foreach(QVariant listItem, variantList) {
+ appendVariantToDBusMessage(listItem, &array_iter);
+ }
+
+ dbus_message_iter_close_container(dbus_iter, &array_iter);
+ }
+
+ break;
+ }
+ default:
+ qDebug() << "Unsupported variant type: " << argument.type();
+ break;
+ }
+
+ return true;
+}
+
+static QVariant getVariantFromDBusMessage(DBusMessageIter *iter) {
+ dbus_bool_t bool_data;
+ dbus_int32_t int32_data;
+ dbus_uint32_t uint32_data;
+ dbus_int64_t int64_data;
+ dbus_uint64_t uint64_data;
+ char *str_data;
+ char char_data;
+ int argtype = dbus_message_iter_get_arg_type(iter);
+
+ switch (argtype) {
+
+ case DBUS_TYPE_BOOLEAN:
+ {
+ dbus_message_iter_get_basic(iter, &bool_data);
+ QVariant variant((bool)bool_data);
+ return variant;
+ }
+
+ case DBUS_TYPE_ARRAY:
+ {
+ // Handle all arrays here
+ int elem_type = dbus_message_iter_get_element_type(iter);
+ DBusMessageIter array_iter;
+
+ dbus_message_iter_recurse(iter, &array_iter);
+
+ if (elem_type == DBUS_TYPE_BYTE) {
+ QByteArray byte_array;
+ do {
+ dbus_message_iter_get_basic(&array_iter, &char_data);
+ byte_array.append(char_data);
+ } while (dbus_message_iter_next(&array_iter));
+ QVariant variant(byte_array);
+ return variant;
+ } else if (elem_type == DBUS_TYPE_STRING) {
+ QStringList str_list;
+ do {
+ dbus_message_iter_get_basic(&array_iter, &str_data);
+ str_list.append(str_data);
+ } while (dbus_message_iter_next(&array_iter));
+ QVariant variant(str_list);
+ return variant;
+ } else {
+ QVariantList variantList;
+ do {
+ variantList << getVariantFromDBusMessage(&array_iter);
+ } while (dbus_message_iter_next(&array_iter));
+ QVariant variant(variantList);
+ return variant;
+ }
+ break;
+ }
+
+ case DBUS_TYPE_BYTE:
+ {
+ dbus_message_iter_get_basic(iter, &char_data);
+ QChar ch(char_data);
+ QVariant variant(ch);
+ return variant;
+ }
+
+ case DBUS_TYPE_INT32:
+ {
+ dbus_message_iter_get_basic(iter, &int32_data);
+ QVariant variant((int)int32_data);
+ return variant;
+ }
+
+ case DBUS_TYPE_UINT32:
+ {
+ dbus_message_iter_get_basic(iter, &uint32_data);
+ QVariant variant((uint)uint32_data);
+ return variant;
+ }
+
+ case DBUS_TYPE_STRING:
+ {
+ dbus_message_iter_get_basic(iter, &str_data);
+ QString str(str_data);
+ QVariant variant(str);
+ return variant;
+ }
+
+ case DBUS_TYPE_INT64:
+ {
+ dbus_message_iter_get_basic(iter, &int64_data);
+ QVariant variant((qlonglong)int64_data);
+ return variant;
+ }
+
+ case DBUS_TYPE_UINT64:
+ {
+ dbus_message_iter_get_basic(iter, &uint64_data);
+ QVariant variant((qulonglong)uint64_data);
+ return variant;
+ }
+
+ case DBUS_TYPE_STRUCT:
+ {
+ // Handle all structs here
+ DBusMessageIter struct_iter;
+ dbus_message_iter_recurse(iter, &struct_iter);
+
+ QVariantList variantList;
+ do {
+ variantList << getVariantFromDBusMessage(&struct_iter);
+ } while (dbus_message_iter_next(&struct_iter));
+ QVariant variant(variantList);
+ return variant;
+ }
+
+ default:
+ qDebug() << "Unsupported DBUS type: " << argtype;
+ }
+
+ return QVariant();
+}
+
+static DBusHandlerResult signalHandler (DBusConnection *connection,
+ DBusMessage *message,
+ void *object_ref) {
+ (void)connection;
+ QString interface;
+ QString signal;
+ DBusDispatcher *dispatcher = (DBusDispatcher *)object_ref;
+
+ if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) {
+ interface = dbus_message_get_interface(message);
+ signal = dbus_message_get_member(message);
+
+ QList<QVariant> arglist;
+ DBusMessageIter dbus_iter;
+
+ if (dbus_message_iter_init(message, &dbus_iter)) {
+ // Read return arguments
+ while (dbus_message_iter_get_arg_type (&dbus_iter) != DBUS_TYPE_INVALID) {
+ arglist << getVariantFromDBusMessage(&dbus_iter);
+ dbus_message_iter_next(&dbus_iter);
+ }
+ }
+
+ dispatcher->emitSignalReceived(interface, signal, arglist);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ (void)message;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+DBusDispatcher::DBusDispatcher(const QString& service,
+ const QString& path,
+ const QString& interface,
+ QObject *parent)
+ : QObject(parent),
+ d_ptr(new DBusDispatcherPrivate(service, path, interface, path)) {
+ setupDBus();
+}
+
+DBusDispatcher::DBusDispatcher(const QString& service,
+ const QString& path,
+ const QString& interface,
+ const QString& signalPath,
+ QObject *parent)
+ : QObject(parent),
+ d_ptr(new DBusDispatcherPrivate(service, path, interface, signalPath)) {
+ setupDBus();
+}
+
+DBusDispatcher::~DBusDispatcher()
+{
+ if (d_ptr->connection) {
+ dbus_connection_close(d_ptr->connection);
+ dbus_connection_unref(d_ptr->connection);
+ }
+ delete d_ptr;
+}
+
+void DBusDispatcher::setupDBus()
+{
+ d_ptr->connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL);
+
+ if (d_ptr->connection == NULL)
+ qDebug() << "Unable to get DBUS connection!";
+ else {
+ d_ptr->signal_vtable.message_function = signalHandler;
+
+ dbus_connection_set_exit_on_disconnect(d_ptr->connection, FALSE);
+ dbus_connection_setup_with_g_main(d_ptr->connection, NULL);
+ dbus_connection_register_object_path(d_ptr->connection,
+ d_ptr->signalPath.toLatin1(),
+ &d_ptr->signal_vtable,
+ this);
+ }
+}
+
+static DBusMessage *prepareDBusCall(const QString& service,
+ const QString& path,
+ const QString& interface,
+ const QString& method,
+ const QVariant& arg1 = QVariant(),
+ const QVariant& arg2 = QVariant(),
+ const QVariant& arg3 = QVariant(),
+ const QVariant& arg4 = QVariant(),
+ const QVariant& arg5 = QVariant(),
+ const QVariant& arg6 = QVariant(),
+ const QVariant& arg7 = QVariant(),
+ const QVariant& arg8 = QVariant())
+{
+ DBusMessage *message = dbus_message_new_method_call(service.toLatin1(),
+ path.toLatin1(),
+ interface.toLatin1(),
+ method.toLatin1());
+ DBusMessageIter dbus_iter;
+
+ // Append variants to DBUS message
+ QList<QVariant> arglist;
+ if (arg1.isValid()) arglist << arg1;
+ if (arg2.isValid()) arglist << arg2;
+ if (arg3.isValid()) arglist << arg3;
+ if (arg4.isValid()) arglist << arg4;
+ if (arg5.isValid()) arglist << arg5;
+ if (arg6.isValid()) arglist << arg6;
+ if (arg7.isValid()) arglist << arg7;
+ if (arg8.isValid()) arglist << arg8;
+
+ dbus_message_iter_init_append (message, &dbus_iter);
+
+ while (!arglist.isEmpty()) {
+ QVariant argument = arglist.takeFirst();
+ appendVariantToDBusMessage(argument, &dbus_iter);
+ }
+
+ return message;
+}
+
+QList<QVariant> DBusDispatcher::call(const QString& method,
+ const QVariant& arg1,
+ const QVariant& arg2,
+ const QVariant& arg3,
+ const QVariant& arg4,
+ const QVariant& arg5,
+ const QVariant& arg6,
+ const QVariant& arg7,
+ const QVariant& arg8) {
+ DBusMessageIter dbus_iter;
+ DBusMessage *message = prepareDBusCall(d_ptr->service, d_ptr->path,
+ d_ptr->interface, method,
+ arg1, arg2, arg3, arg4, arg5,
+ arg6, arg7, arg8);
+ DBusMessage *reply = dbus_connection_send_with_reply_and_block(
+ d_ptr->connection,
+ message, -1, NULL);
+ dbus_message_unref(message);
+
+ QList<QVariant> replylist;
+ if (reply != NULL && dbus_message_iter_init(reply, &dbus_iter)) {
+ // Read return arguments
+ while (dbus_message_iter_get_arg_type (&dbus_iter) != DBUS_TYPE_INVALID) {
+ replylist << getVariantFromDBusMessage(&dbus_iter);
+ dbus_message_iter_next(&dbus_iter);
+ }
+ }
+ if (reply != NULL) dbus_message_unref(reply);
+ return replylist;
+}
+
+class PendingCallInfo {
+public:
+ QString method;
+ DBusDispatcher *dispatcher;
+ DBusDispatcherPrivate *priv;
+};
+
+static void freePendingCallInfo(void *memory) {
+ PendingCallInfo *info = (PendingCallInfo *)memory;
+ delete info;
+}
+
+static void pendingCallFunction (DBusPendingCall *pending,
+ void *memory) {
+ PendingCallInfo *info = (PendingCallInfo *)memory;
+ QString errorStr;
+ QList<QVariant> replyList;
+ DBusMessage *reply = dbus_pending_call_steal_reply (pending);
+
+ Q_ASSERT(reply != NULL);
+
+ if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
+ errorStr = dbus_message_get_error_name (reply);
+ } else {
+ DBusMessageIter dbus_iter;
+ dbus_message_iter_init(reply, &dbus_iter);
+ // Read return arguments
+ while (dbus_message_iter_get_arg_type (&dbus_iter) != DBUS_TYPE_INVALID) {
+ replyList << getVariantFromDBusMessage(&dbus_iter);
+ dbus_message_iter_next(&dbus_iter);
+ }
+ }
+
+ info->priv->pending_calls.removeOne(pending);
+ info->dispatcher->emitCallReply(info->method, replyList, errorStr);
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(pending);
+}
+
+bool DBusDispatcher::callAsynchronous(const QString& method,
+ const QVariant& arg1,
+ const QVariant& arg2,
+ const QVariant& arg3,
+ const QVariant& arg4,
+ const QVariant& arg5,
+ const QVariant& arg6,
+ const QVariant& arg7,
+ const QVariant& arg8) {
+ DBusMessage *message = prepareDBusCall(d_ptr->service, d_ptr->path,
+ d_ptr->interface, method,
+ arg1, arg2, arg3, arg4, arg5,
+ arg6, arg7, arg8);
+ DBusPendingCall *call = NULL;
+ dbus_bool_t ret = dbus_connection_send_with_reply(d_ptr->connection,
+ message, &call, -1);
+ PendingCallInfo *info = new PendingCallInfo;
+ info->method = method;
+ info->dispatcher = this;
+ info->priv = d_ptr;
+
+ dbus_pending_call_set_notify(call, pendingCallFunction, info, freePendingCallInfo);
+ d_ptr->pending_calls.append(call);
+ return (bool)ret;
+}
+
+void DBusDispatcher::emitSignalReceived(const QString& interface,
+ const QString& signal,
+ const QList<QVariant>& args) {
+ emit signalReceived(interface, signal, args); }
+
+void DBusDispatcher::emitCallReply(const QString& method,
+ const QList<QVariant>& args,
+ const QString& error) {
+ emit callReply(method, args, error); }
+
+void DBusDispatcher::synchronousDispatch(int timeout_ms)
+{
+ dbus_connection_read_write_dispatch(d_ptr->connection, timeout_ms);
+}
+
+} // Maemo namespace
+
diff --git a/src/plugins/bearer/icd/dbusdispatcher.h b/src/plugins/bearer/icd/dbusdispatcher.h
new file mode 100644
index 0000000..6f2f347
--- /dev/null
+++ b/src/plugins/bearer/icd/dbusdispatcher.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef DBUSDISPATCHER_H
+#define DBUSDISPATCHER_H
+
+#include <QObject>
+#include <QVariant>
+
+namespace Maemo {
+
+class DBusDispatcherPrivate;
+class DBusDispatcher : public QObject
+{
+ Q_OBJECT
+
+public:
+ DBusDispatcher(const QString& service,
+ const QString& path,
+ const QString& interface,
+ QObject *parent = 0);
+ DBusDispatcher(const QString& service,
+ const QString& path,
+ const QString& interface,
+ const QString& signalPath,
+ QObject *parent = 0);
+ ~DBusDispatcher();
+
+ QList<QVariant> call(const QString& method,
+ const QVariant& arg1 = QVariant(),
+ const QVariant& arg2 = QVariant(),
+ const QVariant& arg3 = QVariant(),
+ const QVariant& arg4 = QVariant(),
+ const QVariant& arg5 = QVariant(),
+ const QVariant& arg6 = QVariant(),
+ const QVariant& arg7 = QVariant(),
+ const QVariant& arg8 = QVariant());
+ bool callAsynchronous(const QString& method,
+ const QVariant& arg1 = QVariant(),
+ const QVariant& arg2 = QVariant(),
+ const QVariant& arg3 = QVariant(),
+ const QVariant& arg4 = QVariant(),
+ const QVariant& arg5 = QVariant(),
+ const QVariant& arg6 = QVariant(),
+ const QVariant& arg7 = QVariant(),
+ const QVariant& arg8 = QVariant());
+ void emitSignalReceived(const QString& interface,
+ const QString& signal,
+ const QList<QVariant>& args);
+ void emitCallReply(const QString& method,
+ const QList<QVariant>& args,
+ const QString& error = "");
+ void synchronousDispatch(int timeout_ms);
+
+Q_SIGNALS:
+ void signalReceived(const QString& interface,
+ const QString& signal,
+ const QList<QVariant>& args);
+ void callReply(const QString& method,
+ const QList<QVariant>& args,
+ const QString& error);
+
+protected:
+ void setupDBus();
+
+private:
+ DBusDispatcherPrivate *d_ptr;
+};
+
+} // Maemo namespace
+
+#endif
diff --git a/src/plugins/bearer/icd/iapconf.cpp b/src/plugins/bearer/icd/iapconf.cpp
new file mode 100644
index 0000000..ddd9fc2
--- /dev/null
+++ b/src/plugins/bearer/icd/iapconf.cpp
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <conn_settings.h>
+
+#include "iapconf.h"
+
+#define QSTRING_TO_CONST_CSTR(str) \
+ str.toUtf8().constData()
+
+namespace Maemo {
+
+class IAPConfPrivate {
+public:
+ ConnSettings *settings;
+
+ ConnSettingsValue *variantToValue(const QVariant &variant);
+ QVariant valueToVariant(ConnSettingsValue *value);
+};
+
+ConnSettingsValue *IAPConfPrivate::variantToValue(const QVariant &variant)
+{
+ // Convert variant to ConnSettingsValue
+ ConnSettingsValue *value = conn_settings_value_new();
+ if (value == 0) {
+ qWarning("IAPConf: Unable to create new ConnSettingsValue");
+ return 0;
+ }
+
+ switch(variant.type()) {
+
+ case QVariant::Invalid:
+ value->type = CONN_SETTINGS_VALUE_INVALID;
+ break;
+
+ case QVariant::String: {
+ char *valueStr = strdup(QSTRING_TO_CONST_CSTR(variant.toString()));
+ value->type = CONN_SETTINGS_VALUE_STRING;
+ value->value.string_val = valueStr;
+ break;
+ }
+
+ case QVariant::Int:
+ value->type = CONN_SETTINGS_VALUE_INT;
+ value->value.int_val = variant.toInt();
+ break;
+
+ case QMetaType::Float:
+ case QVariant::Double:
+ value->type = CONN_SETTINGS_VALUE_DOUBLE;
+ value->value.double_val = variant.toDouble();
+ break;
+
+ case QVariant::Bool:
+ value->type = CONN_SETTINGS_VALUE_BOOL;
+ value->value.bool_val = variant.toBool() ? 1 : 0;
+ break;
+
+ case QVariant::ByteArray: {
+ QByteArray array = variant.toByteArray();
+ value->type = CONN_SETTINGS_VALUE_BYTE_ARRAY;
+ value->value.byte_array.len = array.size();
+ value->value.byte_array.val = (unsigned char *)malloc(array.size());
+ memcpy(value->value.byte_array.val, array.constData(), array.size());
+ break;
+ }
+
+ case QVariant::List: {
+ QVariantList list = variant.toList();
+ ConnSettingsValue **list_val = (ConnSettingsValue **)malloc(
+ (list.size() + 1) * sizeof(ConnSettingsValue *));
+
+ for (int idx = 0; idx < list.size(); idx++) {
+ list_val[idx] = variantToValue(list.at(idx));
+ }
+ list_val[list.size()] = 0;
+
+ value->type = CONN_SETTINGS_VALUE_LIST;
+ value->value.list_val = list_val;
+ break;
+ }
+
+ default:
+ qWarning("IAPConf: Can not handle QVariant of type %d",
+ variant.type());
+ conn_settings_value_destroy(value);
+ return 0;
+ }
+
+ return value;
+}
+
+QVariant IAPConfPrivate::valueToVariant(ConnSettingsValue *value)
+{
+ if (value == 0 || value->type == CONN_SETTINGS_VALUE_INVALID) {
+ return QVariant();
+ }
+
+ switch(value->type) {
+
+ case CONN_SETTINGS_VALUE_BOOL:
+ return QVariant(value->value.bool_val ? true : false);
+
+ case CONN_SETTINGS_VALUE_STRING:
+ return QVariant(QString(value->value.string_val));
+
+ case CONN_SETTINGS_VALUE_DOUBLE:
+ return QVariant(value->value.double_val);
+
+ case CONN_SETTINGS_VALUE_INT:
+ return QVariant(value->value.int_val);
+
+ case CONN_SETTINGS_VALUE_LIST: {
+ // At least with GConf backend connsettings returns byte array as list
+ // of ints, first check for that case
+ if (value->value.list_val && value->value.list_val[0]) {
+ bool canBeConvertedToByteArray = true;
+ for (int idx = 0; value->value.list_val[idx]; idx++) {
+ ConnSettingsValue *val = value->value.list_val[idx];
+ if (val->type != CONN_SETTINGS_VALUE_INT
+ || val->value.int_val > 255
+ || val->value.int_val < 0) {
+ canBeConvertedToByteArray = false;
+ break;
+ }
+ }
+
+ if (canBeConvertedToByteArray) {
+ QByteArray array;
+ for (int idx = 0; value->value.list_val[idx]; idx++) {
+ array.append(value->value.list_val[idx]->value.int_val);
+ }
+ return array;
+ }
+
+ // Create normal list
+ QVariantList list;
+ for (int idx = 0; value->value.list_val[idx]; idx++) {
+ list.append(valueToVariant(value->value.list_val[idx]));
+ }
+ return list;
+ }
+ }
+
+ case CONN_SETTINGS_VALUE_BYTE_ARRAY:
+ return QByteArray::fromRawData((char *)value->value.byte_array.val,
+ value->value.byte_array.len);
+
+ default:
+ return QVariant();
+ }
+}
+
+// Public class implementation
+
+IAPConf::IAPConf(const QString &iap_id)
+ : d_ptr(new IAPConfPrivate)
+{
+ d_ptr->settings = conn_settings_open(CONN_SETTINGS_CONNECTION,
+ QSTRING_TO_CONST_CSTR(iap_id));
+ if (d_ptr->settings == 0) {
+ qWarning("IAPConf: Unable to open ConnSettings for %s",
+ QSTRING_TO_CONST_CSTR(iap_id));
+ }
+}
+
+IAPConf::~IAPConf()
+{
+ conn_settings_close(d_ptr->settings);
+ delete d_ptr;
+}
+
+
+QVariant IAPConf::value(const QString& key) const
+{
+ ConnSettingsValue *val = conn_settings_get(d_ptr->settings,
+ QSTRING_TO_CONST_CSTR(key));
+
+ QVariant variant = d_ptr->valueToVariant(val);
+ conn_settings_value_destroy(val);
+ return variant;
+}
+
+
+void IAPConf::getAll(QList<QString> &all_iaps, bool return_path)
+{
+ Q_UNUSED(return_path); // We don't use return path currently
+
+ // Go through all available connections and add them to the list
+ char **ids = conn_settings_list_ids(CONN_SETTINGS_CONNECTION);
+ if (ids == 0) {
+ // No ids found - nothing to do
+ return;
+ }
+
+ for (int idx = 0; ids[idx]; idx++) {
+ all_iaps.append(QString(ids[idx]));
+ free(ids[idx]);
+ }
+ free(ids);
+}
+
+
+} // namespace Maemo
diff --git a/src/plugins/bearer/icd/iapconf.h b/src/plugins/bearer/icd/iapconf.h
new file mode 100644
index 0000000..9c4ddcb
--- /dev/null
+++ b/src/plugins/bearer/icd/iapconf.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef IAPCONF_H
+#define IAPCONF_H
+
+#include <QString>
+#include <QVariant>
+
+namespace Maemo {
+
+class IAPConfPrivate;
+class IAPConf {
+public:
+ IAPConf(const QString &iap_id);
+ virtual ~IAPConf();
+
+ /**
+ Get one IAP value.
+ */
+ QVariant value(const QString& key) const;
+
+ /**
+ Return all the IAPs found in the system. If return_path is true,
+ then do not strip the IAP path away.
+ */
+ static void getAll(QList<QString> &all_iaps, bool return_path=false);
+
+private:
+ IAPConfPrivate *d_ptr;
+};
+
+} // namespace Maemo
+
+#endif
diff --git a/src/plugins/bearer/icd/iapmonitor.cpp b/src/plugins/bearer/icd/iapmonitor.cpp
new file mode 100644
index 0000000..6138e7b
--- /dev/null
+++ b/src/plugins/bearer/icd/iapmonitor.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QStringList>
+
+#include <conn_settings.h>
+#include "iapmonitor.h"
+
+namespace Maemo {
+
+
+void conn_settings_notify_func (ConnSettingsType type,
+ const char *id,
+ const char *key,
+ ConnSettingsValue *value,
+ void *user_data);
+
+class IAPMonitorPrivate {
+private:
+ IAPMonitor *monitor;
+ ConnSettings *settings;
+
+public:
+
+ IAPMonitorPrivate(IAPMonitor *monitor)
+ : monitor(monitor)
+ {
+ settings = conn_settings_open(CONN_SETTINGS_CONNECTION, NULL);
+ conn_settings_add_notify(
+ settings,
+ (ConnSettingsNotifyFunc *)conn_settings_notify_func,
+ this);
+ }
+
+ ~IAPMonitorPrivate()
+ {
+ conn_settings_del_notify(settings);
+ conn_settings_close(settings);
+ }
+
+ void iapAdded(const QString &iap)
+ {
+ monitor->iapAdded(iap);
+ }
+
+ void iapRemoved(const QString &iap)
+ {
+ monitor->iapRemoved(iap);
+ }
+};
+
+void conn_settings_notify_func (ConnSettingsType type,
+ const char *id,
+ const char *key,
+ ConnSettingsValue *value,
+ void *user_data)
+{
+ if (type != CONN_SETTINGS_CONNECTION) return;
+ IAPMonitorPrivate *priv = (IAPMonitorPrivate *)user_data;
+
+ QString iapId(key);
+ iapId = iapId.split("/")[0];
+ if (value != 0) {
+ priv->iapAdded(iapId);
+ } else if (iapId == QString(key)) {
+ // IAP is removed only when the directory gets removed
+ priv->iapRemoved(iapId);
+ }
+}
+
+IAPMonitor::IAPMonitor()
+ : d_ptr(new IAPMonitorPrivate(this))
+{
+}
+
+IAPMonitor::~IAPMonitor()
+{
+ delete d_ptr;
+}
+
+void IAPMonitor::iapAdded(const QString &id)
+{
+ // By default do nothing
+}
+
+void IAPMonitor::iapRemoved(const QString &id)
+{
+ // By default do nothing
+}
+
+} // namespace Maemo
diff --git a/src/plugins/bearer/icd/iapmonitor.h b/src/plugins/bearer/icd/iapmonitor.h
new file mode 100644
index 0000000..21ad3bc
--- /dev/null
+++ b/src/plugins/bearer/icd/iapmonitor.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef IAPMONITOR_H
+#define IAPMONITOR_H
+
+#include <QString>
+
+namespace Maemo {
+
+class IAPMonitorPrivate;
+class IAPMonitor {
+public:
+ IAPMonitor();
+ ~IAPMonitor();
+
+protected:
+ virtual void iapAdded(const QString &id);
+ virtual void iapRemoved(const QString &id);
+
+private:
+ IAPMonitorPrivate *d_ptr;
+ Q_DECLARE_PRIVATE(IAPMonitor);
+};
+
+} // namespace Maemo
+
+#endif // IAPMONITOR_H
+
diff --git a/src/plugins/bearer/icd/icd.pro b/src/plugins/bearer/icd/icd.pro
index b2c58e9..464cc1c 100644
--- a/src/plugins/bearer/icd/icd.pro
+++ b/src/plugins/bearer/icd/icd.pro
@@ -7,15 +7,25 @@ QMAKE_CXXFLAGS *= $$QT_CFLAGS_DBUS $$QT_CFLAGS_CONNSETTINGS
LIBS += $$QT_LIBS_CONNSETTINGS
HEADERS += qicdengine.h \
- qnetworksession_impl.h
+ qnetworksession_impl.h \
+ dbusdispatcher.h \
+ iapconf.h \
+ iapmonitor.h \
+ maemo_icd.h \
+ proxyconf.h \
+ wlan-utils.h
SOURCES += main.cpp \
qicdengine.cpp \
- qnetworksession_impl.cpp
+ qnetworksession_impl.cpp \
+ dbusdispatcher.cpp \
+ iapmonitor.cpp \
+ iapconf.cpp \
+ maemo_icd.cpp \
+ proxyconf.cpp
#DEFINES += BEARER_MANAGEMENT_DEBUG
-include(../../../3rdparty/libconninet.pri)
include(../../../3rdparty/libgq.pri)
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer
diff --git a/src/plugins/bearer/icd/maemo_icd.cpp b/src/plugins/bearer/icd/maemo_icd.cpp
new file mode 100644
index 0000000..eb093fe
--- /dev/null
+++ b/src/plugins/bearer/icd/maemo_icd.cpp
@@ -0,0 +1,849 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "maemo_icd.h"
+#include "dbusdispatcher.h"
+
+#include <QObject>
+#include <QTimer>
+#include <QCoreApplication>
+#include <QEventLoop>
+#include <QDebug>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace Maemo {
+
+#undef PRINT_DEBUGINFO
+#ifdef PRINT_DEBUGINFO
+ static FILE *fdebug = NULL;
+#define PDEBUG(fmt, args...) \
+ do { \
+ struct timeval tv; \
+ gettimeofday(&tv, 0); \
+ fprintf(fdebug, "DEBUG[%d]:%ld.%ld:%s:%s():%d: " fmt, \
+ getpid(), \
+ tv.tv_sec, tv.tv_usec, \
+ __FILE__, __FUNCTION__, __LINE__, args); \
+ fflush(fdebug); \
+ } while(0)
+#else
+#define PDEBUG(fmt...)
+#endif
+
+
+class IcdPrivate
+{
+public:
+ IcdPrivate(Icd *myfriend)
+ {
+ init(10000, IcdNewDbusInterface, myfriend);
+ }
+
+ IcdPrivate(unsigned int timeout, Icd *myfriend)
+ {
+ init(timeout, IcdNewDbusInterface, myfriend);
+ }
+
+ IcdPrivate(unsigned int timeout, IcdDbusInterfaceVer ver, Icd *myfriend)
+ {
+ /* Note that the old Icd interface is currently disabled and
+ * the new one is always used.
+ */
+ init(timeout, IcdNewDbusInterface, myfriend);
+ }
+
+ ~IcdPrivate()
+ {
+ QObject::disconnect(mDBus,
+ SIGNAL(signalReceived(const QString&,
+ const QString&,
+ const QList<QVariant>&)),
+ icd,
+ SLOT(icdSignalReceived(const QString&,
+ const QString&,
+ const QList<QVariant>&)));
+
+ QObject::disconnect(mDBus,
+ SIGNAL(callReply(const QString&,
+ const QList<QVariant>&,
+ const QString&)),
+ icd,
+ SLOT(icdCallReply(const QString&,
+ const QList<QVariant>&,
+ const QString&)));
+
+ delete mDBus;
+ mDBus = 0;
+ }
+
+ /* Icd2 dbus API functions */
+ QStringList scan(icd_scan_request_flags flags,
+ QStringList &network_types,
+ QList<IcdScanResult>& scan_results,
+ QString& error);
+
+ uint state(QString& service_type, uint service_attrs,
+ QString& service_id, QString& network_type,
+ uint network_attrs, QByteArray& network_id,
+ IcdStateResult &state_result);
+
+ uint addrinfo(QString& service_type, uint service_attrs,
+ QString& service_id, QString& network_type,
+ uint network_attrs, QByteArray& network_id,
+ IcdAddressInfoResult& addr_result);
+
+ uint state(QList<IcdStateResult>& state_results);
+ uint statistics(QList<IcdStatisticsResult>& stats_results);
+ uint addrinfo(QList<IcdAddressInfoResult>& addr_results);
+
+ void signalReceived(const QString& interface,
+ const QString& signal,
+ const QList<QVariant>& args);
+ void callReply(const QString& method,
+ const QList<QVariant>& args,
+ const QString& error);
+
+public:
+ DBusDispatcher *mDBus;
+ QString mMethod;
+ QString mInterface;
+ QString mSignal;
+ QString mError;
+ QList<QVariant> mArgs;
+ QList<QVariant> receivedSignals;
+ unsigned int timeout;
+ IcdDbusInterfaceVer icd_dbus_version;
+ Icd *icd;
+
+ void init(unsigned int dbus_timeout, IcdDbusInterfaceVer ver,
+ Icd *myfriend)
+ {
+ if (ver == IcdNewDbusInterface) {
+ mDBus = new DBusDispatcher(ICD_DBUS_API_INTERFACE,
+ ICD_DBUS_API_PATH,
+ ICD_DBUS_API_INTERFACE);
+ } else {
+ mDBus = new DBusDispatcher(ICD_DBUS_SERVICE,
+ ICD_DBUS_PATH,
+ ICD_DBUS_INTERFACE);
+ }
+ icd_dbus_version = ver;
+
+ /* This connect has a side effect as it means that only one
+ * Icd object can exists in one time. This should be fixed!
+ */
+ QObject::connect(mDBus,
+ SIGNAL(signalReceived(const QString&,
+ const QString&,
+ const QList<QVariant>&)),
+ myfriend,
+ SLOT(icdSignalReceived(const QString&,
+ const QString&,
+ const QList<QVariant>&)));
+
+ QObject::connect(mDBus,
+ SIGNAL(callReply(const QString&,
+ const QList<QVariant>&,
+ const QString&)),
+ myfriend,
+ SLOT(icdCallReply(const QString&,
+ const QList<QVariant>&,
+ const QString&)));
+
+ icd = myfriend;
+ timeout = dbus_timeout;
+
+#ifdef PRINT_DEBUGINFO
+ if (!fdebug) {
+ fdebug = fopen("/tmp/maemoicd.log", "a+");
+ }
+ PDEBUG("created %s\n", "IcdPrivate");
+#endif
+ }
+
+ void clearState()
+ {
+ mMethod.clear();
+ mInterface.clear();
+ mSignal.clear();
+ mError.clear();
+ mArgs.clear();
+ receivedSignals.clear();
+ }
+
+ bool doState();
+};
+
+
+void IcdPrivate::signalReceived(const QString& interface,
+ const QString& signal,
+ const QList<QVariant>& args)
+{
+ // Signal handler, which simply records what has been signalled
+ mInterface = interface;
+ mSignal = signal;
+ mArgs = args;
+
+ //qDebug() << "signal" << signal << "received:" << args;
+ receivedSignals << QVariant(interface) << QVariant(signal) << QVariant(args);
+}
+
+
+void IcdPrivate::callReply(const QString& method,
+ const QList<QVariant>& /*args*/,
+ const QString& error)
+{
+ mMethod = method;
+ mError = error;
+}
+
+
+static void get_scan_result(QList<QVariant>& args,
+ IcdScanResult& ret)
+{
+ int i=0;
+
+ if (args.isEmpty())
+ return;
+
+ ret.status = args[i++].toUInt();
+ ret.timestamp = args[i++].toUInt();
+ ret.scan.service_type = args[i++].toString();
+ ret.service_name = args[i++].toString();
+ ret.scan.service_attrs = args[i++].toUInt();
+ ret.scan.service_id = args[i++].toString();
+ ret.service_priority = args[i++].toInt();
+ ret.scan.network_type = args[i++].toString();
+ ret.network_name = args[i++].toString();
+ ret.scan.network_attrs = args[i++].toUInt();
+ ret.scan.network_id = args[i++].toByteArray();
+ ret.network_priority = args[i++].toInt();
+ ret.signal_strength = args[i++].toInt();
+ ret.station_id = args[i++].toString();
+ ret.signal_dB = args[i++].toInt();
+}
+
+
+QStringList IcdPrivate::scan(icd_scan_request_flags flags,
+ QStringList &network_types,
+ QList<IcdScanResult>& scan_results,
+ QString& error)
+{
+ QStringList scanned_types;
+ QTimer timer;
+ QVariant reply;
+ QVariantList vl;
+ bool last_result = false;
+ IcdScanResult result;
+ int all_waited;
+
+ clearState();
+ reply = mDBus->call(ICD_DBUS_API_SCAN_REQ, (uint)flags);
+ if (reply.type() != QVariant::List)
+ return scanned_types;
+ vl = reply.toList();
+ if (vl.isEmpty()) {
+ error = "Scan did not return anything.";
+ return scanned_types;
+ }
+ reply = vl.first();
+ scanned_types = reply.toStringList();
+ //qDebug() << "Scanning:" << scanned_types;
+ all_waited = scanned_types.size();
+
+ timer.setSingleShot(true);
+ timer.start(timeout);
+
+ scan_results.clear();
+ while (!last_result) {
+ while (timer.isActive() && mInterface.isEmpty() && mError.isEmpty()) {
+ QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
+ }
+
+ if (!timer.isActive()) {
+ //qDebug() << "Timeout happened";
+ break;
+ }
+
+ if (mSignal != ICD_DBUS_API_SCAN_SIG) {
+ //qDebug() << "Received" << mSignal << "while waiting" << ICD_DBUS_API_SCAN_SIG << ", ignoring";
+ mInterface.clear();
+ continue;
+ }
+
+ if (mError.isEmpty()) {
+ QString msgInterface = receivedSignals.takeFirst().toString();
+ QString msgSignal = receivedSignals.takeFirst().toString();
+ QList<QVariant> msgArgs = receivedSignals.takeFirst().toList();
+ //qDebug() << "Signal" << msgSignal << "received.";
+ //qDebug() << "Params:" << msgArgs;
+
+ while (!msgSignal.isEmpty()) {
+ get_scan_result(msgArgs, result);
+
+#if 0
+ qDebug() << "Received: " <<
+ "status =" << result.status <<
+ ", timestamp =" << result.timestamp <<
+ ", service_type =" << result.scan.service_type <<
+ ", service_name =" << result.service_name <<
+ ", service_attrs =" << result.scan.service_attrs <<
+ ", service_id =" << result.scan.service_id <<
+ ", service_priority =" << result.service_priority <<
+ ", network_type =" << result.scan.network_type <<
+ ", network_name =" << result.network_name <<
+ ", network_attrs =" << result.scan.network_attrs <<
+ ", network_id =" << "-" <<
+ ", network_priority =" << result.network_priority <<
+ ", signal_strength =" << result.signal_strength <<
+ ", station_id =" << result.station_id <<
+ ", signal_dB =" << result.signal_dB;
+#endif
+
+ if (result.status == ICD_SCAN_COMPLETE) {
+ //qDebug() << "waited =" << all_waited;
+ if (--all_waited == 0) {
+ last_result = true;
+ break;
+ }
+ } else
+ scan_results << result;
+
+ if (receivedSignals.isEmpty())
+ break;
+
+ msgInterface = receivedSignals.takeFirst().toString();
+ msgSignal = receivedSignals.takeFirst().toString();
+ msgArgs = receivedSignals.takeFirst().toList();
+ }
+ mInterface.clear();
+
+ } else {
+ qWarning() << "Error while scanning:" << mError;
+ break;
+ }
+ }
+ timer.stop();
+
+ error = mError;
+ return scanned_types;
+}
+
+
+static void get_state_all_result(QList<QVariant>& args,
+ IcdStateResult& ret)
+{
+ int i=0;
+
+ ret.params.service_type = args[i++].toString();
+ ret.params.service_attrs = args[i++].toUInt();
+ ret.params.service_id = args[i++].toString();
+ ret.params.network_type = args[i++].toString();
+ ret.params.network_attrs = args[i++].toUInt();
+ ret.params.network_id = args[i++].toByteArray();
+ ret.error = args[i++].toString();
+ ret.state = args[i++].toInt();
+}
+
+
+static void get_state_all_result2(QList<QVariant>& args,
+ IcdStateResult& ret)
+{
+ int i=0;
+
+ ret.params.network_type = args[i++].toString();
+ ret.state = args[i++].toInt();
+
+ // Initialize the other values so that the caller can
+ // notice we only returned partial status
+ ret.params.service_type = QString();
+ ret.params.service_attrs = 0;
+ ret.params.service_id = QString();
+ ret.params.network_attrs = 0;
+ ret.params.network_id = QByteArray();
+ ret.error = QString();
+}
+
+
+uint IcdPrivate::state(QString& service_type, uint service_attrs,
+ QString& service_id, QString& network_type,
+ uint network_attrs, QByteArray& network_id,
+ IcdStateResult& state_result)
+{
+ QTimer timer;
+ QVariant reply;
+ uint total_signals;
+ QVariantList vl;
+
+ clearState();
+
+ reply = mDBus->call(ICD_DBUS_API_STATE_REQ,
+ service_type, service_attrs, service_id,
+ network_type, network_attrs, network_id);
+ if (reply.type() != QVariant::List)
+ return 0;
+ vl = reply.toList();
+ if (vl.isEmpty())
+ return 0;
+ reply = vl.first();
+ total_signals = reply.toUInt();
+ if (!total_signals)
+ return 0;
+
+ timer.setSingleShot(true);
+ timer.start(timeout);
+
+ mInterface.clear();
+ while (timer.isActive() && mInterface.isEmpty()) {
+ QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
+
+ if (mSignal != ICD_DBUS_API_STATE_SIG) {
+ mInterface.clear();
+ continue;
+ }
+ }
+
+ timer.stop();
+
+ if (mError.isEmpty()) {
+ if (!mArgs.isEmpty()) {
+ if (mArgs.size()>2)
+ get_state_all_result(mArgs, state_result);
+ else {
+ // We are not connected as we did not get the status we asked
+ return 0;
+ }
+ }
+ } else {
+ qWarning() << "Error:" << mError;
+ }
+
+ // The returned value should be one because we asked for one state
+ return total_signals;
+}
+
+
+/* Special version of the state() call which does not call event loop.
+ * Needed in order to fix NB#175098 where Qt4.7 webkit crashes because event
+ * loop is run when webkit does not expect it. This function is called from
+ * bearer management API syncStateWithInterface() in QNetworkSession
+ * constructor.
+ */
+uint IcdPrivate::state(QList<IcdStateResult>& state_results)
+{
+ QVariant reply;
+ QVariantList vl;
+ uint signals_left, total_signals;
+ IcdStateResult result;
+ time_t started;
+ int timeout_secs = timeout / 1000;
+
+ PDEBUG("%s\n", "state_results");
+
+ clearState();
+ reply = mDBus->call(ICD_DBUS_API_STATE_REQ);
+ if (reply.type() != QVariant::List)
+ return 0;
+ vl = reply.toList();
+ if (vl.isEmpty())
+ return 0;
+ reply = vl.first();
+ signals_left = total_signals = reply.toUInt();
+ if (!signals_left)
+ return 0;
+
+ started = time(0);
+ state_results.clear();
+ mError.clear();
+ while (signals_left) {
+ mInterface.clear();
+ while ((time(0)<=(started+timeout_secs)) && mInterface.isEmpty()) {
+ mDBus->synchronousDispatch(1000);
+ }
+
+ if (time(0)>(started+timeout_secs)) {
+ total_signals = 0;
+ break;
+ }
+
+ if (mSignal != ICD_DBUS_API_STATE_SIG) {
+ continue;
+ }
+
+ if (mError.isEmpty()) {
+ if (!mArgs.isEmpty()) {
+ if (mArgs.size()==2)
+ get_state_all_result2(mArgs, result);
+ else
+ get_state_all_result(mArgs, result);
+ state_results << result;
+ }
+ signals_left--;
+ } else {
+ qWarning() << "Error:" << mError;
+ break;
+ }
+ }
+
+ PDEBUG("total_signals=%d\n", total_signals);
+ return total_signals;
+}
+
+
+static void get_statistics_all_result(QList<QVariant>& args,
+ IcdStatisticsResult& ret)
+{
+ int i=0;
+
+ if (args.isEmpty())
+ return;
+
+ ret.params.service_type = args[i++].toString();
+ ret.params.service_attrs = args[i++].toUInt();
+ ret.params.service_id = args[i++].toString();
+ ret.params.network_type = args[i++].toString();
+ ret.params.network_attrs = args[i++].toUInt();
+ ret.params.network_id = args[i++].toByteArray();
+ ret.time_active = args[i++].toUInt();
+ ret.signal_strength = (enum icd_nw_levels)args[i++].toUInt();
+ ret.bytes_sent = args[i++].toUInt();
+ ret.bytes_received = args[i++].toUInt();
+}
+
+
+uint IcdPrivate::statistics(QList<IcdStatisticsResult>& stats_results)
+{
+ QTimer timer;
+ QVariant reply;
+ QVariantList vl;
+ uint signals_left, total_signals;
+ IcdStatisticsResult result;
+
+ clearState();
+ reply = mDBus->call(ICD_DBUS_API_STATISTICS_REQ);
+ if (reply.type() != QVariant::List)
+ return 0;
+ vl = reply.toList();
+ if (vl.isEmpty())
+ return 0;
+ reply = vl.first();
+ if (reply.type() != QVariant::UInt)
+ return 0;
+ signals_left = total_signals = reply.toUInt();
+
+ if (!signals_left)
+ return 0;
+
+ timer.setSingleShot(true);
+ timer.start(timeout);
+ stats_results.clear();
+ while (signals_left) {
+ mInterface.clear();
+ while (timer.isActive() && mInterface.isEmpty()) {
+ QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
+ }
+
+ if (!timer.isActive()) {
+ total_signals = 0;
+ break;
+ }
+
+ if (mSignal != ICD_DBUS_API_STATISTICS_SIG) {
+ continue;
+ }
+
+ if (mError.isEmpty()) {
+ get_statistics_all_result(mArgs, result);
+ stats_results << result;
+ signals_left--;
+ } else {
+ qWarning() << "Error:" << mError;
+ break;
+ }
+ }
+ timer.stop();
+
+ return total_signals;
+}
+
+
+static void get_addrinfo_all_result(QList<QVariant>& args,
+ IcdAddressInfoResult& ret)
+{
+ int i=0;
+
+ if (args.isEmpty())
+ return;
+
+ ret.params.service_type = args[i++].toString();
+ ret.params.service_attrs = args[i++].toUInt();
+ ret.params.service_id = args[i++].toString();
+ ret.params.network_type = args[i++].toString();
+ ret.params.network_attrs = args[i++].toUInt();
+ ret.params.network_id = args[i++].toByteArray();
+
+ QVariantList vl = args[i].toList();
+ QVariant reply = vl.first();
+ QList<QVariant> lst = reply.toList();
+ for (int k=0; k<lst.size()/6; k=k+6) {
+ IcdIPInformation ip_info;
+ ip_info.address = lst[k].toString();
+ ip_info.netmask = lst[k++].toString();
+ ip_info.default_gateway = lst[k++].toString();
+ ip_info.dns1 = lst[k++].toString();
+ ip_info.dns2 = lst[k++].toString();
+ ip_info.dns3 = lst[k++].toString();
+
+ ret.ip_info << ip_info;
+ }
+}
+
+
+/* Special version of the addrinfo() call which does not call event loop.
+ * Needed in order to fix NB#175098 where Qt4.7 webkit crashes because event
+ * loop is run when webkit does not expect it. This function is called from
+ * bearer management API syncStateWithInterface() in QNetworkSession
+ * constructor.
+ */
+uint IcdPrivate::addrinfo(QList<IcdAddressInfoResult>& addr_results)
+{
+ QVariant reply;
+ QVariantList vl;
+ uint signals_left, total_signals;
+ IcdAddressInfoResult result;
+ time_t started;
+ int timeout_secs = timeout / 1000;
+
+ PDEBUG("%s\n", "addr_results");
+
+ clearState();
+ reply = mDBus->call(ICD_DBUS_API_ADDRINFO_REQ);
+ if (reply.type() != QVariant::List)
+ return 0;
+ vl = reply.toList();
+ if (vl.isEmpty())
+ return 0;
+ reply = vl.first();
+ if (reply.type() != QVariant::UInt)
+ return 0;
+ signals_left = total_signals = reply.toUInt();
+ if (!signals_left)
+ return 0;
+
+ started = time(0);
+ addr_results.clear();
+ while (signals_left) {
+ mInterface.clear();
+ while ((time(0)<=(started+timeout_secs)) && mInterface.isEmpty()) {
+ mDBus->synchronousDispatch(1000);
+ }
+
+ if (time(0)>(started+timeout_secs)) {
+ total_signals = 0;
+ break;
+ }
+
+ if (mSignal != ICD_DBUS_API_ADDRINFO_SIG) {
+ continue;
+ }
+
+ if (mError.isEmpty()) {
+ get_addrinfo_all_result(mArgs, result);
+ addr_results << result;
+ signals_left--;
+ } else {
+ qWarning() << "Error:" << mError;
+ break;
+ }
+ }
+
+ PDEBUG("total_signals=%d\n", total_signals);
+ return total_signals;
+}
+
+
+uint IcdPrivate::addrinfo(QString& service_type, uint service_attrs,
+ QString& service_id, QString& network_type,
+ uint network_attrs, QByteArray& network_id,
+ IcdAddressInfoResult& addr_result)
+{
+ QTimer timer;
+ QVariant reply;
+ uint total_signals;
+ QVariantList vl;
+
+ clearState();
+
+ reply = mDBus->call(ICD_DBUS_API_ADDRINFO_REQ,
+ service_type, service_attrs, service_id,
+ network_type, network_attrs, network_id);
+ if (reply.type() != QVariant::List)
+ return 0;
+ vl = reply.toList();
+ if (vl.isEmpty())
+ return 0;
+ reply = vl.first();
+ total_signals = reply.toUInt();
+
+ if (!total_signals)
+ return 0;
+
+ timer.setSingleShot(true);
+ timer.start(timeout);
+
+ mInterface.clear();
+ while (timer.isActive() && mInterface.isEmpty()) {
+ QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
+
+ if (mSignal != ICD_DBUS_API_ADDRINFO_SIG) {
+ mInterface.clear();
+ continue;
+ }
+ }
+
+ timer.stop();
+
+ if (mError.isEmpty()) {
+ get_addrinfo_all_result(mArgs, addr_result);
+ } else {
+ qWarning() << "Error:" << mError;
+ }
+
+ // The returned value should be one because we asked for one addrinfo
+ return total_signals;
+}
+
+
+Icd::Icd(QObject *parent)
+ : QObject(parent), d(new IcdPrivate(this))
+{
+}
+
+Icd::Icd(unsigned int timeout, QObject *parent)
+ : QObject(parent), d(new IcdPrivate(timeout, this))
+{
+}
+
+Icd::Icd(unsigned int timeout, IcdDbusInterfaceVer ver, QObject *parent)
+ : QObject(parent), d(new IcdPrivate(timeout, ver, this))
+{
+}
+
+Icd::~Icd()
+{
+ delete d;
+}
+
+
+QStringList Icd::scan(icd_scan_request_flags flags,
+ QStringList &network_types,
+ QList<IcdScanResult>& scan_results,
+ QString& error)
+{
+ return d->scan(flags, network_types, scan_results, error);
+}
+
+
+uint Icd::state(QString& service_type, uint service_attrs,
+ QString& service_id, QString& network_type,
+ uint network_attrs, QByteArray& network_id,
+ IcdStateResult &state_result)
+{
+ return d->state(service_type, service_attrs, service_id,
+ network_type, network_attrs, network_id,
+ state_result);
+}
+
+
+uint Icd::addrinfo(QString& service_type, uint service_attrs,
+ QString& service_id, QString& network_type,
+ uint network_attrs, QByteArray& network_id,
+ IcdAddressInfoResult& addr_result)
+{
+ return d->addrinfo(service_type, service_attrs, service_id,
+ network_type, network_attrs, network_id,
+ addr_result);
+}
+
+
+uint Icd::state(QList<IcdStateResult>& state_results)
+{
+ return d->state(state_results);
+}
+
+
+uint Icd::statistics(QList<IcdStatisticsResult>& stats_results)
+{
+ return d->statistics(stats_results);
+}
+
+
+uint Icd::addrinfo(QList<IcdAddressInfoResult>& addr_results)
+{
+ return d->addrinfo(addr_results);
+}
+
+
+void Icd::icdSignalReceived(const QString& interface,
+ const QString& signal,
+ const QList<QVariant>& args)
+{
+ d->signalReceived(interface, signal, args);
+}
+
+
+void Icd::icdCallReply(const QString& method,
+ const QList<QVariant>& args,
+ const QString& error)
+{
+ d->callReply(method, args, error);
+}
+
+} // Maemo namespace
+
+
diff --git a/src/plugins/bearer/icd/maemo_icd.h b/src/plugins/bearer/icd/maemo_icd.h
new file mode 100644
index 0000000..156316a
--- /dev/null
+++ b/src/plugins/bearer/icd/maemo_icd.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef MAEMO_ICD_H
+#define MAEMO_ICD_H
+
+#include <QObject>
+#include <QStringList>
+#include <QByteArray>
+#include <QMetaType>
+#include <QtDBus>
+#include <QDBusArgument>
+
+#include <glib.h>
+#include <icd/dbus_api.h>
+#include <icd/osso-ic.h>
+#include <icd/osso-ic-dbus.h>
+#include <icd/network_api_defines.h>
+
+#define ICD_LONG_SCAN_TIMEOUT (30*1000) /* 30sec */
+#define ICD_SHORT_SCAN_TIMEOUT (10*1000) /* 10sec */
+#define ICD_SHORT_CONNECT_TIMEOUT (10*1000) /* 10sec */
+#define ICD_LONG_CONNECT_TIMEOUT (150*1000) /* 2.5min */
+
+namespace Maemo {
+
+struct CommonParams {
+ QString service_type;
+ uint service_attrs;
+ QString service_id;
+ QString network_type;
+ uint network_attrs;
+ QByteArray network_id;
+};
+
+struct IcdScanResult {
+ uint status; // see #icd_scan_status
+ uint timestamp; // when last seen
+ QString service_name;
+ uint service_priority; // within a service type
+ QString network_name;
+ uint network_priority;
+ struct CommonParams scan;
+ uint signal_strength; // quality, 0 (none) - 10 (good)
+ QString station_id; // e.g. MAC address or similar id
+ uint signal_dB; // use signal strength above unless you know what you are doing
+
+ IcdScanResult() {
+ status = timestamp = scan.service_attrs = service_priority =
+ scan.network_attrs = network_priority = signal_strength =
+ signal_dB = 0;
+ }
+};
+
+struct IcdStateResult {
+ struct CommonParams params;
+ QString error;
+ uint state;
+};
+
+struct IcdStatisticsResult {
+ struct CommonParams params;
+ uint time_active; // in seconds
+ enum icd_nw_levels signal_strength; // see network_api_defines.h in icd2-dev package
+ uint bytes_sent;
+ uint bytes_received;
+};
+
+struct IcdIPInformation {
+ QString address;
+ QString netmask;
+ QString default_gateway;
+ QString dns1;
+ QString dns2;
+ QString dns3;
+};
+
+struct IcdAddressInfoResult {
+ struct CommonParams params;
+ QList<IcdIPInformation> ip_info;
+};
+
+enum IcdDbusInterfaceVer {
+ IcdOldDbusInterface = 0, // use the old OSSO-IC interface
+ IcdNewDbusInterface // use the new Icd2 interface (default)
+};
+
+
+class IcdPrivate;
+class Icd : public QObject
+{
+ Q_OBJECT
+
+public:
+ Icd(QObject *parent = 0);
+ Icd(unsigned int timeout, QObject *parent = 0);
+ Icd(unsigned int timeout, IcdDbusInterfaceVer ver, QObject *parent = 0);
+ ~Icd();
+
+ /* Icd2 dbus API functions */
+ QStringList scan(icd_scan_request_flags flags,
+ QStringList &network_types,
+ QList<IcdScanResult>& scan_results,
+ QString& error);
+
+ uint state(QString& service_type, uint service_attrs,
+ QString& service_id, QString& network_type,
+ uint network_attrs, QByteArray& network_id,
+ IcdStateResult &state_result);
+
+ uint addrinfo(QString& service_type, uint service_attrs,
+ QString& service_id, QString& network_type,
+ uint network_attrs, QByteArray& network_id,
+ IcdAddressInfoResult& addr_result);
+
+ uint state(QList<IcdStateResult>& state_results);
+ uint statistics(QList<IcdStatisticsResult>& stats_results);
+ uint addrinfo(QList<IcdAddressInfoResult>& addr_results);
+
+private Q_SLOTS:
+ void icdSignalReceived(const QString& interface,
+ const QString& signal,
+ const QList<QVariant>& args);
+ void icdCallReply(const QString& method,
+ const QList<QVariant>& args,
+ const QString& error);
+
+private:
+ IcdPrivate *d;
+ friend class IcdPrivate;
+};
+
+} // Maemo namespace
+
+#endif
diff --git a/src/plugins/bearer/icd/proxyconf.cpp b/src/plugins/bearer/icd/proxyconf.cpp
new file mode 100644
index 0000000..e5c8f4e
--- /dev/null
+++ b/src/plugins/bearer/icd/proxyconf.cpp
@@ -0,0 +1,412 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QVariant>
+#include <QStringList>
+#include <QDebug>
+#include <QWriteLocker>
+#include <QNetworkProxyFactory>
+#include <QNetworkProxy>
+#include <gconf/gconf-value.h>
+#include <gconf/gconf-client.h>
+#include "proxyconf.h"
+
+#define CONF_PROXY "/system/proxy"
+#define HTTP_PROXY "/system/http_proxy"
+
+
+namespace Maemo {
+
+static QString convertKey(const char *key)
+{
+ return QString::fromUtf8(key);
+}
+
+static QVariant convertValue(GConfValue *src)
+{
+ if (!src) {
+ return QVariant();
+ } else {
+ switch (src->type) {
+ case GCONF_VALUE_INVALID:
+ return QVariant(QVariant::Invalid);
+ case GCONF_VALUE_BOOL:
+ return QVariant((bool)gconf_value_get_bool(src));
+ case GCONF_VALUE_INT:
+ return QVariant(gconf_value_get_int(src));
+ case GCONF_VALUE_FLOAT:
+ return QVariant(gconf_value_get_float(src));
+ case GCONF_VALUE_STRING:
+ return QVariant(QString::fromUtf8(gconf_value_get_string(src)));
+ case GCONF_VALUE_LIST:
+ switch (gconf_value_get_list_type(src)) {
+ case GCONF_VALUE_STRING:
+ {
+ QStringList result;
+ for (GSList *elts = gconf_value_get_list(src); elts; elts = elts->next)
+ result.append(QString::fromUtf8(gconf_value_get_string((GConfValue *)elts->data)));
+ return QVariant(result);
+ }
+ default:
+ {
+ QList<QVariant> result;
+ for (GSList *elts = gconf_value_get_list(src); elts; elts = elts->next)
+ result.append(convertValue((GConfValue *)elts->data));
+ return QVariant(result);
+ }
+ }
+ case GCONF_VALUE_SCHEMA:
+ default:
+ return QVariant();
+ }
+ }
+}
+
+
+/* Fast version of GConfItem, allows reading subtree at a time */
+class GConfItemFast {
+public:
+ GConfItemFast(const QString &k) : key(k) {}
+ QHash<QString,QVariant> getEntries() const;
+
+private:
+ QString key;
+};
+
+#define withClient(c) for (GConfClient *c = gconf_client_get_default(); c; c=0)
+
+
+QHash<QString,QVariant> GConfItemFast::getEntries() const
+{
+ QHash<QString,QVariant> children;
+
+ withClient(client) {
+ QByteArray k = key.toUtf8();
+ GSList *entries = gconf_client_all_entries(client, k.data(), NULL);
+ for (GSList *e = entries; e; e = e->next) {
+ char *key_name = strrchr(((GConfEntry *)e->data)->key, '/');
+ if (!key_name)
+ key_name = ((GConfEntry *)e->data)->key;
+ else
+ key_name++;
+ QString key(convertKey(key_name));
+ QVariant value = convertValue(((GConfEntry *)e->data)->value);
+ gconf_entry_unref((GConfEntry *)e->data);
+ //qDebug()<<"key="<<key<<"value="<<value;
+ children.insert(key, value);
+ }
+ g_slist_free (entries);
+ }
+
+ return children;
+}
+
+
+
+class NetworkProxyFactory : QNetworkProxyFactory {
+public:
+ NetworkProxyFactory() { }
+ QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery());
+};
+
+
+QList<QNetworkProxy> NetworkProxyFactory::queryProxy(const QNetworkProxyQuery &query)
+{
+ ProxyConf proxy_conf;
+
+ QList<QNetworkProxy> result = proxy_conf.flush(query);
+ if (result.isEmpty())
+ result << QNetworkProxy::NoProxy;
+
+ return result;
+}
+
+
+class ProxyConfPrivate {
+private:
+ // proxy values from gconf
+ QString mode;
+ bool use_http_host;
+ QString autoconfig_url;
+ QString http_proxy;
+ quint16 http_port;
+ QList<QVariant> ignore_hosts;
+ QString secure_host;
+ quint16 secure_port;
+ QString ftp_host;
+ quint16 ftp_port;
+ QString socks_host;
+ quint16 socks_port;
+ QString rtsp_host;
+ quint16 rtsp_port;
+
+ bool isHostExcluded(const QString &host);
+
+public:
+ QString prefix;
+ QString http_prefix;
+
+ void readProxyData();
+ QList<QNetworkProxy> flush(const QNetworkProxyQuery &query);
+};
+
+
+static QHash<QString,QVariant> getValues(const QString& prefix)
+{
+ GConfItemFast item(prefix);
+ return item.getEntries();
+}
+
+static QHash<QString,QVariant> getHttpValues(const QString& prefix)
+{
+ GConfItemFast item(prefix);
+ return item.getEntries();
+}
+
+#define GET(var, type) \
+ do { \
+ QVariant v = values.value(#var); \
+ if (v.isValid()) \
+ var = v.to##type (); \
+ } while(0)
+
+#define GET_HTTP(var, name, type) \
+ do { \
+ QVariant v = httpValues.value(#name); \
+ if (v.isValid()) \
+ var = v.to##type (); \
+ } while(0)
+
+
+void ProxyConfPrivate::readProxyData()
+{
+ QHash<QString,QVariant> values = getValues(prefix);
+ QHash<QString,QVariant> httpValues = getHttpValues(http_prefix);
+
+ //qDebug()<<"values="<<values;
+
+ /* Read the proxy settings from /system/proxy* */
+ GET_HTTP(http_proxy, host, String);
+ GET_HTTP(http_port, port, Int);
+ GET_HTTP(ignore_hosts, ignore_hosts, List);
+
+ GET(mode, String);
+ GET(autoconfig_url, String);
+ GET(secure_host, String);
+ GET(secure_port, Int);
+ GET(ftp_host, String);
+ GET(ftp_port, Int);
+ GET(socks_host, String);
+ GET(socks_port, Int);
+ GET(rtsp_host, String);
+ GET(rtsp_port, Int);
+
+ if (http_proxy.isEmpty())
+ use_http_host = false;
+ else
+ use_http_host = true;
+}
+
+
+bool ProxyConfPrivate::isHostExcluded(const QString &host)
+{
+ if (host.isEmpty())
+ return true;
+
+ if (ignore_hosts.isEmpty())
+ return false;
+
+ QHostAddress ipAddress;
+ bool isIpAddress = ipAddress.setAddress(host);
+
+ foreach (QVariant h, ignore_hosts) {
+ QString entry = h.toString();
+ if (isIpAddress && ipAddress.isInSubnet(QHostAddress::parseSubnet(entry))) {
+ return true; // excluded
+ } else {
+ // do wildcard matching
+ QRegExp rx(entry, Qt::CaseInsensitive, QRegExp::Wildcard);
+ if (rx.exactMatch(host))
+ return true;
+ }
+ }
+
+ // host was not excluded
+ return false;
+}
+
+
+QList<QNetworkProxy> ProxyConfPrivate::flush(const QNetworkProxyQuery &query)
+{
+ QList<QNetworkProxy> result;
+
+#if 0
+ qDebug()<<"http_proxy" << http_proxy;
+ qDebug()<<"http_port" << http_port;
+ qDebug()<<"ignore_hosts" << ignore_hosts;
+ qDebug()<<"use_http_host" << use_http_host;
+ qDebug()<<"mode" << mode;
+ qDebug()<<"autoconfig_url" << autoconfig_url;
+ qDebug()<<"secure_host" << secure_host;
+ qDebug()<<"secure_port" << secure_port;
+ qDebug()<<"ftp_host" << ftp_host;
+ qDebug()<<"ftp_port" << ftp_port;
+ qDebug()<<"socks_host" << socks_host;
+ qDebug()<<"socks_port" << socks_port;
+ qDebug()<<"rtsp_host" << rtsp_host;
+ qDebug()<<"rtsp_port" << rtsp_port;
+#endif
+
+ if (isHostExcluded(query.peerHostName()))
+ return result; // no proxy for this host
+
+ if (mode == "auto") {
+ // TODO: pac currently not supported, fix me
+ return result;
+ }
+
+ if (mode == "manual") {
+ bool isHttps = false;
+ QString protocol = query.protocolTag().toLower();
+
+ // try the protocol-specific proxy
+ QNetworkProxy protocolSpecificProxy;
+
+ if (protocol == QLatin1String("ftp")) {
+ if (!ftp_host.isEmpty()) {
+ protocolSpecificProxy.setType(QNetworkProxy::FtpCachingProxy);
+ protocolSpecificProxy.setHostName(ftp_host);
+ protocolSpecificProxy.setPort(ftp_port);
+ }
+ } else if (protocol == QLatin1String("http")) {
+ if (!http_proxy.isEmpty()) {
+ protocolSpecificProxy.setType(QNetworkProxy::HttpProxy);
+ protocolSpecificProxy.setHostName(http_proxy);
+ protocolSpecificProxy.setPort(http_port);
+ }
+ } else if (protocol == QLatin1String("https")) {
+ isHttps = true;
+ if (!secure_host.isEmpty()) {
+ protocolSpecificProxy.setType(QNetworkProxy::HttpProxy);
+ protocolSpecificProxy.setHostName(secure_host);
+ protocolSpecificProxy.setPort(secure_port);
+ }
+ }
+
+ if (protocolSpecificProxy.type() != QNetworkProxy::DefaultProxy)
+ result << protocolSpecificProxy;
+
+
+ if (!socks_host.isEmpty()) {
+ QNetworkProxy proxy;
+ proxy.setType(QNetworkProxy::Socks5Proxy);
+ proxy.setHostName(socks_host);
+ proxy.setPort(socks_port);
+ result << proxy;
+ }
+
+
+ // Add the HTTPS proxy if present (and if we haven't added yet)
+ if (!isHttps) {
+ QNetworkProxy https;
+ if (!secure_host.isEmpty()) {
+ https.setType(QNetworkProxy::HttpProxy);
+ https.setHostName(secure_host);
+ https.setPort(secure_port);
+ }
+
+ if (https.type() != QNetworkProxy::DefaultProxy &&
+ https != protocolSpecificProxy)
+ result << https;
+ }
+ }
+
+ return result;
+}
+
+
+ProxyConf::ProxyConf()
+ : d_ptr(new ProxyConfPrivate)
+{
+ g_type_init();
+ d_ptr->prefix = CONF_PROXY;
+ d_ptr->http_prefix = HTTP_PROXY;
+}
+
+ProxyConf::~ProxyConf()
+{
+ delete d_ptr;
+}
+
+
+QList<QNetworkProxy> ProxyConf::flush(const QNetworkProxyQuery &query)
+{
+ d_ptr->readProxyData();
+ return d_ptr->flush(query);
+}
+
+
+static int refcount = 0;
+static QReadWriteLock lock;
+
+void ProxyConf::update()
+{
+ QWriteLocker locker(&lock);
+ NetworkProxyFactory *factory = new NetworkProxyFactory();
+ QNetworkProxyFactory::setApplicationProxyFactory((QNetworkProxyFactory*)factory);
+ refcount++;
+}
+
+
+void ProxyConf::clear(void)
+{
+ QWriteLocker locker(&lock);
+ refcount--;
+ if (refcount == 0)
+ QNetworkProxyFactory::setApplicationProxyFactory(NULL);
+
+ if (refcount<0)
+ refcount = 0;
+}
+
+
+} // namespace Maemo
diff --git a/src/plugins/bearer/icd/proxyconf.h b/src/plugins/bearer/icd/proxyconf.h
new file mode 100644
index 0000000..884cc5c
--- /dev/null
+++ b/src/plugins/bearer/icd/proxyconf.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef PROXYCONF_H
+#define PROXYCONF_H
+
+#include <QString>
+#include <QNetworkProxy>
+
+namespace Maemo {
+
+class ProxyConfPrivate;
+class ProxyConf {
+private:
+ ProxyConfPrivate *d_ptr;
+
+public:
+ ProxyConf();
+ virtual ~ProxyConf();
+
+ QList<QNetworkProxy> flush(const QNetworkProxyQuery &query = QNetworkProxyQuery()); // read the proxies from db
+
+ /* Note that for each update() call there should be corresponding
+ * clear() call because the ProxyConf class implements a reference
+ * counting mechanism. The factory is removed only when there is
+ * no one using the factory any more.
+ */
+ static void update(void); // this builds QNetworkProxy factory
+ static void clear(void); // this removes QNetworkProxy factory
+};
+
+} // namespace Maemo
+
+#endif
diff --git a/src/plugins/bearer/icd/qicdengine.cpp b/src/plugins/bearer/icd/qicdengine.cpp
index 3264f15..bdf4e2e 100644
--- a/src/plugins/bearer/icd/qicdengine.cpp
+++ b/src/plugins/bearer/icd/qicdengine.cpp
@@ -43,7 +43,7 @@
#include "qnetworksession_impl.h"
#include <wlancond.h>
-#include <libicd-network-wlan-dev.h>
+#include <wlan-utils.h>
#include <iapconf.h>
#include <iapmonitor.h>
@@ -67,6 +67,10 @@ QString IcdNetworkConfigurationPrivate::bearerTypeName() const
return iap_type;
}
+/******************************************************************************/
+/** IapAddTimer specific */
+/******************************************************************************/
+
/* The IapAddTimer is a helper class that makes sure we update
* the configuration only after all db additions to certain
* iap are finished (after a certain timeout)
@@ -162,6 +166,9 @@ void IapAddTimer::del(QString& iap_id)
}
}
+/******************************************************************************/
+/** IAPMonitor specific */
+/******************************************************************************/
class IapMonitor : public Maemo::IAPMonitor
{
@@ -216,6 +223,11 @@ void IapMonitor::iapRemoved(const QString &iap_id)
d->deleteConfiguration(id);
}
+
+/******************************************************************************/
+/** QIcdEngine implementation */
+/******************************************************************************/
+
QIcdEngine::QIcdEngine(QObject *parent)
: QBearerEngine(parent), iapMonitor(0), m_dbusInterface(0),
firstUpdate(true), m_scanGoingOn(false)
diff --git a/src/plugins/bearer/icd/qicdengine.h b/src/plugins/bearer/icd/qicdengine.h
index 0d5ba27..d528f15 100644
--- a/src/plugins/bearer/icd/qicdengine.h
+++ b/src/plugins/bearer/icd/qicdengine.h
@@ -46,7 +46,7 @@
#include <QtCore/qtimer.h>
-#include <maemo_icd.h>
+#include "maemo_icd.h"
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/bearer/icd/qnetworksession_impl.cpp b/src/plugins/bearer/icd/qnetworksession_impl.cpp
index 787cc55..2ed0b88 100644
--- a/src/plugins/bearer/icd/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/icd/qnetworksession_impl.cpp
@@ -60,13 +60,16 @@ QDBusArgument &operator<<(QDBusArgument &argument,
const ICd2DetailsDBusStruct &icd2)
{
argument.beginStructure();
+
argument << icd2.serviceType;
argument << icd2.serviceAttributes;
argument << icd2.setviceId;
argument << icd2.networkType;
argument << icd2.networkAttributes;
argument << icd2.networkId;
+
argument.endStructure();
+
return argument;
}
@@ -74,13 +77,16 @@ const QDBusArgument &operator>>(const QDBusArgument &argument,
ICd2DetailsDBusStruct &icd2)
{
argument.beginStructure();
+
argument >> icd2.serviceType;
argument >> icd2.serviceAttributes;
argument >> icd2.setviceId;
argument >> icd2.networkType;
argument >> icd2.networkAttributes;
argument >> icd2.networkId;
+
argument.endStructure();
+
return argument;
}
@@ -104,9 +110,12 @@ QDBusArgument &operator<<(QDBusArgument &argument,
const ICd2DetailsList &detailsList)
{
argument.beginArray(qMetaTypeId<ICd2DetailsDBusStruct>());
+
for (int i = 0; i < detailsList.count(); ++i)
argument << detailsList[i];
+
argument.endArray();
+
return argument;
}
@@ -144,7 +153,8 @@ void QNetworkSessionPrivateImpl::iapStateChanged(const QString& iapid, uint icd_
void QNetworkSessionPrivateImpl::cleanupSession(void)
{
- QObject::disconnect(q, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(updateProxies(QNetworkSession::State)));
+ QObject::disconnect(q, SIGNAL(stateChanged(QNetworkSession::State)),
+ this, SLOT(updateProxies(QNetworkSession::State)));
}
diff --git a/src/plugins/bearer/icd/wlan-utils.h b/src/plugins/bearer/icd/wlan-utils.h
new file mode 100644
index 0000000..1d9e89d
--- /dev/null
+++ b/src/plugins/bearer/icd/wlan-utils.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef WLAN_UTILS_H
+#define WLAN_UTILS_H
+
+/** Originally taken from: libicd-network-wlan-dev.h*/
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <wlancond.h>
+#include <icd/network_api_defines.h>
+
+/* capability bits inside network attributes var */
+#define NWATTR_WPS_MASK 0x0000F000
+#define NWATTR_ALGORITHM_MASK 0x00000F00
+#define NWATTR_WPA2_MASK 0x00000080
+#define NWATTR_METHOD_MASK 0x00000078
+#define NWATTR_MODE_MASK 0x00000007
+
+#define CAP_LOCALMASK 0x0FFFE008
+
+/* how much to shift between capability and network attributes var */
+#define CAP_SHIFT_WPS 3
+#define CAP_SHIFT_ALGORITHM 20
+#define CAP_SHIFT_WPA2 1
+#define CAP_SHIFT_METHOD 1
+#define CAP_SHIFT_MODE 0
+#define CAP_SHIFT_ALWAYS_ONLINE 26
+
+/* ------------------------------------------------------------------------- */
+/* From combined to capability */
+static inline dbus_uint32_t nwattr2cap(guint nwattrs, dbus_uint32_t *cap)
+{
+ guint oldval = *cap;
+
+ *cap &= CAP_LOCALMASK; /* clear old capabilities */
+ *cap |=
+ ((nwattrs & ICD_NW_ATTR_ALWAYS_ONLINE) >> CAP_SHIFT_ALWAYS_ONLINE) |
+ ((nwattrs & NWATTR_WPS_MASK) >> CAP_SHIFT_WPS) |
+ ((nwattrs & NWATTR_ALGORITHM_MASK) << CAP_SHIFT_ALGORITHM) |
+ ((nwattrs & NWATTR_WPA2_MASK) << CAP_SHIFT_WPA2) |
+ ((nwattrs & NWATTR_METHOD_MASK) << CAP_SHIFT_METHOD) |
+ (nwattrs & NWATTR_MODE_MASK);
+
+ return oldval;
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* From capability to combined */
+static inline guint cap2nwattr(dbus_uint32_t cap, guint *nwattrs)
+{
+ guint oldval = *nwattrs;
+
+ *nwattrs &= ~ICD_NW_ATTR_LOCALMASK; /* clear old capabilities */
+ *nwattrs |=
+#ifdef WLANCOND_WPS_MASK
+ ((cap & WLANCOND_WPS_MASK) << CAP_SHIFT_WPS) |
+#endif
+ ((cap & (WLANCOND_ENCRYPT_ALG_MASK |
+ WLANCOND_ENCRYPT_GROUP_ALG_MASK)) >> CAP_SHIFT_ALGORITHM)|
+ ((cap & WLANCOND_ENCRYPT_WPA2_MASK) >> CAP_SHIFT_WPA2) |
+ ((cap & WLANCOND_ENCRYPT_METHOD_MASK) >> CAP_SHIFT_METHOD) |
+ (cap & WLANCOND_MODE_MASK);
+
+ return oldval;
+}
+
+
+#endif