--- a/qtmobility/src/bearer/qnetworksession_maemo.cpp Fri Apr 16 15:51:22 2010 +0300
+++ b/qtmobility/src/bearer/qnetworksession_maemo.cpp Mon May 03 13:18:40 2010 +0300
@@ -42,280 +42,142 @@
#include <QHash>
#include "qnetworksession_maemo_p.h"
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
#include <maemo_icd.h>
#include <iapconf.h>
#include <proxyconf.h>
-#include <sys/types.h>
#include <ifaddrs.h>
-#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+
+QDBusArgument &operator<<(QDBusArgument &argument,
+ const QtMobility::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;
+}
+
+const QDBusArgument &operator>>(const QDBusArgument &argument,
+ QtMobility::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;
+}
+
+const QDBusArgument &operator>>(const QDBusArgument &argument,
+ QtMobility::ICd2DetailsList &detailsList)
+{
+ argument.beginArray();
+ detailsList.clear();
+
+ while (!argument.atEnd()) {
+ QtMobility::ICd2DetailsDBusStruct element;
+ argument >> element;
+ detailsList.append(element);
+ }
+
+ argument.endArray();
+ return argument;
+}
+
+QDBusArgument &operator<<(QDBusArgument &argument,
+ const QtMobility::ICd2DetailsList &detailsList)
+{
+ argument.beginArray(qMetaTypeId<QtMobility::ICd2DetailsDBusStruct>());
+ for (int i = 0; i < detailsList.count(); ++i)
+ argument << detailsList[i];
+ argument.endArray();
+ return argument;
+}
+
QTM_BEGIN_NAMESPACE
static QHash<QString, QVariant> properties;
static QString get_network_interface();
-static DBusConnection *dbus_connection;
-static DBusHandlerResult signal_handler(DBusConnection *connection,
- DBusMessage *message,
- void *user_data);
-#define ICD_DBUS_MATCH "type='signal'," \
- "interface='" ICD_DBUS_INTERFACE "'," \
- "path='" ICD_DBUS_PATH "'"
-
-
-static inline DBusConnection *get_dbus_conn(DBusError *error)
-{
- DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, error);
-#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "Listening to bus" << dbus_bus_get_unique_name(conn);
-#endif
-
- return conn;
-}
-
-
-/* Helper class that monitors the Icd status messages and
- * can change the IAP status accordingly. This is a singleton.
- */
-class IcdListener : public QObject
+void QNetworkSessionPrivate::iapStateChanged(const QString& iapid, uint icd_connection_state)
{
- Q_OBJECT
-
-public:
- IcdListener() : first_call(true) { }
- friend DBusHandlerResult signal_handler(DBusConnection *connection,
- DBusMessage *message,
- void *user_data);
- void setup(QNetworkSessionPrivate *d);
- void cleanup();
- void cleanupSession(QNetworkSessionPrivate *ptr);
-
- enum IapConnectionStatus {
- /* The IAP was connected */
- CONNECTED = 0,
- /* The IAP was disconnected */
- DISCONNECTED,
- /* The IAP is disconnecting */
- DISCONNECTING,
- /* The IAP has a network address, but is not yet fully connected */
- NETWORK_UP
- };
-
-private:
- void icdSignalReceived(QString&, QString&, QString&);
- bool first_call;
- QHash<QString, QNetworkSessionPrivate* > sessions;
-};
-
-Q_GLOBAL_STATIC(IcdListener, icdListener);
-
-
-static DBusHandlerResult signal_handler(DBusConnection *,
- DBusMessage *message,
- void *user_data)
-{
- if (dbus_message_is_signal(message,
- ICD_DBUS_INTERFACE,
- ICD_STATUS_CHANGED_SIG)) {
-
- IcdListener *icd = (IcdListener *)user_data;
- DBusError error;
- dbus_error_init(&error);
-
- char *iap_id = 0;
- char *network_type = 0;
- char *state = 0;
-
- if (dbus_message_get_args(message, &error,
- DBUS_TYPE_STRING, &iap_id,
- DBUS_TYPE_STRING, &network_type,
- DBUS_TYPE_STRING, &state,
- DBUS_TYPE_INVALID) == FALSE) {
- qWarning() << QString("Failed to parse icd status signal: %1").arg(error.message);
- } else {
- QString _iap_id(iap_id);
- QString _network_type(network_type);
- QString _state(state);
-
- icd->icdSignalReceived(_iap_id, _network_type, _state);
- }
-
- dbus_error_free(&error);
- return DBUS_HANDLER_RESULT_HANDLED;
+ if ((publicConfig.type() == QNetworkConfiguration::UserChoice) && opened) {
+ updateIdentifier(iapid);
}
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-
-void IcdListener::setup(QNetworkSessionPrivate *d)
-{
- if (first_call) {
- // We use the old Icd dbus interface like in ConIC
- DBusError error;
- dbus_error_init(&error);
-
- dbus_connection = get_dbus_conn(&error);
- if (dbus_error_is_set(&error)) {
- qWarning() << "Cannot get dbus connection.";
- dbus_error_free(&error);
- return;
- }
-
- static struct DBusObjectPathVTable icd_vtable;
- icd_vtable.message_function = signal_handler;
-
- dbus_bus_add_match(dbus_connection, ICD_DBUS_MATCH, &error);
- if (dbus_error_is_set(&error)) {
- qWarning() << "Cannot add match" << ICD_DBUS_MATCH;
- dbus_error_free(&error);
- return;
- }
-
- if (dbus_connection_register_object_path(dbus_connection,
- ICD_DBUS_PATH,
- &icd_vtable,
- (void*)this) == FALSE) {
- qWarning() << "Cannot register dbus signal handler, interface"<< ICD_DBUS_INTERFACE << "path" << ICD_DBUS_PATH;
- dbus_error_free(&error);
- return;
- }
-
-#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "Listening" << ICD_STATUS_CHANGED_SIG << "signal from" << ICD_DBUS_SERVICE;
-#endif
- first_call = false;
- dbus_error_free(&error);
- }
-
- QString id = d->activeConfig.identifier();
- if (!sessions.contains(id)) {
- QNetworkSessionPrivate *ptr = d;
- sessions.insert(id, ptr);
+ if (((publicConfig.type() == QNetworkConfiguration::UserChoice) && (activeConfig.d->id == iapid)) ||
+ (publicConfig.d->id == iapid)) {
+ switch (icd_connection_state) {
+ case ICD_STATE_CONNECTING:
+ updateState(QNetworkSession::Connecting);
+ break;
+ case ICD_STATE_CONNECTED:
+ updateState(QNetworkSession::Connected);
+ break;
+ case ICD_STATE_DISCONNECTING:
+ updateState(QNetworkSession::Closing);
+ break;
+ case ICD_STATE_DISCONNECTED:
+ updateState(QNetworkSession::Disconnected);
+ break;
+ default:
+ break;
+ }
}
}
-
-void IcdListener::icdSignalReceived(QString& iap_id,
-#ifdef BEARER_MANAGEMENT_DEBUG
- QString& network_type,
-#else
- QString&,
-#endif
- QString& state)
-{
- if (iap_id == OSSO_IAP_SCAN) // icd sends scan status signals which we will ignore
- return;
-
-#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "Status received:" << iap_id << "type" << network_type << "state" << state;
-#endif
-
- if (!sessions.contains(iap_id)) {
-#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "No session for IAP" << iap_id;
-#endif
- return;
- }
-
- QNetworkSessionPrivate *session = sessions.value(iap_id);
- QNetworkConfiguration ap_conf = session->manager.configurationFromIdentifier(iap_id);
- if (!ap_conf.isValid()) {
-#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "Unknown IAP" << iap_id;
-#endif
- return;
- }
-
- IapConnectionStatus status;
-
- if (state == "IDLE") {
- status = DISCONNECTED;
- } else if (state == "CONNECTED") {
- status = CONNECTED;
- } else if (state == "NETWORKUP") {
- status = NETWORK_UP;
- } else {
- //qDebug() << "Unknown state" << state;
- return;
- }
-
- if (status == DISCONNECTED) {
- if (ap_conf.state() == QNetworkConfiguration::Active) {
- /* The IAP was just disconnected by Icd */
- session->updateState(QNetworkSession::Disconnected);
- } else {
-#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "Got a network disconnect when in state" << ap_conf.state();
-#endif
- }
- } else if (status == CONNECTED) {
- /* The IAP was just connected by Icd */
- session->updateState(QNetworkSession::Connected);
- session->updateIdentifier(iap_id);
-
- if (session->publicConfig.identifier() == OSSO_IAP_ANY) {
-#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "IAP" << iap_id << "connected when connecting to" << OSSO_IAP_ANY;
-#endif
- } else {
-#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "IAP" << iap_id << "connected";
-#endif
- }
- }
-
- return;
-}
-
-
-void IcdListener::cleanup()
-{
- if (!first_call) {
- dbus_bus_remove_match(dbus_connection, ICD_DBUS_MATCH, NULL);
- dbus_connection_unref(dbus_connection);
- }
-}
-
-
-void IcdListener::cleanupSession(QNetworkSessionPrivate *ptr)
-{
- if (ptr->publicConfig.type() == QNetworkConfiguration::UserChoice)
- (void)sessions.take(ptr->activeConfig.identifier());
- else
- (void)sessions.take(ptr->publicConfig.identifier());
-}
-
-
void QNetworkSessionPrivate::cleanupSession(void)
{
- icdListener()->cleanupSession(this);
-
QObject::disconnect(q, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(updateProxies(QNetworkSession::State)));
}
void QNetworkSessionPrivate::updateState(QNetworkSession::State newState)
{
- if( newState != state) {
- state = newState;
-
- if (state == QNetworkSession::Disconnected) {
+ if (newState != state) {
+ if (newState == QNetworkSession::Disconnected) {
+ if (isOpen) {
+ // The Session was aborted by the user or system
+ lastError = QNetworkSession::SessionAbortedError;
+ emit q->error(lastError);
+ emit q->closed();
+ }
+ if (m_stopTimer.isActive()) {
+ // Session was closed by calling stop()
+ m_stopTimer.stop();
+ }
isOpen = false;
+ opened = false;
currentNetworkInterface.clear();
- if (publicConfig.type() == QNetworkConfiguration::UserChoice)
- activeConfig.d->state = QNetworkConfiguration::Defined;
- publicConfig.d->state = QNetworkConfiguration::Defined;
-
- } else if (state == QNetworkSession::Connected) {
- isOpen = true;
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
+ copyConfig(publicConfig, activeConfig);
+ activeConfig.d->state = QNetworkConfiguration::Defined;
+ } else {
+ if (!activeConfig.isValid()) {
+ // Active configuration (IAP) was removed from system
+ // => Connection was disconnected and configuration became
+ // invalid
+ // => Also Session state must be changed to invalid
+ newState = QNetworkSession::Invalid;
+ }
+ }
+ } else if (newState == QNetworkSession::Connected) {
+ if (opened) {
+ isOpen = true;
+ }
if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
activeConfig.d->state = QNetworkConfiguration::Active;
activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint;
@@ -323,12 +185,15 @@
publicConfig.d->state = QNetworkConfiguration::Active;
}
- emit q->stateChanged(newState);
+ if (newState != state) {
+ state = newState;
+ emit q->stateChanged(newState);
+ }
}
}
-void QNetworkSessionPrivate::updateIdentifier(QString &newId)
+void QNetworkSessionPrivate::updateIdentifier(const QString &newId)
{
if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
activeConfig.d->network_attrs |= ICD_NW_ATTR_IAPNAME;
@@ -357,7 +222,7 @@
return 0;
}
- foreach (Maemo::IcdStatisticsResult res, stats_results) {
+ foreach (const Maemo::IcdStatisticsResult &res, stats_results) {
if (res.params.network_attrs & ICD_NW_ATTR_IAPNAME) {
/* network_id is the IAP UUID */
if (QString(res.params.network_id.data()) == activeConfig.identifier()) {
@@ -433,9 +298,6 @@
*/
void QNetworkSessionPrivate::syncStateWithInterface()
{
- /* Start to listen Icd status messages. */
- icdListener()->setup(this);
-
/* Initially we are not active although the configuration might be in
* connected state.
*/
@@ -447,10 +309,10 @@
if (publicConfig.d.data()) {
QNetworkConfigurationManagerPrivate* mgr = (QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager;
if (mgr) {
- QObject::connect(mgr, SIGNAL(configurationChanged(QNetworkConfiguration)),
- this, SLOT(configurationChanged(QNetworkConfiguration)));
+ connect(mgr, SIGNAL(iapStateChanged(const QString&, uint)),
+ this, SLOT(iapStateChanged(const QString&, uint)));
} else {
- qWarning()<<"Manager object not set when trying to connect configurationChanged signal. Your configuration object is not correctly setup, did you remember to call manager.updateConfigurations() before creating session object?";
+ qWarning()<<"Manager object not set when trying to connect iapStateChanged signal. Your configuration object is not correctly setup, did you remember to call manager.updateConfigurations() before creating session object?";
state = QNetworkSession::Invalid;
lastError = QNetworkSession::UnknownSessionError;
return;
@@ -464,14 +326,14 @@
switch (publicConfig.type()) {
case QNetworkConfiguration::InternetAccessPoint:
- activeConfig = publicConfig;
+ activeConfig = publicConfig;
break;
case QNetworkConfiguration::ServiceNetwork:
- serviceConfig = publicConfig;
+ serviceConfig = publicConfig;
break;
case QNetworkConfiguration::UserChoice:
// active config will contain correct data after open() has succeeded
- copyConfig(publicConfig, activeConfig);
+ copyConfig(publicConfig, activeConfig);
/* We create new configuration that holds the actual configuration
* returned by icd. This way publicConfig still contains the
@@ -505,7 +367,6 @@
* supports only one connection anyway.
*/
if (icd.state(state_results) && !state_results.isEmpty()) {
-
/* If we did not get full state back, then we are not
* connected and can skip the next part.
*/
@@ -518,46 +379,44 @@
*/
if (publicConfig.type() == QNetworkConfiguration::UserChoice ||
publicConfig.d->id == state_results.first().params.network_id) {
-
switch (state_results.first().state) {
case ICD_STATE_DISCONNECTED:
- state = QNetworkSession::Disconnected;
+ state = QNetworkSession::Disconnected;
if (activeConfig.d.data())
activeConfig.d->isValid = true;
break;
case ICD_STATE_CONNECTING:
- state = QNetworkSession::Connecting;
+ state = QNetworkSession::Connecting;
if (activeConfig.d.data())
activeConfig.d->isValid = true;
break;
case ICD_STATE_CONNECTED:
{
- if (!state_results.first().error.isEmpty())
+ if (!state_results.first().error.isEmpty())
break;
-
+
const QString id = state_results.first().params.network_id;
- QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager;
+ QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager;
if (mgr->accessPointConfigurations.contains(id)) {
//we don't want the copied data if the config is already known by the manager
//just reuse it so that existing references to the old data get the same update
- QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = mgr->accessPointConfigurations.value(activeConfig.d->id);
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = mgr->accessPointConfigurations.value(id);
activeConfig.d = priv;
}
-
state = QNetworkSession::Connected;
- activeConfig.d->network_id = state_results.first().params.network_id;
- activeConfig.d->id = activeConfig.d->network_id;
- activeConfig.d->network_attrs = state_results.first().params.network_attrs;
- activeConfig.d->iap_type = state_results.first().params.network_type;
- activeConfig.d->service_type = state_results.first().params.service_type;
- activeConfig.d->service_id = state_results.first().params.service_id;
- activeConfig.d->service_attrs = state_results.first().params.service_attrs;
- activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint;
- activeConfig.d->state = QNetworkConfiguration::Active;
- activeConfig.d->isValid = true;
- currentNetworkInterface = get_network_interface();
+ activeConfig.d->network_id = state_results.first().params.network_id;
+ activeConfig.d->id = activeConfig.d->network_id;
+ activeConfig.d->network_attrs = state_results.first().params.network_attrs;
+ activeConfig.d->iap_type = state_results.first().params.network_type;
+ activeConfig.d->service_type = state_results.first().params.service_type;
+ activeConfig.d->service_id = state_results.first().params.service_id;
+ activeConfig.d->service_attrs = state_results.first().params.service_attrs;
+ activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint;
+ activeConfig.d->state = QNetworkConfiguration::Active;
+ activeConfig.d->isValid = true;
+ currentNetworkInterface = get_network_interface();
Maemo::IAPConf iap_name(activeConfig.d->id);
QString name_value = iap_name.value("name").toString();
@@ -566,7 +425,6 @@
else
activeConfig.d->name = activeConfig.d->id;
-
// Add the new active configuration to manager or update the old config
mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager;
if (!(mgr->accessPointConfigurations.contains(activeConfig.d->id))) {
@@ -581,23 +439,17 @@
//qDebug()<<"New configuration"<<activeConfig.d->id<<"added to manager in sync";
#endif
- } else {
- mgr->configurationChanged((QNetworkConfigurationPrivate*)(activeConfig.d.data()));
-#ifdef BEARER_MANAGEMENT_DEBUG
- //qDebug()<<"Existing configuration"<<activeConfig.d->id<<"updated in manager in sync";
-#endif
- }
-
+ }
}
break;
case ICD_STATE_DISCONNECTING:
- state = QNetworkSession::Closing;
+ state = QNetworkSession::Closing;
if (activeConfig.d.data())
activeConfig.d->isValid = true;
break;
default:
- break;
+ break;
}
}
} else {
@@ -686,7 +538,6 @@
state = QNetworkSession::NotAvailable;
} else if ((activeConfig.state() & QNetworkConfiguration::Undefined) == QNetworkConfiguration::Undefined) {
state = QNetworkSession::NotAvailable;
- clearConfiguration(activeConfig);
}
bool oldActive = isOpen;
@@ -701,7 +552,7 @@
if (oldState != state) {
emit q->stateChanged(state);
- if (state == QNetworkSession::Disconnected) {
+ if (state == QNetworkSession::Disconnected && oldActive) {
#ifdef BEARER_MANAGEMENT_DEBUG
//qDebug()<<"session aborted error emitted for"<<activeConfig.identifier();
#endif
@@ -715,16 +566,6 @@
#endif
}
-
-void QNetworkSessionPrivate::configurationChanged(const QNetworkConfiguration &config)
-{
- if (serviceConfig.isValid() && (config == serviceConfig || config == activeConfig))
- updateStateFromServiceNetwork();
- else if (config == activeConfig)
- updateStateFromActiveConfig();
-}
-
-
static QString get_network_interface()
{
Maemo::Icd icd;
@@ -761,14 +602,16 @@
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
- family = ifa->ifa_addr->sa_family;
- if (family != AF_INET) {
- continue; /* Currently only IPv4 is supported by icd dbus interface */
- }
- if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == addr.s_addr) {
- iface = QString(ifa->ifa_name);
- break;
- }
+ if (ifa->ifa_addr) {
+ family = ifa->ifa_addr->sa_family;
+ if (family != AF_INET) {
+ continue; /* Currently only IPv4 is supported by icd dbus interface */
+ }
+ if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == addr.s_addr) {
+ iface = QString(ifa->ifa_name);
+ break;
+ }
+ }
}
freeifaddrs(ifaddr);
@@ -778,11 +621,18 @@
void QNetworkSessionPrivate::open()
{
+ if (m_stopTimer.isActive()) {
+ m_stopTimer.stop();
+ }
+ if (!publicConfig.isValid()) {
+ lastError = QNetworkSession::InvalidConfigurationError;
+ emit q->error(lastError);
+ return;
+ }
if (serviceConfig.isValid()) {
lastError = QNetworkSession::OperationNotSupportedError;
emit q->error(lastError);
} else if (!isOpen) {
-
if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
/* Caller is trying to connect to default IAP.
* At this time we will not know the IAP details so we just
@@ -810,219 +660,206 @@
if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) {
state = QNetworkSession::Connecting;
emit q->stateChanged(state);
-
- QTimer::singleShot(0, this, SLOT(do_open()));
- return;
+ QTimer::singleShot(0, this, SLOT(do_open()));
+ return;
}
-
isOpen = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active;
if (isOpen)
emit quitPendingWaitsForOpened();
} else {
- /* We seem to be active so inform caller */
- emit quitPendingWaitsForOpened();
+ /* We seem to be active so inform caller */
+ emit quitPendingWaitsForOpened();
}
}
-
void QNetworkSessionPrivate::do_open()
{
icd_connection_flags flags = connectFlags;
- bool st;
- QString result;
QString iap = publicConfig.identifier();
if (state == QNetworkSession::Connected) {
#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "Already connected to" << activeConfig.identifier();
+ qDebug() << "Already connected to" << activeConfig.identifier();
#endif
emit q->stateChanged(QNetworkSession::Connected);
- emit quitPendingWaitsForOpened();
+ emit quitPendingWaitsForOpened();
return;
}
- Maemo::IcdConnectResult connect_result;
- Maemo::Icd icd(ICD_LONG_CONNECT_TIMEOUT);
- QNetworkConfiguration config;
if (publicConfig.type() == QNetworkConfiguration::UserChoice)
- config = activeConfig;
+ config = activeConfig;
else
- config = publicConfig;
+ config = publicConfig;
if (iap == OSSO_IAP_ANY) {
#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "connecting to default IAP" << iap;
+ qDebug() << "connecting to default IAP" << iap;
#endif
- st = icd.connect(flags, connect_result);
-
+ m_connectRequestTimer.start(ICD_LONG_CONNECT_TIMEOUT);
+ m_dbusInterface->asyncCall(ICD_DBUS_API_CONNECT_REQ, (uint)flags); // Return value ignored
+ m_asynchCallActive = true;
} else {
-
- QList<Maemo::ConnectParams> params;
- Maemo::ConnectParams param;
- param.connect.service_type = config.d->service_type;
- param.connect.service_attrs = config.d->service_attrs;
- param.connect.service_id = config.d->service_id;
- param.connect.network_type = config.d->iap_type;
- param.connect.network_attrs = config.d->network_attrs;
- if (config.d->network_attrs & ICD_NW_ATTR_IAPNAME)
- param.connect.network_id = QByteArray(iap.toLatin1());
- else
- param.connect.network_id = config.d->network_id;
- params.append(param);
+ ICd2DetailsDBusStruct icd2;
+ icd2.serviceType = config.d->service_type;
+ icd2.serviceAttributes = config.d->service_attrs;
+ icd2.setviceId = config.d->service_id;
+ icd2.networkType = config.d->iap_type;
+ icd2.networkAttributes = config.d->network_attrs;
+ if (config.d->network_attrs & ICD_NW_ATTR_IAPNAME) {
+ icd2.networkId = QByteArray(iap.toLatin1());
+ } else {
+ icd2.networkId = config.d->network_id;
+ }
#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug("connecting to %s/%s/0x%x/%s/0x%x/%s",
- param.connect.network_id.data(),
- param.connect.network_type.toAscii().constData(),
- param.connect.network_attrs,
- param.connect.service_type.toAscii().constData(),
- param.connect.service_attrs,
- param.connect.service_id.toAscii().constData());
-#endif
- st = icd.connect(flags, params, connect_result);
- }
-
- if (st) {
- result = connect_result.connect.network_id.data();
- QString connected_iap = result;
-
- if (connected_iap.isEmpty()) {
-#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "connect to"<< iap << "failed, result is empty";
-#endif
- updateState(QNetworkSession::Disconnected);
- emit q->error(QNetworkSession::InvalidConfigurationError);
- if (publicConfig.type() == QNetworkConfiguration::UserChoice)
- cleanupAnyConfiguration();
- return;
- }
-
- /* If the user tried to connect to some specific connection (foo)
- * and we were already connected to some other connection (bar),
- * then we cannot activate this session although icd has a valid
- * connection to somewhere.
- */
- if ((publicConfig.type() != QNetworkConfiguration::UserChoice) &&
- (connected_iap != config.identifier())) {
- updateState(QNetworkSession::Disconnected);
- emit q->error(QNetworkSession::InvalidConfigurationError);
- return;
- }
-
-
- /* Did we connect to non saved IAP? */
- if (!(config.d->network_attrs & ICD_NW_ATTR_IAPNAME)) {
- /* Because the connection succeeded, the IAP is now known.
- */
- config.d->network_attrs |= ICD_NW_ATTR_IAPNAME;
- config.d->id = connected_iap;
- }
-
- /* User might have changed the IAP name when a new IAP was saved */
- Maemo::IAPConf iap_name(config.d->id);
- QString name = iap_name.value("name").toString();
- if (!name.isEmpty())
- config.d->name = name;
-
- config.d->iap_type = connect_result.connect.network_type;
-
- config.d->isValid = true;
- config.d->state = QNetworkConfiguration::Active;
- config.d->type = QNetworkConfiguration::InternetAccessPoint;
-
- startTime = QDateTime::currentDateTime();
- updateState(QNetworkSession::Connected);
-
- currentNetworkInterface = get_network_interface();
-
-#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "connected to" << result << config.d->name << "at" << currentNetworkInterface;
+ qDebug("connecting to %s/%s/0x%x/%s/0x%x/%s",
+ icd2.networkId.data(),
+ icd2.networkType.toAscii().constData(),
+ icd2.networkAttributes,
+ icd2.serviceType.toAscii().constData(),
+ icd2.serviceAttributes,
+ icd2.setviceId.toAscii().constData());
#endif
- /* We first check if the configuration already exists in the manager
- * and if it is not found there, we then insert it. Note that this
- * is only done for user choice config only because it can be missing
- * from config manager list.
- */
-
- if (publicConfig.d->type == QNetworkConfiguration::UserChoice) {
-
-#ifdef BEARER_MANAGEMENT_DEBUG
-#if 0
- QList<QNetworkConfiguration> configs;
- QNetworkConfigurationManagerPrivate *conPriv = (QNetworkConfigurationManagerPrivate*)config.d.data()->manager;
- QList<QString> cpsIdents = conPriv->accessPointConfigurations.keys();
- foreach( QString ii, cpsIdents) {
- QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> p =
- conPriv->accessPointConfigurations.value(ii);
- QNetworkConfiguration pt;
- pt.d = conPriv->accessPointConfigurations.value(ii);
- configs << pt;
- }
-
- int all = configs.count();
- qDebug() << "All configurations:" << all;
- foreach(QNetworkConfiguration p, configs) {
- qDebug() << p.name() <<": isvalid->" <<p.isValid() << " type->"<< p.type() <<
- " roaming->" << p.isRoamingAvailable() << "identifier->" << p.identifier() <<
- " purpose->" << p.purpose() << " state->" << p.state();
- }
-#endif
-#endif
-
- QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)config.d.data()->manager;
- if (!mgr->accessPointConfigurations.contains(result)) {
- QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = config.d;
- mgr->accessPointConfigurations.insert(result, ptr);
-
- QNetworkConfiguration item;
- item.d = ptr;
- emit mgr->configurationAdded(item);
-
-#ifdef BEARER_MANAGEMENT_DEBUG
- //qDebug()<<"New configuration"<<result<<"added to manager in open";
-#endif
-
- } else {
- QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = mgr->accessPointConfigurations.value(result);
- QNetworkConfiguration reference;
- reference.d = priv;
- copyConfig(config, reference, false);
- config = reference;
- activeConfig = reference;
- mgr->configurationChanged((QNetworkConfigurationPrivate*)(config.d.data()));
-
-#ifdef BEARER_MANAGEMENT_DEBUG
- //qDebug()<<"Existing configuration"<<result<<"updated in manager in open";
-#endif
- }
- }
-
- emit quitPendingWaitsForOpened();
-
- } else {
-#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "connect to"<< iap << "failed, status:" << connect_result.status;
-#endif
- updateState(QNetworkSession::Disconnected);
- if (publicConfig.type() == QNetworkConfiguration::UserChoice)
- cleanupAnyConfiguration();
- emit q->error(QNetworkSession::UnknownSessionError);
+ ICd2DetailsList paramArray;
+ paramArray.append(icd2);
+ m_connectRequestTimer.start(ICD_LONG_CONNECT_TIMEOUT);
+ m_dbusInterface->asyncCall(ICD_DBUS_API_CONNECT_REQ, (uint)flags, QVariant::fromValue(paramArray)); // Return value ignored
+ m_asynchCallActive = true;
}
}
+ void QNetworkSessionPrivate::stateChange(const QDBusMessage& rep)
+{
+ if (m_asynchCallActive == true) {
+ if (m_connectRequestTimer.isActive())
+ m_connectRequestTimer.stop();
+ m_asynchCallActive = false;
-void QNetworkSessionPrivate::cleanupAnyConfiguration()
-{
+ QString result = rep.arguments().at(5).toString(); // network id or empty string
+ QString connected_iap = result;
+ if (connected_iap.isEmpty()) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "connect to"<< publicConfig.identifier() << "failed, result is empty";
+#endif
+ updateState(QNetworkSession::Disconnected);
+ emit q->error(QNetworkSession::InvalidConfigurationError);
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice)
+ copyConfig(publicConfig, activeConfig);
+ return;
+ }
+
+ /* If the user tried to connect to some specific connection (foo)
+ * and we were already connected to some other connection (bar),
+ * then we cannot activate this session although icd has a valid
+ * connection to somewhere.
+ */
+ if ((publicConfig.type() != QNetworkConfiguration::UserChoice) &&
+ (connected_iap != config.identifier())) {
+ updateState(QNetworkSession::Disconnected);
+ emit q->error(QNetworkSession::InvalidConfigurationError);
+ return;
+ }
+
+ /* Did we connect to non saved IAP? */
+ if (!(config.d->network_attrs & ICD_NW_ATTR_IAPNAME)) {
+ /* Because the connection succeeded, the IAP is now known.
+ */
+ config.d->network_attrs |= ICD_NW_ATTR_IAPNAME;
+ config.d->id = connected_iap;
+ }
+
+ /* User might have changed the IAP name when a new IAP was saved */
+ Maemo::IAPConf iap_name(config.d->id);
+ QString name = iap_name.value("name").toString();
+ if (!name.isEmpty())
+ config.d->name = name;
+
+ config.d->iap_type = rep.arguments().at(3).toString(); // connect_result.connect.network_type;
+ config.d->isValid = true;
+ config.d->state = QNetworkConfiguration::Active;
+ config.d->type = QNetworkConfiguration::InternetAccessPoint;
+
+ startTime = QDateTime::currentDateTime();
+ updateState(QNetworkSession::Connected);
+ //currentNetworkInterface = get_network_interface();
#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug()<<"Removing configuration created for" << activeConfig.d->id;
+ //qDebug() << "connected to" << result << config.d->name << "at" << currentNetworkInterface;
+#endif
+
+ /* We first check if the configuration already exists in the manager
+ * and if it is not found there, we then insert it. Note that this
+ * is only done for user choice config only because it can be missing
+ * from config manager list.
+ */
+ if (publicConfig.d->type == QNetworkConfiguration::UserChoice) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+#if 0
+ QList<QNetworkConfiguration> configs;
+ QNetworkConfigurationManagerPrivate *conPriv = (QNetworkConfigurationManagerPrivate*)config.d.data()->manager;
+ QList<QString> cpsIdents = conPriv->accessPointConfigurations.keys();
+ foreach( QString ii, cpsIdents) {
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> p =
+ conPriv->accessPointConfigurations.value(ii);
+ QNetworkConfiguration pt;
+ pt.d = conPriv->accessPointConfigurations.value(ii);
+ configs << pt;
+ }
+
+ int all = configs.count();
+ qDebug() << "All configurations:" << all;
+ foreach(QNetworkConfiguration p, configs) {
+ qDebug() << p.name() <<": isvalid->" <<p.isValid() << " type->"<< p.type() <<
+ " roaming->" << p.isRoamingAvailable() << "identifier->" << p.identifier() <<
+ " purpose->" << p.purpose() << " state->" << p.state();
+ }
+#endif
#endif
- activeConfig = publicConfig;
+ QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager;
+ if (!mgr->accessPointConfigurations.contains(result)) {
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = config.d;
+ mgr->accessPointConfigurations.insert(result, ptr);
+
+ QNetworkConfiguration item;
+ item.d = ptr;
+ emit mgr->configurationAdded(item);
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug()<<"New configuration"<<result<<"added to manager in open";
+#endif
+
+ } else {
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = mgr->accessPointConfigurations.value(result);
+ QNetworkConfiguration reference;
+ reference.d = priv;
+ copyConfig(config, reference, false);
+ reference.d.data()->id = result; // Note: Id was not copied in copyConfig() function
+ config = reference;
+ activeConfig = reference;
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug()<<"Existing configuration"<<result<<"updated in manager in open";
+#endif
+ }
+ }
+
+ emit quitPendingWaitsForOpened();
+ }
}
+void QNetworkSessionPrivate::connectTimeout()
+{
+ updateState(QNetworkSession::Disconnected);
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice)
+ copyConfig(publicConfig, activeConfig);
+ emit q->error(QNetworkSession::UnknownSessionError);
+}
void QNetworkSessionPrivate::close()
{
+ if (m_connectRequestTimer.isActive())
+ m_connectRequestTimer.stop();
+
if (serviceConfig.isValid()) {
lastError = QNetworkSession::OperationNotSupportedError;
emit q->error(lastError);
@@ -1036,33 +873,37 @@
void QNetworkSessionPrivate::stop()
{
+ if (m_connectRequestTimer.isActive())
+ m_connectRequestTimer.stop();
+
if (serviceConfig.isValid()) {
lastError = QNetworkSession::OperationNotSupportedError;
emit q->error(lastError);
} else {
if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
- state = QNetworkSession::Closing;
- emit q->stateChanged(state);
-
- Maemo::Icd icd;
+ if (!m_stopTimer.isActive()) {
+ Maemo::Icd icd;
#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "stopping session" << publicConfig.identifier();
+ qDebug() << "stopping session" << publicConfig.identifier();
#endif
- icd.disconnect(ICD_CONNECTION_FLAG_APPLICATION_EVENT);
- startTime = QDateTime();
+ state = QNetworkSession::Closing;
+ emit q->stateChanged(state);
+
+ opened = false;
+ isOpen = false;
- /* Note that the state will go disconnected in
- * updateStateFromActiveConfig() which gets called after
- * configurationChanged is emitted (below).
- */
+ icd.disconnect(ICD_CONNECTION_FLAG_APPLICATION_EVENT);
+ startTime = QDateTime();
- activeConfig.d->state = QNetworkConfiguration::Discovered;
- QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager;
- mgr->configurationChanged((QNetworkConfigurationPrivate*)activeConfig.d.data());
+ /* Note: Session state will change to disconnected
+ * as soon as QNetworkConfigurationManager sends
+ * corresponding iapStateChanged signal.
+ */
- opened = false;
- isOpen = false;
-
+ // Make sure that this Session will send closed signal
+ // even though ICD connection will not ever get closed
+ m_stopTimer.start(ICD_SHORT_CONNECT_TIMEOUT); // 10 seconds wait
+ }
} else {
opened = false;
isOpen = false;
@@ -1071,6 +912,14 @@
}
}
+void QNetworkSessionPrivate::finishStopBySendingClosedSignal()
+{
+ if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ state = QNetworkSession::Connected;
+ emit q->stateChanged(state);
+ }
+ emit q->closed();
+}
void QNetworkSessionPrivate::migrate()
{
@@ -1186,7 +1035,6 @@
}
-#include "qnetworksession_maemo.moc"
#include "moc_qnetworksession_maemo_p.cpp"
QTM_END_NAMESPACE