qtmobility/src/bearer/qnetworksession_maemo.cpp
changeset 4 90517678cc4f
parent 0 cfcbf08528c4
child 11 06b8e2af4411
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include <QHash>
    42 #include <QHash>
    43 
    43 
    44 #include "qnetworksession_maemo_p.h"
    44 #include "qnetworksession_maemo_p.h"
    45 #include <dbus/dbus.h>
       
    46 #include <dbus/dbus-glib-lowlevel.h>
       
    47 
    45 
    48 #include <maemo_icd.h>
    46 #include <maemo_icd.h>
    49 #include <iapconf.h>
    47 #include <iapconf.h>
    50 #include <proxyconf.h>
    48 #include <proxyconf.h>
    51 
    49 
    52 #include <sys/types.h>
       
    53 #include <ifaddrs.h>
    50 #include <ifaddrs.h>
    54 #include <sys/socket.h>
       
    55 #include <netinet/in.h>
    51 #include <netinet/in.h>
    56 #include <arpa/inet.h>
    52 #include <arpa/inet.h>
    57 
    53 
       
    54 
       
    55 QDBusArgument &operator<<(QDBusArgument &argument,
       
    56                           const QtMobility::ICd2DetailsDBusStruct &icd2)
       
    57 {
       
    58     argument.beginStructure();
       
    59     argument << icd2.serviceType;
       
    60     argument << icd2.serviceAttributes;
       
    61     argument << icd2.setviceId;
       
    62     argument << icd2.networkType;
       
    63     argument << icd2.networkAttributes;
       
    64     argument << icd2.networkId;
       
    65     argument.endStructure();
       
    66     return argument;
       
    67 }
       
    68 
       
    69 const QDBusArgument &operator>>(const QDBusArgument &argument,
       
    70                                 QtMobility::ICd2DetailsDBusStruct &icd2)
       
    71 {
       
    72     argument.beginStructure();
       
    73     argument >> icd2.serviceType;
       
    74     argument >> icd2.serviceAttributes;
       
    75     argument >> icd2.setviceId;
       
    76     argument >> icd2.networkType;
       
    77     argument >> icd2.networkAttributes;
       
    78     argument >> icd2.networkId;
       
    79     argument.endStructure();
       
    80     return argument;
       
    81 }
       
    82 
       
    83 const QDBusArgument &operator>>(const QDBusArgument &argument,
       
    84                                 QtMobility::ICd2DetailsList &detailsList)
       
    85 {
       
    86      argument.beginArray();
       
    87      detailsList.clear();
       
    88 
       
    89      while (!argument.atEnd()) {
       
    90          QtMobility::ICd2DetailsDBusStruct element;
       
    91          argument >> element;
       
    92          detailsList.append(element);
       
    93      }
       
    94 
       
    95      argument.endArray();
       
    96      return argument;
       
    97 }
       
    98 
       
    99 QDBusArgument &operator<<(QDBusArgument &argument,
       
   100                           const QtMobility::ICd2DetailsList &detailsList)
       
   101 {
       
   102      argument.beginArray(qMetaTypeId<QtMobility::ICd2DetailsDBusStruct>());
       
   103      for (int i = 0; i < detailsList.count(); ++i)
       
   104          argument << detailsList[i];
       
   105      argument.endArray();
       
   106      return argument;
       
   107 }
       
   108 
    58 QTM_BEGIN_NAMESPACE
   109 QTM_BEGIN_NAMESPACE
    59 
   110 
    60 static QHash<QString, QVariant> properties;
   111 static QHash<QString, QVariant> properties;
    61 
   112 
    62 static QString get_network_interface();
   113 static QString get_network_interface();
    63 static DBusConnection *dbus_connection;
   114 
    64 static DBusHandlerResult signal_handler(DBusConnection *connection,
   115 void QNetworkSessionPrivate::iapStateChanged(const QString& iapid, uint icd_connection_state)
    65 					DBusMessage *message,
   116 {
    66 					void *user_data);
   117     if ((publicConfig.type() == QNetworkConfiguration::UserChoice) && opened) {
    67 
   118         updateIdentifier(iapid);
    68 #define ICD_DBUS_MATCH		"type='signal'," \
   119     }
    69 				"interface='" ICD_DBUS_INTERFACE "'," \
   120 
    70 				"path='" ICD_DBUS_PATH "'"
   121     if (((publicConfig.type() == QNetworkConfiguration::UserChoice) && (activeConfig.d->id == iapid)) ||
    71 
   122         (publicConfig.d->id == iapid)) {
    72 
   123         switch (icd_connection_state) {
    73 static inline DBusConnection *get_dbus_conn(DBusError *error)
   124         case ICD_STATE_CONNECTING:
    74 {
   125             updateState(QNetworkSession::Connecting);
    75     DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, error);
   126             break;
    76 #ifdef BEARER_MANAGEMENT_DEBUG
   127         case ICD_STATE_CONNECTED:
    77     qDebug() << "Listening to bus" << dbus_bus_get_unique_name(conn);
   128             updateState(QNetworkSession::Connected);
    78 #endif
   129             break;
    79 
   130         case ICD_STATE_DISCONNECTING:
    80     return conn;
   131             updateState(QNetworkSession::Closing);
    81 }
   132             break;
    82 
   133         case ICD_STATE_DISCONNECTED:
    83 
   134             updateState(QNetworkSession::Disconnected);
    84 /* Helper class that monitors the Icd status messages and
   135             break;
    85  * can change the IAP status accordingly. This is a singleton.
   136         default:
    86  */
   137             break;
    87 class IcdListener : public QObject
   138         }
    88 {
   139     }
    89     Q_OBJECT
   140 }
    90 
       
    91 public:
       
    92     IcdListener() : first_call(true) { }
       
    93     friend DBusHandlerResult signal_handler(DBusConnection *connection,
       
    94 					    DBusMessage *message,
       
    95 					    void *user_data);
       
    96     void setup(QNetworkSessionPrivate *d);
       
    97     void cleanup();
       
    98     void cleanupSession(QNetworkSessionPrivate *ptr);
       
    99 
       
   100     enum IapConnectionStatus {
       
   101 	/* The IAP was connected */
       
   102 	CONNECTED = 0,
       
   103 	/* The IAP was disconnected */
       
   104 	DISCONNECTED,
       
   105 	/* The IAP is disconnecting */
       
   106 	DISCONNECTING,
       
   107 	/* The IAP has a network address, but is not yet fully connected */
       
   108 	NETWORK_UP
       
   109     };
       
   110 
       
   111 private:
       
   112     void icdSignalReceived(QString&, QString&, QString&);
       
   113     bool first_call;
       
   114     QHash<QString, QNetworkSessionPrivate* > sessions;
       
   115 };
       
   116 
       
   117 Q_GLOBAL_STATIC(IcdListener, icdListener);
       
   118  
       
   119 
       
   120 static DBusHandlerResult signal_handler(DBusConnection *,
       
   121 					DBusMessage *message,
       
   122 					void *user_data)
       
   123 {
       
   124     if (dbus_message_is_signal(message,
       
   125 				ICD_DBUS_INTERFACE,
       
   126 				ICD_STATUS_CHANGED_SIG)) {
       
   127 
       
   128 	IcdListener *icd = (IcdListener *)user_data;
       
   129 	DBusError error;
       
   130 	dbus_error_init(&error);
       
   131 
       
   132 	char *iap_id = 0;
       
   133 	char *network_type = 0;
       
   134 	char *state = 0;
       
   135 
       
   136 	if (dbus_message_get_args(message, &error,
       
   137 				    DBUS_TYPE_STRING, &iap_id,
       
   138 				    DBUS_TYPE_STRING, &network_type,
       
   139 				    DBUS_TYPE_STRING, &state,
       
   140 				    DBUS_TYPE_INVALID) == FALSE) {
       
   141 	    qWarning() << QString("Failed to parse icd status signal: %1").arg(error.message);
       
   142         } else {
       
   143 	    QString _iap_id(iap_id);
       
   144 	    QString _network_type(network_type);
       
   145 	    QString _state(state);
       
   146 
       
   147 	    icd->icdSignalReceived(_iap_id, _network_type, _state);
       
   148 	}
       
   149 
       
   150 	dbus_error_free(&error);
       
   151         return DBUS_HANDLER_RESULT_HANDLED;
       
   152     }
       
   153 
       
   154     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
       
   155 }
       
   156 
       
   157 
       
   158 void IcdListener::setup(QNetworkSessionPrivate *d)
       
   159 {
       
   160     if (first_call) {
       
   161 	// We use the old Icd dbus interface like in ConIC
       
   162 	DBusError error;
       
   163 	dbus_error_init(&error);
       
   164 
       
   165 	dbus_connection = get_dbus_conn(&error);
       
   166 	if (dbus_error_is_set(&error)) {
       
   167 	    qWarning() << "Cannot get dbus connection.";
       
   168 	    dbus_error_free(&error);
       
   169 	    return;
       
   170 	}
       
   171 
       
   172 	static struct DBusObjectPathVTable icd_vtable;
       
   173 	icd_vtable.message_function = signal_handler;
       
   174 
       
   175 	dbus_bus_add_match(dbus_connection, ICD_DBUS_MATCH, &error);
       
   176 	if (dbus_error_is_set(&error)) {
       
   177 	    qWarning() << "Cannot add match" << ICD_DBUS_MATCH;
       
   178 	    dbus_error_free(&error);
       
   179 	    return;
       
   180 	}
       
   181 
       
   182 	if (dbus_connection_register_object_path(dbus_connection,
       
   183 						    ICD_DBUS_PATH,
       
   184 						    &icd_vtable,
       
   185 						    (void*)this) == FALSE) {
       
   186 	    qWarning() << "Cannot register dbus signal handler, interface"<< ICD_DBUS_INTERFACE << "path" << ICD_DBUS_PATH;
       
   187 	    dbus_error_free(&error);
       
   188 	    return;
       
   189 	}
       
   190 
       
   191 #ifdef BEARER_MANAGEMENT_DEBUG
       
   192 	qDebug() << "Listening" << ICD_STATUS_CHANGED_SIG << "signal from" << ICD_DBUS_SERVICE;
       
   193 #endif
       
   194 	first_call = false;
       
   195 	dbus_error_free(&error);
       
   196     }
       
   197 
       
   198     QString id = d->activeConfig.identifier();
       
   199     if (!sessions.contains(id)) {
       
   200 	QNetworkSessionPrivate *ptr = d;
       
   201 	sessions.insert(id, ptr);
       
   202     }
       
   203 }
       
   204 
       
   205 
       
   206 void IcdListener::icdSignalReceived(QString& iap_id,
       
   207 #ifdef BEARER_MANAGEMENT_DEBUG
       
   208 				    QString& network_type,
       
   209 #else
       
   210 				    QString&,
       
   211 #endif
       
   212 				    QString& state)
       
   213 {
       
   214     if (iap_id == OSSO_IAP_SCAN) // icd sends scan status signals which we will ignore
       
   215 	return;
       
   216 
       
   217 #ifdef BEARER_MANAGEMENT_DEBUG
       
   218     qDebug() << "Status received:" << iap_id << "type" << network_type << "state" << state;
       
   219 #endif
       
   220 
       
   221     if (!sessions.contains(iap_id)) {
       
   222 #ifdef BEARER_MANAGEMENT_DEBUG
       
   223 	qDebug() << "No session for IAP" << iap_id;
       
   224 #endif
       
   225 	return;
       
   226     }
       
   227 
       
   228     QNetworkSessionPrivate *session = sessions.value(iap_id);
       
   229     QNetworkConfiguration ap_conf = session->manager.configurationFromIdentifier(iap_id);
       
   230     if (!ap_conf.isValid()) {
       
   231 #ifdef BEARER_MANAGEMENT_DEBUG
       
   232 	qDebug() << "Unknown IAP" << iap_id;
       
   233 #endif
       
   234 	return;
       
   235     }
       
   236 
       
   237     IapConnectionStatus status;
       
   238 
       
   239     if (state == "IDLE") {
       
   240 	status = DISCONNECTED;
       
   241     } else if (state == "CONNECTED") {
       
   242 	status = CONNECTED;
       
   243     } else if (state == "NETWORKUP") {
       
   244 	status = NETWORK_UP;
       
   245     } else {
       
   246 	//qDebug() << "Unknown state" << state;
       
   247 	return;
       
   248     }
       
   249 
       
   250     if (status == DISCONNECTED) {
       
   251 	if (ap_conf.state() == QNetworkConfiguration::Active) {
       
   252 	    /* The IAP was just disconnected by Icd */
       
   253 	    session->updateState(QNetworkSession::Disconnected);
       
   254 	} else {
       
   255 #ifdef BEARER_MANAGEMENT_DEBUG
       
   256 	    qDebug() << "Got a network disconnect when in state" << ap_conf.state();
       
   257 #endif
       
   258 	}
       
   259     } else if (status == CONNECTED) {
       
   260 	/* The IAP was just connected by Icd */
       
   261 	session->updateState(QNetworkSession::Connected);
       
   262 	session->updateIdentifier(iap_id);
       
   263 
       
   264 	if (session->publicConfig.identifier() == OSSO_IAP_ANY) {
       
   265 #ifdef BEARER_MANAGEMENT_DEBUG
       
   266 	    qDebug() << "IAP" << iap_id << "connected when connecting to" << OSSO_IAP_ANY;
       
   267 #endif
       
   268 	} else {
       
   269 #ifdef BEARER_MANAGEMENT_DEBUG
       
   270 	    qDebug() << "IAP" << iap_id << "connected";
       
   271 #endif
       
   272 	}
       
   273     }
       
   274 
       
   275     return;
       
   276 }
       
   277 
       
   278 
       
   279 void IcdListener::cleanup()
       
   280 {
       
   281     if (!first_call) {
       
   282 	dbus_bus_remove_match(dbus_connection, ICD_DBUS_MATCH, NULL);
       
   283 	dbus_connection_unref(dbus_connection);
       
   284     }
       
   285 }
       
   286 
       
   287 
       
   288 void IcdListener::cleanupSession(QNetworkSessionPrivate *ptr)
       
   289 {
       
   290     if (ptr->publicConfig.type() == QNetworkConfiguration::UserChoice)
       
   291         (void)sessions.take(ptr->activeConfig.identifier());
       
   292     else
       
   293         (void)sessions.take(ptr->publicConfig.identifier());
       
   294 }
       
   295 
       
   296 
   141 
   297 void QNetworkSessionPrivate::cleanupSession(void)
   142 void QNetworkSessionPrivate::cleanupSession(void)
   298 {
   143 {
   299     icdListener()->cleanupSession(this);
       
   300 
       
   301     QObject::disconnect(q, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(updateProxies(QNetworkSession::State)));
   144     QObject::disconnect(q, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(updateProxies(QNetworkSession::State)));
   302 }
   145 }
   303 
   146 
   304 
   147 
   305 void QNetworkSessionPrivate::updateState(QNetworkSession::State newState)
   148 void QNetworkSessionPrivate::updateState(QNetworkSession::State newState)
   306 {
   149 {
   307     if( newState != state) {
   150     if (newState != state) {
   308         state = newState;
   151         if (newState == QNetworkSession::Disconnected) {
   309 
   152             if (isOpen) {
   310 	if (state == QNetworkSession::Disconnected) {
   153                 // The Session was aborted by the user or system
       
   154                 lastError = QNetworkSession::SessionAbortedError;
       
   155                 emit q->error(lastError);
       
   156                 emit q->closed();
       
   157             }
       
   158             if (m_stopTimer.isActive()) {
       
   159                 // Session was closed by calling stop()
       
   160                 m_stopTimer.stop();
       
   161             }
   311             isOpen = false;
   162             isOpen = false;
       
   163             opened = false;
   312 	    currentNetworkInterface.clear();
   164 	    currentNetworkInterface.clear();
   313 	    if (publicConfig.type() == QNetworkConfiguration::UserChoice)
   165             if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
   314 		activeConfig.d->state = QNetworkConfiguration::Defined;
   166                 copyConfig(publicConfig, activeConfig);
   315 	    publicConfig.d->state = QNetworkConfiguration::Defined;
   167                 activeConfig.d->state = QNetworkConfiguration::Defined;
   316 
   168             } else {
   317 	} else if (state == QNetworkSession::Connected) {
   169                 if (!activeConfig.isValid()) {
   318             isOpen = true;
   170                     // Active configuration (IAP) was removed from system
       
   171                     // => Connection was disconnected and configuration became
       
   172                     //    invalid
       
   173                     // => Also Session state must be changed to invalid
       
   174                     newState = QNetworkSession::Invalid;
       
   175                 }
       
   176             }
       
   177         } else if (newState == QNetworkSession::Connected) {
       
   178             if (opened) {
       
   179                 isOpen = true;
       
   180             }
   319 	    if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
   181 	    if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
   320 		activeConfig.d->state = QNetworkConfiguration::Active;
   182 		activeConfig.d->state = QNetworkConfiguration::Active;
   321 		activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint;
   183 		activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint;
   322 	    }
   184 	    }
   323 	    publicConfig.d->state = QNetworkConfiguration::Active;
   185 	    publicConfig.d->state = QNetworkConfiguration::Active;
   324 	}
   186 	}
   325 
   187 
   326 	emit q->stateChanged(newState);
   188         if (newState != state) {
   327     }
   189             state = newState;
   328 }
   190             emit q->stateChanged(newState);
   329 
   191         }
   330 
   192     }
   331 void QNetworkSessionPrivate::updateIdentifier(QString &newId)
   193 }
       
   194 
       
   195 
       
   196 void QNetworkSessionPrivate::updateIdentifier(const QString &newId)
   332 {
   197 {
   333     if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
   198     if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
   334 	activeConfig.d->network_attrs |= ICD_NW_ATTR_IAPNAME;
   199 	activeConfig.d->network_attrs |= ICD_NW_ATTR_IAPNAME;
   335 	activeConfig.d->id = newId;
   200 	activeConfig.d->id = newId;
   336     } else {
   201     } else {
   355 
   220 
   356     if (!icd.statistics(stats_results)) {
   221     if (!icd.statistics(stats_results)) {
   357 	return 0;
   222 	return 0;
   358     }
   223     }
   359 
   224 
   360     foreach (Maemo::IcdStatisticsResult res, stats_results) {
   225     foreach (const Maemo::IcdStatisticsResult &res, stats_results) {
   361 	if (res.params.network_attrs & ICD_NW_ATTR_IAPNAME) {
   226 	if (res.params.network_attrs & ICD_NW_ATTR_IAPNAME) {
   362 	    /* network_id is the IAP UUID */
   227 	    /* network_id is the IAP UUID */
   363 	    if (QString(res.params.network_id.data()) == activeConfig.identifier()) {
   228 	    if (QString(res.params.network_id.data()) == activeConfig.identifier()) {
   364 		counter_tx = res.bytes_sent;
   229 		counter_tx = res.bytes_sent;
   365 		counter_rx = res.bytes_received;
   230 		counter_rx = res.bytes_received;
   431 /* This is called by QNetworkSession constructor and it updates the current
   296 /* This is called by QNetworkSession constructor and it updates the current
   432  * state of the configuration.
   297  * state of the configuration.
   433  */
   298  */
   434 void QNetworkSessionPrivate::syncStateWithInterface()
   299 void QNetworkSessionPrivate::syncStateWithInterface()
   435 {
   300 {
   436     /* Start to listen Icd status messages. */
       
   437     icdListener()->setup(this);
       
   438 
       
   439     /* Initially we are not active although the configuration might be in
   301     /* Initially we are not active although the configuration might be in
   440      * connected state.
   302      * connected state.
   441      */
   303      */
   442     isOpen = false;
   304     isOpen = false;
   443     opened = false;
   305     opened = false;
   445     QObject::connect(&manager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationsChanged()));
   307     QObject::connect(&manager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationsChanged()));
   446 
   308 
   447     if (publicConfig.d.data()) {
   309     if (publicConfig.d.data()) {
   448 	QNetworkConfigurationManagerPrivate* mgr = (QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager;
   310 	QNetworkConfigurationManagerPrivate* mgr = (QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager;
   449 	if (mgr) {
   311 	if (mgr) {
   450 	    QObject::connect(mgr, SIGNAL(configurationChanged(QNetworkConfiguration)),
   312             connect(mgr, SIGNAL(iapStateChanged(const QString&, uint)),
   451 			    this, SLOT(configurationChanged(QNetworkConfiguration)));
   313                     this, SLOT(iapStateChanged(const QString&, uint)));
   452 	} else {
   314 	} else {
   453 	    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?";
   315             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?";
   454 	    state = QNetworkSession::Invalid;
   316 	    state = QNetworkSession::Invalid;
   455 	    lastError = QNetworkSession::UnknownSessionError;
   317 	    lastError = QNetworkSession::UnknownSessionError;
   456 	    return;
   318 	    return;
   457 	}
   319 	}
   458     }
   320     }
   462     state = QNetworkSession::Invalid;
   324     state = QNetworkSession::Invalid;
   463     lastError = QNetworkSession::UnknownSessionError;
   325     lastError = QNetworkSession::UnknownSessionError;
   464 
   326 
   465     switch (publicConfig.type()) {
   327     switch (publicConfig.type()) {
   466     case QNetworkConfiguration::InternetAccessPoint:
   328     case QNetworkConfiguration::InternetAccessPoint:
   467 	activeConfig = publicConfig;
   329         activeConfig = publicConfig;
   468         break;
   330         break;
   469     case QNetworkConfiguration::ServiceNetwork:
   331     case QNetworkConfiguration::ServiceNetwork:
   470 	serviceConfig = publicConfig;
   332         serviceConfig = publicConfig;
   471 	break;
   333 	break;
   472     case QNetworkConfiguration::UserChoice:
   334     case QNetworkConfiguration::UserChoice:
   473 	// active config will contain correct data after open() has succeeded
   335 	// active config will contain correct data after open() has succeeded
   474 	copyConfig(publicConfig, activeConfig);
   336         copyConfig(publicConfig, activeConfig);
   475 
   337 
   476 	/* We create new configuration that holds the actual configuration
   338 	/* We create new configuration that holds the actual configuration
   477 	 * returned by icd. This way publicConfig still contains the
   339 	 * returned by icd. This way publicConfig still contains the
   478 	 * original user specified configuration.
   340 	 * original user specified configuration.
   479 	 *
   341 	 *
   503 
   365 
   504     /* Update the active config from first connection, this is ok as icd
   366     /* Update the active config from first connection, this is ok as icd
   505      * supports only one connection anyway.
   367      * supports only one connection anyway.
   506      */
   368      */
   507     if (icd.state(state_results) && !state_results.isEmpty()) {
   369     if (icd.state(state_results) && !state_results.isEmpty()) {
   508 
       
   509 	/* If we did not get full state back, then we are not
   370 	/* If we did not get full state back, then we are not
   510 	 * connected and can skip the next part.
   371 	 * connected and can skip the next part.
   511 	 */
   372 	 */
   512 	if (!(state_results.first().params.network_attrs == 0 &&
   373 	if (!(state_results.first().params.network_attrs == 0 &&
   513 		state_results.first().params.network_id.isEmpty())) {
   374 		state_results.first().params.network_id.isEmpty())) {
   516 	     * that tell the icd is actually connected to another IAP,
   377 	     * that tell the icd is actually connected to another IAP,
   517 	     * then do not update current state etc.
   378 	     * then do not update current state etc.
   518 	     */
   379 	     */
   519 	    if (publicConfig.type() == QNetworkConfiguration::UserChoice ||
   380 	    if (publicConfig.type() == QNetworkConfiguration::UserChoice ||
   520 		    publicConfig.d->id == state_results.first().params.network_id) {
   381 		    publicConfig.d->id == state_results.first().params.network_id) {
   521 
       
   522 		switch (state_results.first().state) {
   382 		switch (state_results.first().state) {
   523 		case ICD_STATE_DISCONNECTED:
   383 		case ICD_STATE_DISCONNECTED:
   524 		    state = QNetworkSession::Disconnected;
   384                     state = QNetworkSession::Disconnected;
   525 		    if (activeConfig.d.data())
   385 		    if (activeConfig.d.data())
   526 			activeConfig.d->isValid = true;
   386 			activeConfig.d->isValid = true;
   527 		    break;
   387 		    break;
   528 		case ICD_STATE_CONNECTING:
   388 		case ICD_STATE_CONNECTING:
   529 		    state = QNetworkSession::Connecting;
   389                     state = QNetworkSession::Connecting;
   530 		    if (activeConfig.d.data())
   390 		    if (activeConfig.d.data())
   531 			activeConfig.d->isValid = true;
   391 			activeConfig.d->isValid = true;
   532 		    break;
   392 		    break;
   533 		case ICD_STATE_CONNECTED:
   393 		case ICD_STATE_CONNECTED:
   534 		    {
   394 		    {
   535 			if (!state_results.first().error.isEmpty())
   395                         if (!state_results.first().error.isEmpty())
   536 			    break;
   396 			    break;
   537                         
   397 
   538                         const QString id = state_results.first().params.network_id;
   398                         const QString id = state_results.first().params.network_id;
   539 
   399 
   540 			QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager;
   400                         QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager;
   541 			if (mgr->accessPointConfigurations.contains(id)) {
   401 			if (mgr->accessPointConfigurations.contains(id)) {
   542                             //we don't want the copied data if the config is already known by the manager
   402                             //we don't want the copied data if the config is already known by the manager
   543                             //just reuse it so that existing references to the old data get the same update
   403                             //just reuse it so that existing references to the old data get the same update
   544 			    QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = mgr->accessPointConfigurations.value(activeConfig.d->id);
   404                             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = mgr->accessPointConfigurations.value(id);
   545                             activeConfig.d = priv;
   405                             activeConfig.d = priv;
   546                         }
   406                         }
   547 
   407 
   548 
       
   549 			state = QNetworkSession::Connected;
   408 			state = QNetworkSession::Connected;
   550 			activeConfig.d->network_id = state_results.first().params.network_id;
   409                         activeConfig.d->network_id = state_results.first().params.network_id;
   551 			activeConfig.d->id = activeConfig.d->network_id;
   410                         activeConfig.d->id = activeConfig.d->network_id;
   552 			activeConfig.d->network_attrs = state_results.first().params.network_attrs;
   411                         activeConfig.d->network_attrs = state_results.first().params.network_attrs;
   553 			activeConfig.d->iap_type = state_results.first().params.network_type;
   412                         activeConfig.d->iap_type = state_results.first().params.network_type;
   554 			activeConfig.d->service_type = state_results.first().params.service_type;
   413                         activeConfig.d->service_type = state_results.first().params.service_type;
   555 			activeConfig.d->service_id = state_results.first().params.service_id;
   414                         activeConfig.d->service_id = state_results.first().params.service_id;
   556 			activeConfig.d->service_attrs = state_results.first().params.service_attrs;
   415                         activeConfig.d->service_attrs = state_results.first().params.service_attrs;
   557 			activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint;
   416                         activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint;
   558 			activeConfig.d->state = QNetworkConfiguration::Active;
   417                         activeConfig.d->state = QNetworkConfiguration::Active;
   559 			activeConfig.d->isValid = true;
   418                         activeConfig.d->isValid = true;
   560 			currentNetworkInterface = get_network_interface();
   419                         currentNetworkInterface = get_network_interface();
   561 
   420 
   562 			Maemo::IAPConf iap_name(activeConfig.d->id);
   421 			Maemo::IAPConf iap_name(activeConfig.d->id);
   563 			QString name_value = iap_name.value("name").toString();
   422 			QString name_value = iap_name.value("name").toString();
   564 			if (!name_value.isEmpty())
   423 			if (!name_value.isEmpty())
   565 			    activeConfig.d->name = name_value;
   424 			    activeConfig.d->name = name_value;
   566 			else
   425 			else
   567 			    activeConfig.d->name = activeConfig.d->id;
   426 			    activeConfig.d->name = activeConfig.d->id;
   568 
   427 
   569 
       
   570 			// Add the new active configuration to manager or update the old config
   428 			// Add the new active configuration to manager or update the old config
   571 			mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager;
   429 			mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager;
   572 			if (!(mgr->accessPointConfigurations.contains(activeConfig.d->id))) {
   430 			if (!(mgr->accessPointConfigurations.contains(activeConfig.d->id))) {
   573 			    QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = activeConfig.d;
   431 			    QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = activeConfig.d;
   574 			    mgr->accessPointConfigurations.insert(activeConfig.d->id, ptr);
   432 			    mgr->accessPointConfigurations.insert(activeConfig.d->id, ptr);
   579 
   437 
   580 #ifdef BEARER_MANAGEMENT_DEBUG
   438 #ifdef BEARER_MANAGEMENT_DEBUG
   581 			    //qDebug()<<"New configuration"<<activeConfig.d->id<<"added to manager in sync";
   439 			    //qDebug()<<"New configuration"<<activeConfig.d->id<<"added to manager in sync";
   582 #endif
   440 #endif
   583 
   441 
   584 			} else {
   442                         }
   585 			    mgr->configurationChanged((QNetworkConfigurationPrivate*)(activeConfig.d.data()));
       
   586 #ifdef BEARER_MANAGEMENT_DEBUG
       
   587 			    //qDebug()<<"Existing configuration"<<activeConfig.d->id<<"updated in manager in sync";
       
   588 #endif
       
   589 			}
       
   590 
       
   591 		    }
   443 		    }
   592 		    break;
   444 		    break;
   593 
   445 
   594 		case ICD_STATE_DISCONNECTING:
   446 		case ICD_STATE_DISCONNECTING:
   595 		    state = QNetworkSession::Closing;
   447                     state = QNetworkSession::Closing;
   596 		    if (activeConfig.d.data())
   448 		    if (activeConfig.d.data())
   597 			activeConfig.d->isValid = true;
   449 			activeConfig.d->isValid = true;
   598 		    break;
   450 		    break;
   599 		default:
   451 		default:
   600 		    break;
   452                     break;
   601 		}
   453 		}
   602 	    }
   454 	    }
   603 	} else {
   455 	} else {
   604 #ifdef BEARER_MANAGEMENT_DEBUG
   456 #ifdef BEARER_MANAGEMENT_DEBUG
   605 	    qDebug() << "status_req tells icd is not connected";
   457 	    qDebug() << "status_req tells icd is not connected";
   684         state = QNetworkSession::Disconnected;
   536         state = QNetworkSession::Disconnected;
   685     } else if ((activeConfig.state() & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) {
   537     } else if ((activeConfig.state() & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) {
   686         state = QNetworkSession::NotAvailable;
   538         state = QNetworkSession::NotAvailable;
   687     } else if ((activeConfig.state() & QNetworkConfiguration::Undefined) == QNetworkConfiguration::Undefined) {
   539     } else if ((activeConfig.state() & QNetworkConfiguration::Undefined) == QNetworkConfiguration::Undefined) {
   688         state = QNetworkSession::NotAvailable;
   540         state = QNetworkSession::NotAvailable;
   689 	clearConfiguration(activeConfig);
       
   690     }
   541     }
   691 
   542 
   692     bool oldActive = isOpen;
   543     bool oldActive = isOpen;
   693     isOpen = newActive;
   544     isOpen = newActive;
   694 
   545 
   699         emit q->closed();
   550         emit q->closed();
   700 
   551 
   701     if (oldState != state) {
   552     if (oldState != state) {
   702         emit q->stateChanged(state);
   553         emit q->stateChanged(state);
   703 
   554 
   704 	if (state == QNetworkSession::Disconnected) {
   555         if (state == QNetworkSession::Disconnected && oldActive) {
   705 #ifdef BEARER_MANAGEMENT_DEBUG
   556 #ifdef BEARER_MANAGEMENT_DEBUG
   706 	    //qDebug()<<"session aborted error emitted for"<<activeConfig.identifier();
   557 	    //qDebug()<<"session aborted error emitted for"<<activeConfig.identifier();
   707 #endif
   558 #endif
   708 	    lastError = QNetworkSession::SessionAbortedError;
   559 	    lastError = QNetworkSession::SessionAbortedError;
   709 	    emit q->error(lastError);
   560 	    emit q->error(lastError);
   712 
   563 
   713 #ifdef BEARER_MANAGEMENT_DEBUG
   564 #ifdef BEARER_MANAGEMENT_DEBUG
   714     //qDebug()<<"oldState ="<<oldState<<" state ="<<state<<" oldActive ="<<oldActive<<" newActive ="<<newActive<<" opened ="<<opened;
   565     //qDebug()<<"oldState ="<<oldState<<" state ="<<state<<" oldActive ="<<oldActive<<" newActive ="<<newActive<<" opened ="<<opened;
   715 #endif
   566 #endif
   716 }
   567 }
   717 
       
   718 
       
   719 void QNetworkSessionPrivate::configurationChanged(const QNetworkConfiguration &config)
       
   720 {
       
   721     if (serviceConfig.isValid() && (config == serviceConfig || config == activeConfig))
       
   722         updateStateFromServiceNetwork();
       
   723     else if (config == activeConfig)
       
   724         updateStateFromActiveConfig();
       
   725 }
       
   726 
       
   727 
   568 
   728 static QString get_network_interface()
   569 static QString get_network_interface()
   729 {
   570 {
   730     Maemo::Icd icd;
   571     Maemo::Icd icd;
   731     QList<Maemo::IcdAddressInfoResult> addr_results;
   572     QList<Maemo::IcdAddressInfoResult> addr_results;
   759 #endif
   600 #endif
   760 	return iface;
   601 	return iface;
   761     }
   602     }
   762 
   603 
   763     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
   604     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
   764 	family = ifa->ifa_addr->sa_family;
   605         if (ifa->ifa_addr) {
   765 	if (family != AF_INET) {
   606             family = ifa->ifa_addr->sa_family;
   766 	    continue; /* Currently only IPv4 is supported by icd dbus interface */
   607             if (family != AF_INET) {
   767 	}
   608                 continue; /* Currently only IPv4 is supported by icd dbus interface */
   768 	if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == addr.s_addr) {
   609             }
   769 	    iface = QString(ifa->ifa_name);
   610             if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == addr.s_addr) {
   770 	    break;
   611                 iface = QString(ifa->ifa_name);
   771 	}
   612                 break;
       
   613             }
       
   614         }
   772     }
   615     }
   773 
   616 
   774     freeifaddrs(ifaddr);
   617     freeifaddrs(ifaddr);
   775     return iface;
   618     return iface;
   776 }
   619 }
   777 
   620 
   778 
   621 
   779 void QNetworkSessionPrivate::open()
   622 void QNetworkSessionPrivate::open()
   780 {
   623 {
       
   624     if (m_stopTimer.isActive()) {
       
   625         m_stopTimer.stop();
       
   626     }
       
   627     if (!publicConfig.isValid()) {
       
   628         lastError = QNetworkSession::InvalidConfigurationError;
       
   629         emit q->error(lastError);
       
   630         return;
       
   631     }
   781     if (serviceConfig.isValid()) {
   632     if (serviceConfig.isValid()) {
   782         lastError = QNetworkSession::OperationNotSupportedError;
   633         lastError = QNetworkSession::OperationNotSupportedError;
   783         emit q->error(lastError);
   634         emit q->error(lastError);
   784     } else if (!isOpen) {
   635     } else if (!isOpen) {
   785 
       
   786 	if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
   636 	if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
   787 	    /* Caller is trying to connect to default IAP.
   637 	    /* Caller is trying to connect to default IAP.
   788 	     * At this time we will not know the IAP details so we just
   638 	     * At this time we will not know the IAP details so we just
   789 	     * connect and update the active config when the IAP is
   639 	     * connect and update the active config when the IAP is
   790 	     * connected.
   640 	     * connected.
   808         opened = true;
   658         opened = true;
   809 
   659 
   810         if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) {
   660         if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) {
   811             state = QNetworkSession::Connecting;
   661             state = QNetworkSession::Connecting;
   812             emit q->stateChanged(state);
   662             emit q->stateChanged(state);
   813 
   663             QTimer::singleShot(0, this, SLOT(do_open()));
   814 	    QTimer::singleShot(0, this, SLOT(do_open()));
   664             return;
   815 	    return;
       
   816         }
   665         }
   817 
       
   818         isOpen = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active;
   666         isOpen = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active;
   819         if (isOpen)
   667         if (isOpen)
   820             emit quitPendingWaitsForOpened();
   668             emit quitPendingWaitsForOpened();
   821     } else {
   669     } else {
   822 	/* We seem to be active so inform caller */
   670         /* We seem to be active so inform caller */
   823 	emit quitPendingWaitsForOpened();
   671         emit quitPendingWaitsForOpened();
   824     }
   672     }
   825 }
   673 }
   826 
       
   827 
   674 
   828 void QNetworkSessionPrivate::do_open()
   675 void QNetworkSessionPrivate::do_open()
   829 {
   676 {
   830     icd_connection_flags flags = connectFlags;
   677     icd_connection_flags flags = connectFlags;
   831     bool st;
       
   832     QString result;
       
   833     QString iap = publicConfig.identifier();
   678     QString iap = publicConfig.identifier();
   834 
   679 
   835     if (state == QNetworkSession::Connected) {
   680     if (state == QNetworkSession::Connected) {
   836 #ifdef BEARER_MANAGEMENT_DEBUG
   681 #ifdef BEARER_MANAGEMENT_DEBUG
   837 	qDebug() << "Already connected to" << activeConfig.identifier();
   682         qDebug() << "Already connected to" << activeConfig.identifier();
   838 #endif
   683 #endif
   839         emit q->stateChanged(QNetworkSession::Connected);
   684         emit q->stateChanged(QNetworkSession::Connected);
   840 	emit quitPendingWaitsForOpened();
   685         emit quitPendingWaitsForOpened();
   841 	return;
   686 	return;
   842     }
   687     }
   843 
   688 
   844     Maemo::IcdConnectResult connect_result;
       
   845     Maemo::Icd icd(ICD_LONG_CONNECT_TIMEOUT);
       
   846     QNetworkConfiguration config;
       
   847     if (publicConfig.type() == QNetworkConfiguration::UserChoice)
   689     if (publicConfig.type() == QNetworkConfiguration::UserChoice)
   848 	config = activeConfig;
   690         config = activeConfig;
   849     else
   691     else
   850 	config = publicConfig;
   692         config = publicConfig;
   851 
   693 
   852     if (iap == OSSO_IAP_ANY) {
   694     if (iap == OSSO_IAP_ANY) {
   853 #ifdef BEARER_MANAGEMENT_DEBUG
   695 #ifdef BEARER_MANAGEMENT_DEBUG
   854 	qDebug() << "connecting to default IAP" << iap;
   696         qDebug() << "connecting to default IAP" << iap;
   855 #endif
   697 #endif
   856 	st = icd.connect(flags, connect_result);
   698         m_connectRequestTimer.start(ICD_LONG_CONNECT_TIMEOUT);
   857 
   699         m_dbusInterface->asyncCall(ICD_DBUS_API_CONNECT_REQ, (uint)flags); // Return value ignored
       
   700         m_asynchCallActive = true;
   858     } else {
   701     } else {
   859 
   702         ICd2DetailsDBusStruct icd2;
   860 	QList<Maemo::ConnectParams> params;
   703         icd2.serviceType = config.d->service_type;
   861 	Maemo::ConnectParams param;
   704         icd2.serviceAttributes = config.d->service_attrs;
   862 	param.connect.service_type = config.d->service_type;
   705         icd2.setviceId = config.d->service_id;
   863 	param.connect.service_attrs = config.d->service_attrs;
   706         icd2.networkType = config.d->iap_type;
   864 	param.connect.service_id = config.d->service_id;
   707         icd2.networkAttributes = config.d->network_attrs;
   865 	param.connect.network_type = config.d->iap_type;
   708         if (config.d->network_attrs & ICD_NW_ATTR_IAPNAME) {
   866 	param.connect.network_attrs = config.d->network_attrs;
   709             icd2.networkId  = QByteArray(iap.toLatin1());
   867 	if (config.d->network_attrs & ICD_NW_ATTR_IAPNAME)
   710         } else {
   868 	    param.connect.network_id = QByteArray(iap.toLatin1());
   711             icd2.networkId  = config.d->network_id;
   869 	else
   712         }
   870 	    param.connect.network_id = config.d->network_id;
   713 
   871 	params.append(param);
   714 #ifdef BEARER_MANAGEMENT_DEBUG
   872 
   715     qDebug("connecting to %s/%s/0x%x/%s/0x%x/%s",
   873 #ifdef BEARER_MANAGEMENT_DEBUG
   716         icd2.networkId.data(),
   874 	qDebug("connecting to %s/%s/0x%x/%s/0x%x/%s",
   717         icd2.networkType.toAscii().constData(),
   875 	    param.connect.network_id.data(),
   718         icd2.networkAttributes,
   876 	    param.connect.network_type.toAscii().constData(),
   719         icd2.serviceType.toAscii().constData(),
   877 	    param.connect.network_attrs,
   720         icd2.serviceAttributes,
   878 	    param.connect.service_type.toAscii().constData(),
   721         icd2.setviceId.toAscii().constData());
   879 	    param.connect.service_attrs,
   722 #endif
   880 	    param.connect.service_id.toAscii().constData());
   723 
   881 #endif
   724         ICd2DetailsList paramArray;
   882 	st = icd.connect(flags, params, connect_result);
   725         paramArray.append(icd2);
   883     }
   726         m_connectRequestTimer.start(ICD_LONG_CONNECT_TIMEOUT);
   884 
   727         m_dbusInterface->asyncCall(ICD_DBUS_API_CONNECT_REQ, (uint)flags, QVariant::fromValue(paramArray)); // Return value ignored
   885     if (st) {
   728         m_asynchCallActive = true;
   886 	result = connect_result.connect.network_id.data();
   729     }
   887 	QString connected_iap = result;
   730 }
   888 
   731 
   889 	if (connected_iap.isEmpty()) {
   732  void QNetworkSessionPrivate::stateChange(const QDBusMessage& rep)
   890 #ifdef BEARER_MANAGEMENT_DEBUG
   733 {
   891 	    qDebug() << "connect to"<< iap << "failed, result is empty";
   734      if (m_asynchCallActive == true) {
   892 #endif
   735         if (m_connectRequestTimer.isActive())
   893 	    updateState(QNetworkSession::Disconnected);
   736             m_connectRequestTimer.stop();
   894 	    emit q->error(QNetworkSession::InvalidConfigurationError);
   737         m_asynchCallActive = false;
   895 	    if (publicConfig.type() == QNetworkConfiguration::UserChoice)
   738 
   896 		cleanupAnyConfiguration();
   739         QString result = rep.arguments().at(5).toString(); // network id or empty string
   897 	    return;
   740         QString connected_iap = result;
   898 	}
   741         if (connected_iap.isEmpty()) {
   899 
   742 #ifdef BEARER_MANAGEMENT_DEBUG
   900 	/* If the user tried to connect to some specific connection (foo)
   743             qDebug() << "connect to"<< publicConfig.identifier() << "failed, result is empty";
   901 	 * and we were already connected to some other connection (bar),
   744 #endif
   902 	 * then we cannot activate this session although icd has a valid
   745             updateState(QNetworkSession::Disconnected);
   903 	 * connection to somewhere.
   746             emit q->error(QNetworkSession::InvalidConfigurationError);
   904 	 */
   747             if (publicConfig.type() == QNetworkConfiguration::UserChoice)
   905 	if ((publicConfig.type() != QNetworkConfiguration::UserChoice) &&
   748                     copyConfig(publicConfig, activeConfig);
   906 	    (connected_iap != config.identifier())) {
   749             return;
   907 	    updateState(QNetworkSession::Disconnected);
   750         }
   908 	    emit q->error(QNetworkSession::InvalidConfigurationError);
   751 
   909 	    return;
   752          /* If the user tried to connect to some specific connection (foo)
   910 	}
   753          * and we were already connected to some other connection (bar),
   911 
   754          * then we cannot activate this session although icd has a valid
   912 
   755          * connection to somewhere.
   913 	/* Did we connect to non saved IAP? */
   756          */
   914 	if (!(config.d->network_attrs & ICD_NW_ATTR_IAPNAME)) {
   757         if ((publicConfig.type() != QNetworkConfiguration::UserChoice) &&
   915 	    /* Because the connection succeeded, the IAP is now known.
   758             (connected_iap != config.identifier())) {
   916 	     */
   759             updateState(QNetworkSession::Disconnected);
   917 	    config.d->network_attrs |= ICD_NW_ATTR_IAPNAME;
   760             emit q->error(QNetworkSession::InvalidConfigurationError);
   918 	    config.d->id = connected_iap;
   761             return;
   919 	}
   762         }
   920 
   763 
   921 	/* User might have changed the IAP name when a new IAP was saved */
   764         /* Did we connect to non saved IAP? */
   922 	Maemo::IAPConf iap_name(config.d->id);
   765         if (!(config.d->network_attrs & ICD_NW_ATTR_IAPNAME)) {
   923 	QString name = iap_name.value("name").toString();
   766             /* Because the connection succeeded, the IAP is now known.
   924 	if (!name.isEmpty())
   767              */
   925 	    config.d->name = name;
   768             config.d->network_attrs |= ICD_NW_ATTR_IAPNAME;
   926 
   769             config.d->id = connected_iap;
   927         config.d->iap_type = connect_result.connect.network_type;
   770         }
   928 
   771 
   929 	config.d->isValid = true;
   772         /* User might have changed the IAP name when a new IAP was saved */
   930 	config.d->state = QNetworkConfiguration::Active;
   773         Maemo::IAPConf iap_name(config.d->id);
   931 	config.d->type = QNetworkConfiguration::InternetAccessPoint;
   774         QString name = iap_name.value("name").toString();
   932 
   775         if (!name.isEmpty())
   933 	startTime = QDateTime::currentDateTime();
   776             config.d->name = name;
   934 	updateState(QNetworkSession::Connected);
   777 
   935 
   778         config.d->iap_type = rep.arguments().at(3).toString(); // connect_result.connect.network_type;
   936 	currentNetworkInterface = get_network_interface();
   779         config.d->isValid = true;
   937 
   780         config.d->state = QNetworkConfiguration::Active;
   938 #ifdef BEARER_MANAGEMENT_DEBUG
   781         config.d->type = QNetworkConfiguration::InternetAccessPoint;
   939 	qDebug() << "connected to" << result << config.d->name << "at" << currentNetworkInterface;
   782 
   940 #endif
   783         startTime = QDateTime::currentDateTime();
   941 
   784         updateState(QNetworkSession::Connected);
   942 	/* We first check if the configuration already exists in the manager
   785         //currentNetworkInterface = get_network_interface();
   943 	 * and if it is not found there, we then insert it. Note that this
   786 #ifdef BEARER_MANAGEMENT_DEBUG
   944 	 * is only done for user choice config only because it can be missing
   787         //qDebug() << "connected to" << result << config.d->name << "at" << currentNetworkInterface;
   945 	 * from config manager list.
   788 #endif
   946 	 */
   789 
   947 
   790         /* We first check if the configuration already exists in the manager
   948 	if (publicConfig.d->type == QNetworkConfiguration::UserChoice) {
   791          * and if it is not found there, we then insert it. Note that this
   949 
   792          * is only done for user choice config only because it can be missing
       
   793          * from config manager list.
       
   794          */
       
   795         if (publicConfig.d->type == QNetworkConfiguration::UserChoice) {
   950 #ifdef BEARER_MANAGEMENT_DEBUG
   796 #ifdef BEARER_MANAGEMENT_DEBUG
   951 #if 0
   797 #if 0
   952 	    QList<QNetworkConfiguration> configs;
   798             QList<QNetworkConfiguration> configs;
   953 	    QNetworkConfigurationManagerPrivate *conPriv = (QNetworkConfigurationManagerPrivate*)config.d.data()->manager;
   799             QNetworkConfigurationManagerPrivate *conPriv = (QNetworkConfigurationManagerPrivate*)config.d.data()->manager;
   954 	    QList<QString> cpsIdents = conPriv->accessPointConfigurations.keys();
   800             QList<QString> cpsIdents = conPriv->accessPointConfigurations.keys();
   955 	    foreach( QString ii, cpsIdents) {
   801             foreach( QString ii, cpsIdents) {
   956 		QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> p = 
   802                 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> p =
   957 		    conPriv->accessPointConfigurations.value(ii);
   803                         conPriv->accessPointConfigurations.value(ii);
   958 		QNetworkConfiguration pt;
   804                 QNetworkConfiguration pt;
   959 		pt.d = conPriv->accessPointConfigurations.value(ii);
   805                 pt.d = conPriv->accessPointConfigurations.value(ii);
   960 		configs << pt;
   806                 configs << pt;
   961 	    }
   807             }
   962 
   808 
   963 	    int all = configs.count();
   809             int all = configs.count();
   964 	    qDebug() << "All configurations:" << all;
   810             qDebug() << "All configurations:" << all;
   965 	    foreach(QNetworkConfiguration p, configs) {
   811             foreach(QNetworkConfiguration p, configs) {
   966 		qDebug() << p.name() <<":  isvalid->" <<p.isValid() << " type->"<< p.type() << 
   812                 qDebug() << p.name() <<":  isvalid->" <<p.isValid() << " type->"<< p.type() <<
   967 		    " roaming->" << p.isRoamingAvailable() << "identifier->" << p.identifier() <<
   813                         " roaming->" << p.isRoamingAvailable() << "identifier->" << p.identifier() <<
   968 		    " purpose->" << p.purpose() << " state->" << p.state();
   814                         " purpose->" << p.purpose() << " state->" << p.state();
   969 	    }
   815             }
   970 #endif
   816 #endif
   971 #endif
   817 #endif
   972 
   818             QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager;
   973 	    QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)config.d.data()->manager;
       
   974             if (!mgr->accessPointConfigurations.contains(result)) {
   819             if (!mgr->accessPointConfigurations.contains(result)) {
   975 		QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = config.d;
   820                 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = config.d;
   976 		mgr->accessPointConfigurations.insert(result, ptr);
   821                 mgr->accessPointConfigurations.insert(result, ptr);
   977 
   822 
   978 		QNetworkConfiguration item;
   823                 QNetworkConfiguration item;
   979 		item.d = ptr;
   824                 item.d = ptr;
   980 		emit mgr->configurationAdded(item);
   825                 emit mgr->configurationAdded(item);
   981 
   826 
   982 #ifdef BEARER_MANAGEMENT_DEBUG
   827 #ifdef BEARER_MANAGEMENT_DEBUG
   983 		//qDebug()<<"New configuration"<<result<<"added to manager in open";
   828             qDebug()<<"New configuration"<<result<<"added to manager in open";
   984 #endif
   829 #endif
   985 
   830 
   986 	    } else {
   831             } else {
   987 		QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = mgr->accessPointConfigurations.value(result);
   832                 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = mgr->accessPointConfigurations.value(result);
   988 		QNetworkConfiguration reference;
   833                 QNetworkConfiguration reference;
   989 		reference.d = priv;
   834                 reference.d = priv;
   990                 copyConfig(config, reference, false);
   835                 copyConfig(config, reference, false);
       
   836                 reference.d.data()->id = result; // Note: Id was not copied in copyConfig() function
   991                 config = reference;
   837                 config = reference;
   992                 activeConfig = reference;
   838                 activeConfig = reference;
   993 		mgr->configurationChanged((QNetworkConfigurationPrivate*)(config.d.data()));
   839 
   994 
   840 #ifdef BEARER_MANAGEMENT_DEBUG
   995 #ifdef BEARER_MANAGEMENT_DEBUG
   841                 qDebug()<<"Existing configuration"<<result<<"updated in manager in open";
   996 		//qDebug()<<"Existing configuration"<<result<<"updated in manager in open";
   842 #endif
   997 #endif
   843             }
   998 	    }
   844         }
   999 	}
   845 
  1000 
   846         emit quitPendingWaitsForOpened();
  1001 	emit quitPendingWaitsForOpened();
   847     }
  1002 
   848 }
  1003     } else {
   849 
  1004 #ifdef BEARER_MANAGEMENT_DEBUG
   850 void QNetworkSessionPrivate::connectTimeout()
  1005 	qDebug() << "connect to"<< iap << "failed, status:" << connect_result.status;
   851 {
  1006 #endif
   852     updateState(QNetworkSession::Disconnected);
  1007 	updateState(QNetworkSession::Disconnected);
   853     if (publicConfig.type() == QNetworkConfiguration::UserChoice)
  1008 	if (publicConfig.type() == QNetworkConfiguration::UserChoice)
   854             copyConfig(publicConfig, activeConfig);
  1009 	    cleanupAnyConfiguration();
   855         emit q->error(QNetworkSession::UnknownSessionError);
  1010 	emit q->error(QNetworkSession::UnknownSessionError);
   856 }
  1011     }
       
  1012 }
       
  1013 
       
  1014 
       
  1015 void QNetworkSessionPrivate::cleanupAnyConfiguration()
       
  1016 {
       
  1017 #ifdef BEARER_MANAGEMENT_DEBUG
       
  1018     qDebug()<<"Removing configuration created for" << activeConfig.d->id;
       
  1019 #endif
       
  1020     activeConfig = publicConfig;
       
  1021 }
       
  1022 
       
  1023 
   857 
  1024 void QNetworkSessionPrivate::close()
   858 void QNetworkSessionPrivate::close()
  1025 {
   859 {
       
   860     if (m_connectRequestTimer.isActive())
       
   861         m_connectRequestTimer.stop();
       
   862 
  1026     if (serviceConfig.isValid()) {
   863     if (serviceConfig.isValid()) {
  1027         lastError = QNetworkSession::OperationNotSupportedError;
   864         lastError = QNetworkSession::OperationNotSupportedError;
  1028         emit q->error(lastError);
   865         emit q->error(lastError);
  1029     } else if (isOpen) {
   866     } else if (isOpen) {
  1030         opened = false;
   867         opened = false;
  1034 }
   871 }
  1035 
   872 
  1036 
   873 
  1037 void QNetworkSessionPrivate::stop()
   874 void QNetworkSessionPrivate::stop()
  1038 {
   875 {
       
   876     if (m_connectRequestTimer.isActive())
       
   877         m_connectRequestTimer.stop();
       
   878 
  1039     if (serviceConfig.isValid()) {
   879     if (serviceConfig.isValid()) {
  1040         lastError = QNetworkSession::OperationNotSupportedError;
   880         lastError = QNetworkSession::OperationNotSupportedError;
  1041         emit q->error(lastError);
   881         emit q->error(lastError);
  1042     } else {
   882     } else {
  1043         if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
   883         if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
  1044             state = QNetworkSession::Closing;
   884             if (!m_stopTimer.isActive()) {
  1045             emit q->stateChanged(state);
   885                 Maemo::Icd icd;
  1046 
   886 #ifdef BEARER_MANAGEMENT_DEBUG
  1047 	    Maemo::Icd icd;
   887                 qDebug() << "stopping session" << publicConfig.identifier();
  1048 #ifdef BEARER_MANAGEMENT_DEBUG
   888 #endif
  1049 	    qDebug() << "stopping session" << publicConfig.identifier();
   889                 state = QNetworkSession::Closing;
  1050 #endif
   890                 emit q->stateChanged(state);
  1051 	    icd.disconnect(ICD_CONNECTION_FLAG_APPLICATION_EVENT);
   891 
  1052 	    startTime = QDateTime();
   892                 opened = false;
  1053 
   893                 isOpen = false;
  1054 	    /* Note that the state will go disconnected in
   894 
  1055 	     * updateStateFromActiveConfig() which gets called after
   895                 icd.disconnect(ICD_CONNECTION_FLAG_APPLICATION_EVENT);
  1056 	     * configurationChanged is emitted (below).
   896                 startTime = QDateTime();
  1057 	     */
   897 
  1058 
   898                 /* Note: Session state will change to disconnected
  1059 	    activeConfig.d->state = QNetworkConfiguration::Discovered;
   899                  *       as soon as QNetworkConfigurationManager sends
  1060 	    QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager;
   900                  *       corresponding iapStateChanged signal.
  1061 	    mgr->configurationChanged((QNetworkConfigurationPrivate*)activeConfig.d.data());
   901                  */
  1062 
   902 
  1063 	    opened = false;
   903                 // Make sure that this Session will send closed signal
  1064 	    isOpen = false;
   904                 // even though ICD connection will not ever get closed
  1065 
   905                 m_stopTimer.start(ICD_SHORT_CONNECT_TIMEOUT); // 10 seconds wait
       
   906             }
  1066         } else {
   907         } else {
  1067 	    opened = false;
   908 	    opened = false;
  1068 	    isOpen = false;
   909 	    isOpen = false;
  1069 	    emit q->closed();
   910 	    emit q->closed();
  1070 	}
   911 	}
  1071     }
   912     }
  1072 }
   913 }
  1073 
   914 
       
   915 void QNetworkSessionPrivate::finishStopBySendingClosedSignal()
       
   916 {
       
   917     if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
       
   918         state = QNetworkSession::Connected;
       
   919         emit q->stateChanged(state);
       
   920     }
       
   921     emit q->closed();
       
   922 }
  1074 
   923 
  1075 void QNetworkSessionPrivate::migrate()
   924 void QNetworkSessionPrivate::migrate()
  1076 {
   925 {
  1077     qWarning("This platform does not support roaming (%s).", __FUNCTION__);
   926     qWarning("This platform does not support roaming (%s).", __FUNCTION__);
  1078 }
   927 }
  1184 {
  1033 {
  1185     Maemo::ProxyConf::clear();
  1034     Maemo::ProxyConf::clear();
  1186 }
  1035 }
  1187 
  1036 
  1188 
  1037 
  1189 #include "qnetworksession_maemo.moc"
       
  1190 #include "moc_qnetworksession_maemo_p.cpp"
  1038 #include "moc_qnetworksession_maemo_p.cpp"
  1191 
  1039 
  1192 QTM_END_NAMESPACE
  1040 QTM_END_NAMESPACE