Qt 4.8
qbbengine.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Research In Motion
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qbbengine.h"
43 #include "../qnetworksession_impl.h"
44 
45 #include <QDebug>
46 #include <QThreadStorage>
47 #include <QStringList>
48 #include <QTimer>
49 
50 #include <bps/netstatus.h>
51 
52 #ifndef QT_NO_BEARERMANAGEMENT
53 
54 #ifdef QBBENGINE_DEBUG
55 #define qBearerDebug qDebug
56 #else
57 #define qBearerDebug QT_NO_QDEBUG_MACRO
58 #endif
59 
61 {
62  static inline void cleanup(netstatus_interface_list_t *list)
63  {
64  netstatus_free_interfaces(list);
65  }
66 };
67 
69 {
70  static inline void cleanup(char *interface)
71  {
72  bps_free(interface);
73  }
74 };
75 
77 {
79  instance(engine) {}
80 
82 };
83 
85 
87 interfaceType(netstatus_interface_type_t type)
88 {
89  switch (type) {
90  case NETSTATUS_INTERFACE_TYPE_USB:
91  case NETSTATUS_INTERFACE_TYPE_WIRED:
93 
94  case NETSTATUS_INTERFACE_TYPE_WIFI:
96 
97  case NETSTATUS_INTERFACE_TYPE_BLUETOOTH_DUN:
99 
100  case NETSTATUS_INTERFACE_TYPE_CELLULAR:
101  //### TODO not sure which BearerType would be the best
102  //to return here. We need to be able to get more
103  //information on the bearer type in order to return
104  //the exact match.
106 
107  case NETSTATUS_INTERFACE_TYPE_VPN:
108  case NETSTATUS_INTERFACE_TYPE_BB:
109  case NETSTATUS_INTERFACE_TYPE_UNKNOWN:
110  break;
111  }
112 
114 }
115 
117 {
118  return QLatin1String("bps:") + name;
119 }
120 
122 
123 
125  QBearerEngineImpl(parent),
126  previousEventFilter(0),
127  pollingRequired(false),
128  initialized(false)
129 {
130 }
131 
133 {
135 }
136 
137 
139 {
140  const QMutexLocker locker(&mutex);
141 
142  return configurationInterface.value(id);
143 }
144 
146 {
147  const QMutexLocker locker(&mutex);
148 
149  return configurationInterface.contains(id);
150 }
151 
153 {
155 }
156 
158 {
160 }
161 
163 {
164  if (initialized) {
165  qWarning() << Q_FUNC_INFO << "called, but instance already initialized.";
166  return;
167  }
168 
169  instanceStorage()->setLocalData(new EngineInstanceHolder(this));
170 
171  if (netstatus_request_events(0) != BPS_SUCCESS) {
172  qWarning() << Q_FUNC_INFO << "cannot register for network events. Polling enabled.";
173 
174  const QMutexLocker locker(&pollingMutex);
175  pollingRequired = true;
176  } else {
179  }
180 
181  doRequestUpdate();
182 }
183 
185 {
186  doRequestUpdate();
187 }
188 
190 {
191  qBearerDebug() << Q_FUNC_INFO << "entered method";
192 
193  netstatus_interface_list_t interfaceList;
194 
195  if ((netstatus_get_interfaces(&interfaceList)) != BPS_SUCCESS) {
196  qBearerDebug() << Q_FUNC_INFO << "cannot retrieve interface list";
197  return;
198  }
199 
200  const QScopedPointer<netstatus_interface_list_t,
201  NetstatusInterfaceListCleanupHelper> holder(&interfaceList);
202 
203  QSet<QString> currentConfigurations;
204 
205  for (int i = 0; i < interfaceList.num_interfaces; i++) {
206  const char *interface = interfaceList.interfaces[i];
207 
208  qBearerDebug() << Q_FUNC_INFO << "discovered interface" << interface;
209 
210  updateConfiguration(interface);
211 
212  currentConfigurations << idForName(QString::fromLatin1(interface));
213  }
214 
215  QMutexLocker locker(&mutex);
216 
217  const QStringList keys = accessPointConfigurations.uniqueKeys();
218 
219  locker.unlock();
220 
221  Q_FOREACH (const QString &id, keys) {
222  if (!currentConfigurations.contains(id))
224  }
225 
227 }
228 
230 {
231  const QMutexLocker locker(&mutex);
232 
234 
235  if (!ptr || !ptr->isValid)
237 
246 
248 }
249 
250 QNetworkConfigurationManager::Capabilities QBBEngine::capabilities() const
251 {
253 }
254 
256 {
257  return new QNetworkSessionPrivateImpl;
258 }
259 
261 {
262  char *interface = 0;
263 
264  if (netstatus_get_default_interface(&interface) != BPS_SUCCESS)
266 
267  if (!interface)
269 
271 
272  const QString id = idForName(QString::fromLatin1(interface));
273 
274  const QMutexLocker locker(&mutex);
275 
276  if (accessPointConfigurations.contains(id)) {
277  qBearerDebug() << Q_FUNC_INFO << "found default interface:" << id;
278 
279  return accessPointConfigurations.value(id);
280  }
281 
283 }
284 
286 {
287  const QMutexLocker locker(&pollingMutex);
288 
289  return pollingRequired;
290 }
291 
292 bool QBBEngine::filterEvent(void *message)
293 {
294  bps_event_t * const event = static_cast<bps_event_t *>(message);
295 
296  Q_ASSERT(event);
297 
298  QBBEngine *self = instanceStorage()->localData()->instance;
299 
300  Q_ASSERT(self);
301 
302  if (bps_event_get_domain(event) == netstatus_get_domain())
303  self->filterEvent(event);
304 
305  if (self->previousEventFilter)
306  return self->previousEventFilter(message);
307 
308  return false;
309 }
310 
311 void QBBEngine::filterEvent(bps_event_t *event)
312 {
313  Q_UNUSED(event);
314 
315  qBearerDebug() << Q_FUNC_INFO << "got update request.";
316 
317  doRequestUpdate();
318 }
319 
320 void QBBEngine::updateConfiguration(const char *interface)
321 {
322  netstatus_interface_details_t *details = 0;
323 
324  if (netstatus_get_interface_details(interface, &details) != BPS_SUCCESS) {
325  qBearerDebug() << Q_FUNC_INFO << "cannot retrieve details for interface" << interface;
326 
327  return;
328  }
329 
330  const QString name = QString::fromLatin1(netstatus_interface_get_name(details));
331  const QString id = idForName(name);
332 
333 
334  const netstatus_interface_type_t type = netstatus_interface_get_type(details);
335  const netstatus_ip_status_t ipStatus = netstatus_interface_get_ip_status(details);
336 
337  netstatus_free_interface_details(&details);
338 
339  QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Defined;
340 
341  if (ipStatus == NETSTATUS_IP_STATUS_OK)
343 
344  QMutexLocker locker(&mutex);
345 
346  if (accessPointConfigurations.contains(id)) {
348 
349  bool changed = false;
350 
351  QMutexLocker ptrLocker(&ptr->mutex);
352 
353  if (!ptr->isValid) {
354  ptr->isValid = true;
355  changed = true;
356  }
357 
358  if (ptr->name != name) {
359  ptr->name = name;
360  changed = true;
361  }
362 
363  if (ptr->id != id) {
364  ptr->id = id;
365  changed = true;
366  }
367 
368  if (ptr->state != state) {
369  ptr->state = state;
370  changed = true;
371  }
372 
373  const netstatus_ip_status_t oldIpStatus = ptr->oldIpStatus;
374  ptr->oldIpStatus = ipStatus;
375 
376  ptrLocker.unlock();
377 
378  locker.unlock();
379 
380  if (changed) {
381  qBearerDebug() << Q_FUNC_INFO << "configuration changed:" << interface;
382 
384  } else {
385  // maybe Wifi has changed but gateway not yet ready etc.
386  qBearerDebug() << Q_FUNC_INFO << "configuration has not changed.";
387  if (oldIpStatus != ipStatus) { // if IP status changed
388  if (ipStatus != NETSTATUS_IP_STATUS_OK
389  && ipStatus != NETSTATUS_IP_STATUS_ERROR_NOT_UP
390  && ipStatus != NETSTATUS_IP_STATUS_ERROR_NOT_CONFIGURED) {
391  // work around race condition in netstatus API by just checking
392  // again in 300 ms
393  QTimer::singleShot(300, this, SLOT(doRequestUpdate()));
394  }
395  }
396  }
397 
398  return;
399  }
400 
402 
403  ptr->name = name;
404  ptr->isValid = true;
405  ptr->id = id;
406  ptr->state = state;
408  ptr->bearerType = interfaceType(type);
409 
410  accessPointConfigurations.insert(id, ptr);
411  configurationInterface.insert(id, name);
412 
413  locker.unlock();
414 
415  qBearerDebug() << Q_FUNC_INFO << "configuration added:" << interface;
416 
418 }
419 
421 {
422  QMutexLocker locker(&mutex);
423 
425  accessPointConfigurations.take(id);
426 
428 
429  locker.unlock();
430 
432 }
433 
435 
436 #endif // QT_NO_BEARERMANAGEMENT
437 
BearerType
Specifies the type of bearer used by a configuration.
#define qBearerDebug
Definition: qbbengine.cpp:57
int type
Definition: qmetatype.cpp:239
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void doRequestUpdate()
Definition: qbbengine.cpp:189
EngineInstanceHolder(QBBEngine *engine)
Definition: qbbengine.cpp:78
int remove(const Key &key)
Removes all the items that have the key from the hash.
Definition: qhash.h:784
static QString idForName(const QString &name)
Definition: qbbengine.cpp:116
QNetworkConfiguration::StateFlags state
#define Q_EMIT
Definition: qobjectdefs.h:74
static QAbstractEventDispatcher * instance(QThread *thread=0)
Returns a pointer to the event dispatcher object for the specified thread.
void configurationChanged(QNetworkConfigurationPrivatePointer config)
#define SLOT(a)
Definition: qobjectdefs.h:226
void disconnectFromId(const QString &id)
Definition: qbbengine.cpp:157
void unlock()
Unlocks this mutex locker.
Definition: qmutex.h:117
void updateCompleted()
State
This enum describes the connectivity state of the session.
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QBBEngine(QObject *parent=0)
Definition: qbbengine.cpp:124
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
virtual bool event(QEvent *)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition: qobject.cpp:1200
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
QNetworkConfiguration::BearerType bearerType
QStringList keys
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
static void cleanup(netstatus_interface_list_t *list)
Definition: qbbengine.cpp:62
The QScopedPointer class stores a pointer to a dynamically allocated object, and deletes it upon dest...
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
QAbstractEventDispatcher::EventFilter previousEventFilter
Definition: qbbengine.h:99
QMutex pollingMutex
Definition: qbbengine.h:101
QNetworkConfigurationManager::Capabilities capabilities() const
Definition: qbbengine.cpp:250
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QHash< QString, QNetworkConfigurationPrivatePointer > accessPointConfigurations
bool contains(const T &value) const
Definition: qset.h:91
QBBEngine * instance
Definition: qbbengine.cpp:81
const char * name
void updateConfiguration(const char *interface)
Definition: qbbengine.cpp:320
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
void configurationAdded(QNetworkConfigurationPrivatePointer config)
Q_CORE_EXPORT void qWarning(const char *,...)
Q_INVOKABLE void requestUpdate()
Definition: qbbengine.cpp:184
static QNetworkConfiguration::BearerType interfaceType(netstatus_interface_type_t type)
Definition: qbbengine.cpp:87
const T * ptr(const T &t)
QNetworkSessionPrivate * createSessionBackend()
Definition: qbbengine.cpp:255
static void cleanup(char *interface)
Definition: qbbengine.cpp:70
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
QExplicitlySharedDataPointer< QNetworkConfigurationPrivate > QNetworkConfigurationPrivatePointer
QHash< QString, QString > configurationInterface
Definition: qbbengine.h:97
QNetworkConfiguration::Type type
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
EventFilter setEventFilter(EventFilter filter)
Replaces the event filter function for this QAbstractEventDispatcher with filter and returns the repl...
static bool filterEvent(void *message)
Definition: qbbengine.cpp:292
bool singleShot
This static function calls a slot after a given time interval.
Definition: qtimer.h:59
void configurationRemoved(QNetworkConfigurationPrivatePointer config)
Q_GLOBAL_STATIC(QThreadStorage< EngineInstanceHolder *>, instanceStorage)
QString getInterfaceFromId(const QString &id)
Definition: qbbengine.cpp:138
#define Q_FOREACH(variable, container)
Same as foreach(variable, container).
Definition: qglobal.h:2435
Q_INVOKABLE void initialize()
Definition: qbbengine.cpp:162
bool requiresPolling() const
Definition: qbbengine.cpp:285
void connectionError(const QString &id, QBearerEngineImpl::ConnectionError error)
bool initialized
Definition: qbbengine.h:104
bool pollingRequired
Definition: qbbengine.h:103
void removeConfiguration(const QString &id)
Definition: qbbengine.cpp:420
The QThreadStorage class provides per-thread data storage.
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
bool hasIdentifier(const QString &id)
Definition: qbbengine.cpp:145
void connectToId(const QString &id)
Definition: qbbengine.cpp:152
QNetworkSession::State sessionStateForId(const QString &id)
Definition: qbbengine.cpp:229
QNetworkConfigurationPrivatePointer defaultConfiguration()
Definition: qbbengine.cpp:260
#define Q_FUNC_INFO
Definition: qglobal.h:1871