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 |
58 QTM_BEGIN_NAMESPACE |
54 QTM_BEGIN_NAMESPACE |
59 |
55 |
60 static QHash<QString, QVariant> properties; |
56 static QHash<QString, QVariant> properties; |
61 |
57 |
62 static QString get_network_interface(); |
58 static QString get_network_interface(); |
63 static DBusConnection *dbus_connection; |
59 |
64 static DBusHandlerResult signal_handler(DBusConnection *connection, |
60 void QNetworkSessionPrivate::iapStateChanged(const QString& iapid, uint icd_connection_state) |
65 DBusMessage *message, |
61 { |
66 void *user_data); |
62 if ((publicConfig.type() == QNetworkConfiguration::UserChoice) && opened) { |
67 |
63 updateIdentifier(iapid); |
68 #define ICD_DBUS_MATCH "type='signal'," \ |
64 } |
69 "interface='" ICD_DBUS_INTERFACE "'," \ |
65 |
70 "path='" ICD_DBUS_PATH "'" |
66 if (((publicConfig.type() == QNetworkConfiguration::UserChoice) && (activeConfig.d->id == iapid)) || |
71 |
67 (publicConfig.d->id == iapid)) { |
72 |
68 switch (icd_connection_state) { |
73 static inline DBusConnection *get_dbus_conn(DBusError *error) |
69 case ICD_STATE_CONNECTING: |
74 { |
70 updateState(QNetworkSession::Connecting); |
75 DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, error); |
71 break; |
76 #ifdef BEARER_MANAGEMENT_DEBUG |
72 case ICD_STATE_CONNECTED: |
77 qDebug() << "Listening to bus" << dbus_bus_get_unique_name(conn); |
73 updateState(QNetworkSession::Connected); |
78 #endif |
74 break; |
79 |
75 case ICD_STATE_DISCONNECTING: |
80 return conn; |
76 updateState(QNetworkSession::Closing); |
81 } |
77 break; |
82 |
78 case ICD_STATE_DISCONNECTED: |
83 |
79 updateState(QNetworkSession::Disconnected); |
84 /* Helper class that monitors the Icd status messages and |
80 break; |
85 * can change the IAP status accordingly. This is a singleton. |
81 default: |
86 */ |
82 break; |
87 class IcdListener : public QObject |
83 } |
88 { |
84 } |
89 Q_OBJECT |
85 } |
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 |
86 |
297 void QNetworkSessionPrivate::cleanupSession(void) |
87 void QNetworkSessionPrivate::cleanupSession(void) |
298 { |
88 { |
299 icdListener()->cleanupSession(this); |
|
300 |
|
301 QObject::disconnect(q, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(updateProxies(QNetworkSession::State))); |
89 QObject::disconnect(q, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(updateProxies(QNetworkSession::State))); |
302 } |
90 } |
303 |
91 |
304 |
92 |
305 void QNetworkSessionPrivate::updateState(QNetworkSession::State newState) |
93 void QNetworkSessionPrivate::updateState(QNetworkSession::State newState) |
306 { |
94 { |
307 if( newState != state) { |
95 if (newState != state) { |
308 state = newState; |
96 if (newState == QNetworkSession::Disconnected) { |
309 |
97 if (isOpen) { |
310 if (state == QNetworkSession::Disconnected) { |
98 // The Session was aborted by the user or system |
|
99 lastError = QNetworkSession::SessionAbortedError; |
|
100 emit q->error(lastError); |
|
101 emit q->closed(); |
|
102 } |
|
103 if (m_stopTimer.isActive()) { |
|
104 // Session was closed by calling stop() |
|
105 m_stopTimer.stop(); |
|
106 } |
311 isOpen = false; |
107 isOpen = false; |
|
108 opened = false; |
312 currentNetworkInterface.clear(); |
109 currentNetworkInterface.clear(); |
313 if (publicConfig.type() == QNetworkConfiguration::UserChoice) |
110 if (publicConfig.type() == QNetworkConfiguration::UserChoice) { |
314 activeConfig.d->state = QNetworkConfiguration::Defined; |
111 copyConfig(publicConfig, activeConfig); |
315 publicConfig.d->state = QNetworkConfiguration::Defined; |
112 activeConfig.d->state = QNetworkConfiguration::Defined; |
316 |
113 } else { |
317 } else if (state == QNetworkSession::Connected) { |
114 if (!activeConfig.isValid()) { |
318 isOpen = true; |
115 // Active configuration (IAP) was removed from system |
|
116 // => Connection was disconnected and configuration became |
|
117 // invalid |
|
118 // => Also Session state must be changed to invalid |
|
119 newState = QNetworkSession::Invalid; |
|
120 } |
|
121 } |
|
122 } else if (newState == QNetworkSession::Connected) { |
|
123 if (opened) { |
|
124 isOpen = true; |
|
125 } |
319 if (publicConfig.type() == QNetworkConfiguration::UserChoice) { |
126 if (publicConfig.type() == QNetworkConfiguration::UserChoice) { |
320 activeConfig.d->state = QNetworkConfiguration::Active; |
127 activeConfig.d->state = QNetworkConfiguration::Active; |
321 activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint; |
128 activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint; |
322 } |
129 } |
323 publicConfig.d->state = QNetworkConfiguration::Active; |
130 publicConfig.d->state = QNetworkConfiguration::Active; |
324 } |
131 } |
325 |
132 |
326 emit q->stateChanged(newState); |
133 if (newState != state) { |
327 } |
134 state = newState; |
328 } |
135 emit q->stateChanged(newState); |
329 |
136 } |
330 |
137 } |
331 void QNetworkSessionPrivate::updateIdentifier(QString &newId) |
138 } |
|
139 |
|
140 |
|
141 void QNetworkSessionPrivate::updateIdentifier(const QString &newId) |
332 { |
142 { |
333 if (publicConfig.type() == QNetworkConfiguration::UserChoice) { |
143 if (publicConfig.type() == QNetworkConfiguration::UserChoice) { |
334 activeConfig.d->network_attrs |= ICD_NW_ATTR_IAPNAME; |
144 activeConfig.d->network_attrs |= ICD_NW_ATTR_IAPNAME; |
335 activeConfig.d->id = newId; |
145 activeConfig.d->id = newId; |
336 } else { |
146 } else { |
516 * that tell the icd is actually connected to another IAP, |
322 * that tell the icd is actually connected to another IAP, |
517 * then do not update current state etc. |
323 * then do not update current state etc. |
518 */ |
324 */ |
519 if (publicConfig.type() == QNetworkConfiguration::UserChoice || |
325 if (publicConfig.type() == QNetworkConfiguration::UserChoice || |
520 publicConfig.d->id == state_results.first().params.network_id) { |
326 publicConfig.d->id == state_results.first().params.network_id) { |
521 |
|
522 switch (state_results.first().state) { |
327 switch (state_results.first().state) { |
523 case ICD_STATE_DISCONNECTED: |
328 case ICD_STATE_DISCONNECTED: |
524 state = QNetworkSession::Disconnected; |
329 state = QNetworkSession::Disconnected; |
525 if (activeConfig.d.data()) |
330 if (activeConfig.d.data()) |
526 activeConfig.d->isValid = true; |
331 activeConfig.d->isValid = true; |
527 break; |
332 break; |
528 case ICD_STATE_CONNECTING: |
333 case ICD_STATE_CONNECTING: |
529 state = QNetworkSession::Connecting; |
334 state = QNetworkSession::Connecting; |
530 if (activeConfig.d.data()) |
335 if (activeConfig.d.data()) |
531 activeConfig.d->isValid = true; |
336 activeConfig.d->isValid = true; |
532 break; |
337 break; |
533 case ICD_STATE_CONNECTED: |
338 case ICD_STATE_CONNECTED: |
534 { |
339 { |
535 if (!state_results.first().error.isEmpty()) |
340 if (!state_results.first().error.isEmpty()) |
536 break; |
341 break; |
537 |
342 |
538 const QString id = state_results.first().params.network_id; |
343 const QString id = state_results.first().params.network_id; |
539 |
344 |
540 QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager; |
345 QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager; |
541 if (mgr->accessPointConfigurations.contains(id)) { |
346 if (mgr->accessPointConfigurations.contains(id)) { |
542 //we don't want the copied data if the config is already known by the manager |
347 //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 |
348 //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); |
349 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = mgr->accessPointConfigurations.value(id); |
545 activeConfig.d = priv; |
350 activeConfig.d = priv; |
546 } |
351 } |
547 |
352 |
548 |
|
549 state = QNetworkSession::Connected; |
353 state = QNetworkSession::Connected; |
550 activeConfig.d->network_id = state_results.first().params.network_id; |
354 activeConfig.d->network_id = state_results.first().params.network_id; |
551 activeConfig.d->id = activeConfig.d->network_id; |
355 activeConfig.d->id = activeConfig.d->network_id; |
552 activeConfig.d->network_attrs = state_results.first().params.network_attrs; |
356 activeConfig.d->network_attrs = state_results.first().params.network_attrs; |
553 activeConfig.d->iap_type = state_results.first().params.network_type; |
357 activeConfig.d->iap_type = state_results.first().params.network_type; |
554 activeConfig.d->service_type = state_results.first().params.service_type; |
358 activeConfig.d->service_type = state_results.first().params.service_type; |
555 activeConfig.d->service_id = state_results.first().params.service_id; |
359 activeConfig.d->service_id = state_results.first().params.service_id; |
556 activeConfig.d->service_attrs = state_results.first().params.service_attrs; |
360 activeConfig.d->service_attrs = state_results.first().params.service_attrs; |
557 activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint; |
361 activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint; |
558 activeConfig.d->state = QNetworkConfiguration::Active; |
362 activeConfig.d->state = QNetworkConfiguration::Active; |
559 activeConfig.d->isValid = true; |
363 activeConfig.d->isValid = true; |
560 currentNetworkInterface = get_network_interface(); |
364 currentNetworkInterface = get_network_interface(); |
561 |
365 |
562 Maemo::IAPConf iap_name(activeConfig.d->id); |
366 Maemo::IAPConf iap_name(activeConfig.d->id); |
563 QString name_value = iap_name.value("name").toString(); |
367 QString name_value = iap_name.value("name").toString(); |
564 if (!name_value.isEmpty()) |
368 if (!name_value.isEmpty()) |
565 activeConfig.d->name = name_value; |
369 activeConfig.d->name = name_value; |
566 else |
370 else |
567 activeConfig.d->name = activeConfig.d->id; |
371 activeConfig.d->name = activeConfig.d->id; |
568 |
372 |
569 |
|
570 // Add the new active configuration to manager or update the old config |
373 // Add the new active configuration to manager or update the old config |
571 mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager; |
374 mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager; |
572 if (!(mgr->accessPointConfigurations.contains(activeConfig.d->id))) { |
375 if (!(mgr->accessPointConfigurations.contains(activeConfig.d->id))) { |
573 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = activeConfig.d; |
376 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = activeConfig.d; |
574 mgr->accessPointConfigurations.insert(activeConfig.d->id, ptr); |
377 mgr->accessPointConfigurations.insert(activeConfig.d->id, ptr); |
1039 if (serviceConfig.isValid()) { |
823 if (serviceConfig.isValid()) { |
1040 lastError = QNetworkSession::OperationNotSupportedError; |
824 lastError = QNetworkSession::OperationNotSupportedError; |
1041 emit q->error(lastError); |
825 emit q->error(lastError); |
1042 } else { |
826 } else { |
1043 if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { |
827 if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { |
1044 state = QNetworkSession::Closing; |
828 if (!m_stopTimer.isActive()) { |
1045 emit q->stateChanged(state); |
829 Maemo::Icd icd; |
1046 |
830 #ifdef BEARER_MANAGEMENT_DEBUG |
1047 Maemo::Icd icd; |
831 qDebug() << "stopping session" << publicConfig.identifier(); |
1048 #ifdef BEARER_MANAGEMENT_DEBUG |
832 #endif |
1049 qDebug() << "stopping session" << publicConfig.identifier(); |
833 state = QNetworkSession::Closing; |
1050 #endif |
834 emit q->stateChanged(state); |
1051 icd.disconnect(ICD_CONNECTION_FLAG_APPLICATION_EVENT); |
835 |
1052 startTime = QDateTime(); |
836 opened = false; |
1053 |
837 isOpen = false; |
1054 /* Note that the state will go disconnected in |
838 |
1055 * updateStateFromActiveConfig() which gets called after |
839 icd.disconnect(ICD_CONNECTION_FLAG_APPLICATION_EVENT); |
1056 * configurationChanged is emitted (below). |
840 startTime = QDateTime(); |
1057 */ |
841 |
1058 |
842 /* Note: Session state will change to disconnected |
1059 activeConfig.d->state = QNetworkConfiguration::Discovered; |
843 * as soon as QNetworkConfigurationManager sends |
1060 QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager; |
844 * corresponding iapStateChanged signal. |
1061 mgr->configurationChanged((QNetworkConfigurationPrivate*)activeConfig.d.data()); |
845 */ |
1062 |
846 |
1063 opened = false; |
847 // Make sure that this Session will send closed signal |
1064 isOpen = false; |
848 // even though ICD connection will not ever get closed |
1065 |
849 m_stopTimer.start(ICD_SHORT_CONNECT_TIMEOUT); // 10 seconds wait |
|
850 } |
1066 } else { |
851 } else { |
1067 opened = false; |
852 opened = false; |
1068 isOpen = false; |
853 isOpen = false; |
1069 emit q->closed(); |
854 emit q->closed(); |
1070 } |
855 } |
1071 } |
856 } |
1072 } |
857 } |
1073 |
858 |
|
859 void QNetworkSessionPrivate::finishStopBySendingClosedSignal() |
|
860 { |
|
861 if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { |
|
862 state = QNetworkSession::Connected; |
|
863 emit q->stateChanged(state); |
|
864 } |
|
865 emit q->closed(); |
|
866 } |
1074 |
867 |
1075 void QNetworkSessionPrivate::migrate() |
868 void QNetworkSessionPrivate::migrate() |
1076 { |
869 { |
1077 qWarning("This platform does not support roaming (%s).", __FUNCTION__); |
870 qWarning("This platform does not support roaming (%s).", __FUNCTION__); |
1078 } |
871 } |