Doc: Modularize QtNetwork documentation.
[profile/ivi/qtbase.git] / src / network / bearer / qnetworkconfigmanager.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qnetworkconfigmanager.h"
43
44 #include "qnetworkconfigmanager_p.h"
45 #include "qbearerengine_p.h"
46
47 #include <QtCore/qstringlist.h>
48 #include <QtCore/qcoreapplication.h>
49 #include <QtCore/qmutex.h>
50 #include <QtCore/qthread.h>
51 #include <QtCore/private/qcoreapplication_p.h>
52
53 #ifndef QT_NO_BEARERMANAGEMENT
54
55 QT_BEGIN_NAMESPACE
56
57 static QBasicAtomicPointer<QNetworkConfigurationManagerPrivate> connManager_ptr;
58
59 static void connManager_cleanup()
60 {
61     // this is not atomic or thread-safe!
62     QNetworkConfigurationManagerPrivate *cmp = connManager_ptr.fetchAndStoreAcquire(0);
63     if (cmp)
64         cmp->cleanup();
65 }
66
67 void QNetworkConfigurationManagerPrivate::addPostRoutine()
68 {
69     qAddPostRoutine(connManager_cleanup);
70 }
71
72 QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate()
73 {
74     QNetworkConfigurationManagerPrivate *ptr = connManager_ptr.loadAcquire();
75     if (!ptr) {
76         static QBasicMutex connManager_mutex;
77         QMutexLocker locker(&connManager_mutex);
78         if (!(ptr = connManager_ptr.loadAcquire())) {
79             ptr = new QNetworkConfigurationManagerPrivate;
80
81             if (QCoreApplicationPrivate::mainThread() == QThread::currentThread()) {
82                 // right thread or no main thread yet
83                 ptr->addPostRoutine();
84                 ptr->initialize();
85             } else {
86                 // wrong thread, we need to make the main thread do this
87                 QObject *obj = new QObject;
88                 QObject::connect(obj, SIGNAL(destroyed()), ptr, SLOT(addPostRoutine()), Qt::DirectConnection);
89                 ptr->initialize(); // this moves us to the right thread
90                 obj->moveToThread(QCoreApplicationPrivate::mainThread());
91                 obj->deleteLater();
92             }
93
94             connManager_ptr.storeRelease(ptr);
95         }
96     }
97     return ptr;
98 }
99
100 /*!
101     \class QNetworkConfigurationManager
102
103     \brief The QNetworkConfigurationManager class manages the network configurations provided
104     by the system.
105
106     \since 4.7
107
108     \inmodule QtNetwork
109     \ingroup network
110
111     QNetworkConfigurationManager provides access to the network configurations known to the system and
112     enables applications to detect the system capabilities (with regards to network sessions) at runtime.
113
114     A QNetworkConfiguration abstracts a set of configuration options describing how a
115     network interface has to be configured to connect to a particular target network.
116     QNetworkConfigurationManager maintains and updates the global list of
117     QNetworkConfigurations. Applications can access and filter this list via
118     allConfigurations(). If a new configuration is added or an existing one is removed or changed
119     the configurationAdded(), configurationRemoved() and configurationChanged() signals are emitted
120     respectively.
121
122     The defaultConfiguration() can be used when intending to immediately create a new
123     network session without caring about the particular configuration. It returns
124     a \l QNetworkConfiguration::Discovered configuration. If there are not any
125     discovered ones an invalid configuration is returned.
126
127     Some configuration updates may require some time to perform updates. A WLAN scan is
128     such an example. Unless the platform performs internal updates it may be required to
129     manually trigger configuration updates via QNetworkConfigurationManager::updateConfigurations().
130     The completion of the update process is indicted by emitting the updateCompleted()
131     signal. The update process ensures that every existing QNetworkConfiguration instance
132     is updated. There is no need to ask for a renewed configuration list via allConfigurations().
133
134     \sa QNetworkConfiguration
135 */
136
137 /*! 
138     \fn void QNetworkConfigurationManager::configurationAdded(const QNetworkConfiguration &config)
139
140     This signal is emitted whenever a new network configuration is added to the system. The new
141     configuration is specified by \a config.
142 */
143
144 /*!
145     \fn void QNetworkConfigurationManager::configurationRemoved(const QNetworkConfiguration &config)
146
147     This signal is emitted when a configuration is about to be removed from the system. The removed
148     configuration, specified by \a config, is invalid but retains name and identifier.
149 */
150
151 /*!
152     \fn void QNetworkConfigurationManager::updateCompleted()
153
154     This signal is emitted when the configuration update has been completed. Such an update can
155     be initiated via \l updateConfigurations().
156 */
157
158 /*! \fn void QNetworkConfigurationManager::configurationChanged(const QNetworkConfiguration &config)
159
160     This signal is emitted when the \l {QNetworkConfiguration::state()}{state} of \a config changes.
161 */
162
163 /*!
164     \fn void QNetworkConfigurationManager::onlineStateChanged(bool isOnline)
165
166     This signal is emitted when the device changes from online to offline mode or vice versa.
167     \a isOnline represents the new state of the device.
168
169     The state is considered to be online for as long as
170     \l{allConfigurations()}{allConfigurations}(QNetworkConfiguration::Active) returns a list with
171     at least one entry.
172 */
173
174 /*!
175     \enum QNetworkConfigurationManager::Capability
176
177     Specifies the system capabilities of the bearer API. The possible values are:
178
179     \value CanStartAndStopInterfaces Network sessions and their underlying access points can be
180                                      started and stopped. If this flag is not set QNetworkSession
181                                      can only monitor but not influence the state of access points.
182                                      On some platforms this feature may require elevated user
183                                      permissions. This option is platform specific and may not
184                                      always be available.
185     \value DirectConnectionRouting   Network sessions and their sockets can be bound to a
186                                      particular network interface. Any packet that passes through
187                                      the socket goes to the specified network interface and thus
188                                      disregards standard routing table entries. This may be useful
189                                      when two interfaces can reach overlapping IP ranges or an
190                                      application has specific needs in regards to target networks.
191                                      This option is platform specific and may not always be
192                                      available.
193     \value SystemSessionSupport      If this flag is set the underlying platform ensures that a
194                                      network interface is not shut down until the last network
195                                      session has been \l{QNetworkSession::close()}{closed()}. This
196                                      works across multiple processes. If the platform session
197                                      support is missing this API can only ensure the above behavior
198                                      for network sessions within the same process.
199                                      In general mobile platforms have such
200                                      support whereas most desktop platform lack this capability.
201     \value ApplicationLevelRoaming   The system gives applications control over the systems roaming
202                                      behavior. Applications can initiate roaming (in case the
203                                      current link is not suitable) and are consulted if the system
204                                      has identified a more suitable access point.
205     \value ForcedRoaming             The system disconnects an existing access point and reconnects
206                                      via a more suitable one. The application does not have any
207                                      control over this process and has to reconnect its active
208                                      sockets.
209     \value DataStatistics            If this flag is set QNetworkSession can provide statistics
210                                      about transmitted and received data.
211     \value NetworkSessionRequired    If this flag is set the platform requires that a network
212                                      session is created before network operations can be performed.
213 */
214
215 /*!
216     Constructs a QNetworkConfigurationManager with the given \a parent.
217
218     Note that to ensure a valid list of current configurations immediately available, updating
219     is done during construction which causes some delay.
220 */
221 QNetworkConfigurationManager::QNetworkConfigurationManager(QObject *parent)
222     : QObject(parent)
223 {
224     QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
225
226     connect(priv, SIGNAL(configurationAdded(QNetworkConfiguration)),
227             this, SIGNAL(configurationAdded(QNetworkConfiguration)));
228     connect(priv, SIGNAL(configurationRemoved(QNetworkConfiguration)),
229             this, SIGNAL(configurationRemoved(QNetworkConfiguration)));
230     connect(priv, SIGNAL(configurationChanged(QNetworkConfiguration)),
231             this, SIGNAL(configurationChanged(QNetworkConfiguration)));
232     connect(priv, SIGNAL(onlineStateChanged(bool)),
233             this, SIGNAL(onlineStateChanged(bool)));
234     connect(priv, SIGNAL(configurationUpdateComplete()),
235             this, SIGNAL(updateCompleted()));
236
237     priv->enablePolling();
238 }
239
240 /*!
241     Frees the resources associated with the QNetworkConfigurationManager object.
242 */
243 QNetworkConfigurationManager::~QNetworkConfigurationManager()
244 {
245     QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
246     if (priv)
247         priv->disablePolling();
248 }
249
250
251 /*!
252     Returns the default configuration to be used. This function always returns a discovered
253     configuration; otherwise an invalid configuration.
254
255     In some cases it may be required to call updateConfigurations() and wait for the
256     updateCompleted() signal before calling this function.
257
258     \sa allConfigurations()
259 */
260 QNetworkConfiguration QNetworkConfigurationManager::defaultConfiguration() const
261 {
262     QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
263     if (priv)
264         return priv->defaultConfiguration();
265
266     return QNetworkConfiguration();
267 }
268
269 /*!
270     Returns the list of configurations which comply with the given \a filter.
271
272     By default this function returns all (defined and undefined) configurations.
273
274     A wireless network with a particular SSID may only be accessible in a
275     certain area despite the fact that the system has a valid configuration
276     for it. Therefore the filter flag may be used to limit the list to
277     discovered and possibly connected configurations only.
278
279     If \a filter is set to zero this function returns all possible configurations.
280
281     Note that this function returns the states for all configurations as they are known at
282     the time of this function call. If for instance a configuration of type WLAN is defined
283     the system may have to perform a WLAN scan in order to determine whether it is
284     actually available. To obtain the most accurate state updateConfigurations() should
285     be used to update each configuration's state. Note that such an update may require
286     some time. It's completion is signalled by updateCompleted(). In the absence of a
287     configuration update this function returns the best estimate at the time of the call.
288     Therefore, if WLAN configurations are of interest, it is recommended that
289     updateConfigurations() is called once after QNetworkConfigurationManager
290     instantiation (WLAN scans are too time consuming to perform in constructor).
291     After this the data is kept automatically up-to-date as the system reports
292     any changes.
293 */
294 QList<QNetworkConfiguration> QNetworkConfigurationManager::allConfigurations(QNetworkConfiguration::StateFlags filter) const
295 {
296     QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
297     if (priv)
298         return priv->allConfigurations(filter);
299
300     return QList<QNetworkConfiguration>();
301 }
302
303 /*!
304     Returns the QNetworkConfiguration for \a identifier; otherwise returns an
305     invalid QNetworkConfiguration.
306
307     \sa QNetworkConfiguration::identifier()
308 */
309 QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(const QString &identifier) const
310 {
311     QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
312     if (priv)
313         return priv->configurationFromIdentifier(identifier);
314
315     return QNetworkConfiguration();
316 }
317
318 /*!
319     Returns true if the system is considered to be connected to another device via an active
320     network interface; otherwise returns false.
321
322     This is equivalent to the following code snippet:
323
324     \snippet code/src_network_bearer_qnetworkconfigmanager.cpp 0
325
326     \sa onlineStateChanged()
327 */
328 bool QNetworkConfigurationManager::isOnline() const
329 {
330     QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
331     if (priv)
332         return priv->isOnline();
333
334     return false;
335 }
336
337 /*!
338     Returns the capabilities supported by the current platform.
339 */
340 QNetworkConfigurationManager::Capabilities QNetworkConfigurationManager::capabilities() const
341 {
342     QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
343     if (priv)
344         return priv->capabilities();
345
346     return QNetworkConfigurationManager::Capabilities(0);
347 }
348
349 /*!
350     Initiates an update of all configurations. This may be used to initiate WLAN scans or other
351     time consuming updates which may be required to obtain the correct state for configurations.
352
353     This call is asynchronous. On completion of this update the updateCompleted() signal is
354     emitted. If new configurations are discovered or old ones were removed or changed the update
355     process may trigger the emission of one or multiple configurationAdded(),
356     configurationRemoved() and configurationChanged() signals.
357
358     If a configuration state changes as a result of this update all existing QNetworkConfiguration
359     instances are updated automatically.
360
361     \sa allConfigurations()
362 */
363 void QNetworkConfigurationManager::updateConfigurations()
364 {
365     QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
366     if (priv)
367         priv->performAsyncConfigurationUpdate();
368 }
369
370 #include "moc_qnetworkconfigmanager.cpp"
371
372 QT_END_NAMESPACE
373
374 #endif // QT_NO_BEARERMANAGEMENT