| 1 | /****************************************************************************
|
|---|
| 2 | **
|
|---|
| 3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
|---|
| 4 | ** All rights reserved.
|
|---|
| 5 | ** Contact: Nokia Corporation ([email protected])
|
|---|
| 6 | **
|
|---|
| 7 | ** This file is part of the plugins of the Qt Toolkit.
|
|---|
| 8 | **
|
|---|
| 9 | ** $QT_BEGIN_LICENSE:LGPL$
|
|---|
| 10 | ** Commercial Usage
|
|---|
| 11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
|---|
| 12 | ** accordance with the Qt Commercial License Agreement provided with the
|
|---|
| 13 | ** Software or, alternatively, in accordance with the terms contained in
|
|---|
| 14 | ** a written agreement between you and Nokia.
|
|---|
| 15 | **
|
|---|
| 16 | ** GNU Lesser General Public License Usage
|
|---|
| 17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
|---|
| 18 | ** General Public License version 2.1 as published by the Free Software
|
|---|
| 19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
|---|
| 20 | ** packaging of this file. Please review the following information to
|
|---|
| 21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
|---|
| 22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|---|
| 23 | **
|
|---|
| 24 | ** In addition, as a special exception, Nokia gives you certain additional
|
|---|
| 25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
|---|
| 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|---|
| 27 | **
|
|---|
| 28 | ** GNU General Public License Usage
|
|---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU
|
|---|
| 30 | ** General Public License version 3.0 as published by the Free Software
|
|---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
|---|
| 32 | ** packaging of this file. Please review the following information to
|
|---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
|---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
|---|
| 35 | **
|
|---|
| 36 | ** If you have questions regarding the use of this file, please contact
|
|---|
| 37 | ** Nokia at [email protected].
|
|---|
| 38 | ** $QT_END_LICENSE$
|
|---|
| 39 | **
|
|---|
| 40 | ****************************************************************************/
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 | #include "maemo_icd.h"
|
|---|
| 44 | #include "dbusdispatcher.h"
|
|---|
| 45 |
|
|---|
| 46 | #include <QObject>
|
|---|
| 47 | #include <QTimer>
|
|---|
| 48 | #include <QCoreApplication>
|
|---|
| 49 | #include <QEventLoop>
|
|---|
| 50 | #include <QDebug>
|
|---|
| 51 | #include <dbus/dbus.h>
|
|---|
| 52 | #include <dbus/dbus-glib-lowlevel.h>
|
|---|
| 53 |
|
|---|
| 54 | #include <stdio.h>
|
|---|
| 55 | #include <sys/time.h>
|
|---|
| 56 | #include <sys/types.h>
|
|---|
| 57 | #include <unistd.h>
|
|---|
| 58 |
|
|---|
| 59 | namespace Maemo {
|
|---|
| 60 |
|
|---|
| 61 | #undef PRINT_DEBUGINFO
|
|---|
| 62 | #ifdef PRINT_DEBUGINFO
|
|---|
| 63 | static FILE *fdebug = NULL;
|
|---|
| 64 | #define PDEBUG(fmt, args...) \
|
|---|
| 65 | do { \
|
|---|
| 66 | struct timeval tv; \
|
|---|
| 67 | gettimeofday(&tv, 0); \
|
|---|
| 68 | fprintf(fdebug, "DEBUG[%d]:%ld.%ld:%s:%s():%d: " fmt, \
|
|---|
| 69 | getpid(), \
|
|---|
| 70 | tv.tv_sec, tv.tv_usec, \
|
|---|
| 71 | __FILE__, __FUNCTION__, __LINE__, args); \
|
|---|
| 72 | fflush(fdebug); \
|
|---|
| 73 | } while(0)
|
|---|
| 74 | #else
|
|---|
| 75 | #define PDEBUG(fmt...)
|
|---|
| 76 | #endif
|
|---|
| 77 |
|
|---|
| 78 |
|
|---|
| 79 | class IcdPrivate
|
|---|
| 80 | {
|
|---|
| 81 | public:
|
|---|
| 82 | IcdPrivate(Icd *myfriend)
|
|---|
| 83 | {
|
|---|
| 84 | init(10000, IcdNewDbusInterface, myfriend);
|
|---|
| 85 | }
|
|---|
| 86 |
|
|---|
| 87 | IcdPrivate(unsigned int timeout, Icd *myfriend)
|
|---|
| 88 | {
|
|---|
| 89 | init(timeout, IcdNewDbusInterface, myfriend);
|
|---|
| 90 | }
|
|---|
| 91 |
|
|---|
| 92 | IcdPrivate(unsigned int timeout, IcdDbusInterfaceVer ver, Icd *myfriend)
|
|---|
| 93 | {
|
|---|
| 94 | Q_UNUSED(ver);
|
|---|
| 95 |
|
|---|
| 96 | /* Note that the old Icd interface is currently disabled and
|
|---|
| 97 | * the new one is always used.
|
|---|
| 98 | */
|
|---|
| 99 | init(timeout, IcdNewDbusInterface, myfriend);
|
|---|
| 100 | }
|
|---|
| 101 |
|
|---|
| 102 | ~IcdPrivate()
|
|---|
| 103 | {
|
|---|
| 104 | QObject::disconnect(mDBus,
|
|---|
| 105 | SIGNAL(signalReceived(const QString&,
|
|---|
| 106 | const QString&,
|
|---|
| 107 | const QList<QVariant>&)),
|
|---|
| 108 | icd,
|
|---|
| 109 | SLOT(icdSignalReceived(const QString&,
|
|---|
| 110 | const QString&,
|
|---|
| 111 | const QList<QVariant>&)));
|
|---|
| 112 |
|
|---|
| 113 | QObject::disconnect(mDBus,
|
|---|
| 114 | SIGNAL(callReply(const QString&,
|
|---|
| 115 | const QList<QVariant>&,
|
|---|
| 116 | const QString&)),
|
|---|
| 117 | icd,
|
|---|
| 118 | SLOT(icdCallReply(const QString&,
|
|---|
| 119 | const QList<QVariant>&,
|
|---|
| 120 | const QString&)));
|
|---|
| 121 |
|
|---|
| 122 | delete mDBus;
|
|---|
| 123 | mDBus = 0;
|
|---|
| 124 | }
|
|---|
| 125 |
|
|---|
| 126 | /* Icd2 dbus API functions */
|
|---|
| 127 | QStringList scan(icd_scan_request_flags flags,
|
|---|
| 128 | QStringList &network_types,
|
|---|
| 129 | QList<IcdScanResult>& scan_results,
|
|---|
| 130 | QString& error);
|
|---|
| 131 |
|
|---|
| 132 | uint state(QString& service_type, uint service_attrs,
|
|---|
| 133 | QString& service_id, QString& network_type,
|
|---|
| 134 | uint network_attrs, QByteArray& network_id,
|
|---|
| 135 | IcdStateResult &state_result);
|
|---|
| 136 |
|
|---|
| 137 | uint addrinfo(QString& service_type, uint service_attrs,
|
|---|
| 138 | QString& service_id, QString& network_type,
|
|---|
| 139 | uint network_attrs, QByteArray& network_id,
|
|---|
| 140 | IcdAddressInfoResult& addr_result);
|
|---|
| 141 |
|
|---|
| 142 | uint state(QList<IcdStateResult>& state_results);
|
|---|
| 143 | uint statistics(QList<IcdStatisticsResult>& stats_results);
|
|---|
| 144 | uint addrinfo(QList<IcdAddressInfoResult>& addr_results);
|
|---|
| 145 |
|
|---|
| 146 | void signalReceived(const QString& interface,
|
|---|
| 147 | const QString& signal,
|
|---|
| 148 | const QList<QVariant>& args);
|
|---|
| 149 | void callReply(const QString& method,
|
|---|
| 150 | const QList<QVariant>& args,
|
|---|
| 151 | const QString& error);
|
|---|
| 152 |
|
|---|
| 153 | public:
|
|---|
| 154 | DBusDispatcher *mDBus;
|
|---|
| 155 | QString mMethod;
|
|---|
| 156 | QString mInterface;
|
|---|
| 157 | QString mSignal;
|
|---|
| 158 | QString mError;
|
|---|
| 159 | QList<QVariant> mArgs;
|
|---|
| 160 | QList<QVariant> receivedSignals;
|
|---|
| 161 | unsigned int timeout;
|
|---|
| 162 | IcdDbusInterfaceVer icd_dbus_version;
|
|---|
| 163 | Icd *icd;
|
|---|
| 164 |
|
|---|
| 165 | void init(unsigned int dbus_timeout, IcdDbusInterfaceVer ver,
|
|---|
| 166 | Icd *myfriend)
|
|---|
| 167 | {
|
|---|
| 168 | if (ver == IcdNewDbusInterface) {
|
|---|
| 169 | mDBus = new DBusDispatcher(ICD_DBUS_API_INTERFACE,
|
|---|
| 170 | ICD_DBUS_API_PATH,
|
|---|
| 171 | ICD_DBUS_API_INTERFACE);
|
|---|
| 172 | } else {
|
|---|
| 173 | mDBus = new DBusDispatcher(ICD_DBUS_SERVICE,
|
|---|
| 174 | ICD_DBUS_PATH,
|
|---|
| 175 | ICD_DBUS_INTERFACE);
|
|---|
| 176 | }
|
|---|
| 177 | icd_dbus_version = ver;
|
|---|
| 178 |
|
|---|
| 179 | /* This connect has a side effect as it means that only one
|
|---|
| 180 | * Icd object can exists in one time. This should be fixed!
|
|---|
| 181 | */
|
|---|
| 182 | QObject::connect(mDBus,
|
|---|
| 183 | SIGNAL(signalReceived(const QString&,
|
|---|
| 184 | const QString&,
|
|---|
| 185 | const QList<QVariant>&)),
|
|---|
| 186 | myfriend,
|
|---|
| 187 | SLOT(icdSignalReceived(const QString&,
|
|---|
| 188 | const QString&,
|
|---|
| 189 | const QList<QVariant>&)));
|
|---|
| 190 |
|
|---|
| 191 | QObject::connect(mDBus,
|
|---|
| 192 | SIGNAL(callReply(const QString&,
|
|---|
| 193 | const QList<QVariant>&,
|
|---|
| 194 | const QString&)),
|
|---|
| 195 | myfriend,
|
|---|
| 196 | SLOT(icdCallReply(const QString&,
|
|---|
| 197 | const QList<QVariant>&,
|
|---|
| 198 | const QString&)));
|
|---|
| 199 |
|
|---|
| 200 | icd = myfriend;
|
|---|
| 201 | timeout = dbus_timeout;
|
|---|
| 202 |
|
|---|
| 203 | #ifdef PRINT_DEBUGINFO
|
|---|
| 204 | if (!fdebug) {
|
|---|
| 205 | fdebug = fopen("/tmp/maemoicd.log", "a+");
|
|---|
| 206 | }
|
|---|
| 207 | PDEBUG("created %s\n", "IcdPrivate");
|
|---|
| 208 | #endif
|
|---|
| 209 | }
|
|---|
| 210 |
|
|---|
| 211 | void clearState()
|
|---|
| 212 | {
|
|---|
| 213 | mMethod.clear();
|
|---|
| 214 | mInterface.clear();
|
|---|
| 215 | mSignal.clear();
|
|---|
| 216 | mError.clear();
|
|---|
| 217 | mArgs.clear();
|
|---|
| 218 | receivedSignals.clear();
|
|---|
| 219 | }
|
|---|
| 220 |
|
|---|
| 221 | bool doState();
|
|---|
| 222 | };
|
|---|
| 223 |
|
|---|
| 224 |
|
|---|
| 225 | void IcdPrivate::signalReceived(const QString& interface,
|
|---|
| 226 | const QString& signal,
|
|---|
| 227 | const QList<QVariant>& args)
|
|---|
| 228 | {
|
|---|
| 229 | // Signal handler, which simply records what has been signalled
|
|---|
| 230 | mInterface = interface;
|
|---|
| 231 | mSignal = signal;
|
|---|
| 232 | mArgs = args;
|
|---|
| 233 |
|
|---|
| 234 | //qDebug() << "signal" << signal << "received:" << args;
|
|---|
| 235 | receivedSignals << QVariant(interface) << QVariant(signal) << QVariant(args);
|
|---|
| 236 | }
|
|---|
| 237 |
|
|---|
| 238 |
|
|---|
| 239 | void IcdPrivate::callReply(const QString& method,
|
|---|
| 240 | const QList<QVariant>& /*args*/,
|
|---|
| 241 | const QString& error)
|
|---|
| 242 | {
|
|---|
| 243 | mMethod = method;
|
|---|
| 244 | mError = error;
|
|---|
| 245 | }
|
|---|
| 246 |
|
|---|
| 247 |
|
|---|
| 248 | static void get_scan_result(QList<QVariant>& args,
|
|---|
| 249 | IcdScanResult& ret)
|
|---|
| 250 | {
|
|---|
| 251 | int i=0;
|
|---|
| 252 |
|
|---|
| 253 | if (args.isEmpty())
|
|---|
| 254 | return;
|
|---|
| 255 |
|
|---|
| 256 | ret.status = args[i++].toUInt();
|
|---|
| 257 | ret.timestamp = args[i++].toUInt();
|
|---|
| 258 | ret.scan.service_type = args[i++].toString();
|
|---|
| 259 | ret.service_name = args[i++].toString();
|
|---|
| 260 | ret.scan.service_attrs = args[i++].toUInt();
|
|---|
| 261 | ret.scan.service_id = args[i++].toString();
|
|---|
| 262 | ret.service_priority = args[i++].toInt();
|
|---|
| 263 | ret.scan.network_type = args[i++].toString();
|
|---|
| 264 | ret.network_name = args[i++].toString();
|
|---|
| 265 | ret.scan.network_attrs = args[i++].toUInt();
|
|---|
| 266 | ret.scan.network_id = args[i++].toByteArray();
|
|---|
| 267 | ret.network_priority = args[i++].toInt();
|
|---|
| 268 | ret.signal_strength = args[i++].toInt();
|
|---|
| 269 | ret.station_id = args[i++].toString();
|
|---|
| 270 | ret.signal_dB = args[i++].toInt();
|
|---|
| 271 | }
|
|---|
| 272 |
|
|---|
| 273 |
|
|---|
| 274 | QStringList IcdPrivate::scan(icd_scan_request_flags flags,
|
|---|
| 275 | QStringList &network_types,
|
|---|
| 276 | QList<IcdScanResult>& scan_results,
|
|---|
| 277 | QString& error)
|
|---|
| 278 | {
|
|---|
| 279 | Q_UNUSED(network_types);
|
|---|
| 280 |
|
|---|
| 281 | QStringList scanned_types;
|
|---|
| 282 | QTimer timer;
|
|---|
| 283 | QVariant reply;
|
|---|
| 284 | QVariantList vl;
|
|---|
| 285 | bool last_result = false;
|
|---|
| 286 | IcdScanResult result;
|
|---|
| 287 | int all_waited;
|
|---|
| 288 |
|
|---|
| 289 | clearState();
|
|---|
| 290 | reply = mDBus->call(ICD_DBUS_API_SCAN_REQ, (uint)flags);
|
|---|
| 291 | if (reply.type() != QVariant::List)
|
|---|
| 292 | return scanned_types;
|
|---|
| 293 | vl = reply.toList();
|
|---|
| 294 | if (vl.isEmpty()) {
|
|---|
| 295 | error = "Scan did not return anything.";
|
|---|
| 296 | return scanned_types;
|
|---|
| 297 | }
|
|---|
| 298 | reply = vl.first();
|
|---|
| 299 | scanned_types = reply.toStringList();
|
|---|
| 300 | //qDebug() << "Scanning:" << scanned_types;
|
|---|
| 301 | all_waited = scanned_types.size();
|
|---|
| 302 |
|
|---|
| 303 | timer.setSingleShot(true);
|
|---|
| 304 | timer.start(timeout);
|
|---|
| 305 |
|
|---|
| 306 | scan_results.clear();
|
|---|
| 307 | while (!last_result) {
|
|---|
| 308 | while (timer.isActive() && mInterface.isEmpty() && mError.isEmpty()) {
|
|---|
| 309 | QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
|
|---|
| 310 | }
|
|---|
| 311 |
|
|---|
| 312 | if (!timer.isActive()) {
|
|---|
| 313 | //qDebug() << "Timeout happened";
|
|---|
| 314 | break;
|
|---|
| 315 | }
|
|---|
| 316 |
|
|---|
| 317 | if (mSignal != ICD_DBUS_API_SCAN_SIG) {
|
|---|
| 318 | //qDebug() << "Received" << mSignal << "while waiting" << ICD_DBUS_API_SCAN_SIG << ", ignoring";
|
|---|
| 319 | mInterface.clear();
|
|---|
| 320 | continue;
|
|---|
| 321 | }
|
|---|
| 322 |
|
|---|
| 323 | if (mError.isEmpty()) {
|
|---|
| 324 | QString msgInterface = receivedSignals.takeFirst().toString();
|
|---|
| 325 | QString msgSignal = receivedSignals.takeFirst().toString();
|
|---|
| 326 | QList<QVariant> msgArgs = receivedSignals.takeFirst().toList();
|
|---|
| 327 | //qDebug() << "Signal" << msgSignal << "received.";
|
|---|
| 328 | //qDebug() << "Params:" << msgArgs;
|
|---|
| 329 |
|
|---|
| 330 | while (!msgSignal.isEmpty()) {
|
|---|
| 331 | get_scan_result(msgArgs, result);
|
|---|
| 332 |
|
|---|
| 333 | #if 0
|
|---|
| 334 | qDebug() << "Received: " <<
|
|---|
| 335 | "status =" << result.status <<
|
|---|
| 336 | ", timestamp =" << result.timestamp <<
|
|---|
| 337 | ", service_type =" << result.scan.service_type <<
|
|---|
| 338 | ", service_name =" << result.service_name <<
|
|---|
| 339 | ", service_attrs =" << result.scan.service_attrs <<
|
|---|
| 340 | ", service_id =" << result.scan.service_id <<
|
|---|
| 341 | ", service_priority =" << result.service_priority <<
|
|---|
| 342 | ", network_type =" << result.scan.network_type <<
|
|---|
| 343 | ", network_name =" << result.network_name <<
|
|---|
| 344 | ", network_attrs =" << result.scan.network_attrs <<
|
|---|
| 345 | ", network_id =" << "-" <<
|
|---|
| 346 | ", network_priority =" << result.network_priority <<
|
|---|
| 347 | ", signal_strength =" << result.signal_strength <<
|
|---|
| 348 | ", station_id =" << result.station_id <<
|
|---|
| 349 | ", signal_dB =" << result.signal_dB;
|
|---|
| 350 | #endif
|
|---|
| 351 |
|
|---|
| 352 | if (result.status == ICD_SCAN_COMPLETE) {
|
|---|
| 353 | //qDebug() << "waited =" << all_waited;
|
|---|
| 354 | if (--all_waited == 0) {
|
|---|
| 355 | last_result = true;
|
|---|
| 356 | break;
|
|---|
| 357 | }
|
|---|
| 358 | } else
|
|---|
| 359 | scan_results << result;
|
|---|
| 360 |
|
|---|
| 361 | if (receivedSignals.isEmpty())
|
|---|
| 362 | break;
|
|---|
| 363 |
|
|---|
| 364 | msgInterface = receivedSignals.takeFirst().toString();
|
|---|
| 365 | msgSignal = receivedSignals.takeFirst().toString();
|
|---|
| 366 | msgArgs = receivedSignals.takeFirst().toList();
|
|---|
| 367 | }
|
|---|
| 368 | mInterface.clear();
|
|---|
| 369 |
|
|---|
| 370 | } else {
|
|---|
| 371 | qWarning() << "Error while scanning:" << mError;
|
|---|
| 372 | break;
|
|---|
| 373 | }
|
|---|
| 374 | }
|
|---|
| 375 | timer.stop();
|
|---|
| 376 |
|
|---|
| 377 | error = mError;
|
|---|
| 378 | return scanned_types;
|
|---|
| 379 | }
|
|---|
| 380 |
|
|---|
| 381 |
|
|---|
| 382 | static void get_state_all_result(QList<QVariant>& args,
|
|---|
| 383 | IcdStateResult& ret)
|
|---|
| 384 | {
|
|---|
| 385 | int i=0;
|
|---|
| 386 |
|
|---|
| 387 | ret.params.service_type = args[i++].toString();
|
|---|
| 388 | ret.params.service_attrs = args[i++].toUInt();
|
|---|
| 389 | ret.params.service_id = args[i++].toString();
|
|---|
| 390 | ret.params.network_type = args[i++].toString();
|
|---|
| 391 | ret.params.network_attrs = args[i++].toUInt();
|
|---|
| 392 | ret.params.network_id = args[i++].toByteArray();
|
|---|
| 393 | ret.error = args[i++].toString();
|
|---|
| 394 | ret.state = args[i++].toInt();
|
|---|
| 395 | }
|
|---|
| 396 |
|
|---|
| 397 |
|
|---|
| 398 | static void get_state_all_result2(QList<QVariant>& args,
|
|---|
| 399 | IcdStateResult& ret)
|
|---|
| 400 | {
|
|---|
| 401 | int i=0;
|
|---|
| 402 |
|
|---|
| 403 | ret.params.network_type = args[i++].toString();
|
|---|
| 404 | ret.state = args[i++].toInt();
|
|---|
| 405 |
|
|---|
| 406 | // Initialize the other values so that the caller can
|
|---|
| 407 | // notice we only returned partial status
|
|---|
| 408 | ret.params.service_type = QString();
|
|---|
| 409 | ret.params.service_attrs = 0;
|
|---|
| 410 | ret.params.service_id = QString();
|
|---|
| 411 | ret.params.network_attrs = 0;
|
|---|
| 412 | ret.params.network_id = QByteArray();
|
|---|
| 413 | ret.error = QString();
|
|---|
| 414 | }
|
|---|
| 415 |
|
|---|
| 416 |
|
|---|
| 417 | uint IcdPrivate::state(QString& service_type, uint service_attrs,
|
|---|
| 418 | QString& service_id, QString& network_type,
|
|---|
| 419 | uint network_attrs, QByteArray& network_id,
|
|---|
| 420 | IcdStateResult& state_result)
|
|---|
| 421 | {
|
|---|
| 422 | QTimer timer;
|
|---|
| 423 | QVariant reply;
|
|---|
| 424 | uint total_signals;
|
|---|
| 425 | QVariantList vl;
|
|---|
| 426 |
|
|---|
| 427 | clearState();
|
|---|
| 428 |
|
|---|
| 429 | reply = mDBus->call(ICD_DBUS_API_STATE_REQ,
|
|---|
| 430 | service_type, service_attrs, service_id,
|
|---|
| 431 | network_type, network_attrs, network_id);
|
|---|
| 432 | if (reply.type() != QVariant::List)
|
|---|
| 433 | return 0;
|
|---|
| 434 | vl = reply.toList();
|
|---|
| 435 | if (vl.isEmpty())
|
|---|
| 436 | return 0;
|
|---|
| 437 | reply = vl.first();
|
|---|
| 438 | total_signals = reply.toUInt();
|
|---|
| 439 | if (!total_signals)
|
|---|
| 440 | return 0;
|
|---|
| 441 |
|
|---|
| 442 | timer.setSingleShot(true);
|
|---|
| 443 | timer.start(timeout);
|
|---|
| 444 |
|
|---|
| 445 | mInterface.clear();
|
|---|
| 446 | while (timer.isActive() && mInterface.isEmpty()) {
|
|---|
| 447 | QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
|
|---|
| 448 |
|
|---|
| 449 | if (mSignal != ICD_DBUS_API_STATE_SIG) {
|
|---|
| 450 | mInterface.clear();
|
|---|
| 451 | continue;
|
|---|
| 452 | }
|
|---|
| 453 | }
|
|---|
| 454 |
|
|---|
| 455 | timer.stop();
|
|---|
| 456 |
|
|---|
| 457 | if (mError.isEmpty()) {
|
|---|
| 458 | if (!mArgs.isEmpty()) {
|
|---|
| 459 | if (mArgs.size()>2)
|
|---|
| 460 | get_state_all_result(mArgs, state_result);
|
|---|
| 461 | else {
|
|---|
| 462 | // We are not connected as we did not get the status we asked
|
|---|
| 463 | return 0;
|
|---|
| 464 | }
|
|---|
| 465 | }
|
|---|
| 466 | } else {
|
|---|
| 467 | qWarning() << "Error:" << mError;
|
|---|
| 468 | }
|
|---|
| 469 |
|
|---|
| 470 | // The returned value should be one because we asked for one state
|
|---|
| 471 | return total_signals;
|
|---|
| 472 | }
|
|---|
| 473 |
|
|---|
| 474 |
|
|---|
| 475 | /* Special version of the state() call which does not call event loop.
|
|---|
| 476 | * Needed in order to fix NB#175098 where Qt4.7 webkit crashes because event
|
|---|
| 477 | * loop is run when webkit does not expect it. This function is called from
|
|---|
| 478 | * bearer management API syncStateWithInterface() in QNetworkSession
|
|---|
| 479 | * constructor.
|
|---|
| 480 | */
|
|---|
| 481 | uint IcdPrivate::state(QList<IcdStateResult>& state_results)
|
|---|
| 482 | {
|
|---|
| 483 | QVariant reply;
|
|---|
| 484 | QVariantList vl;
|
|---|
| 485 | uint signals_left, total_signals;
|
|---|
| 486 | IcdStateResult result;
|
|---|
| 487 | time_t started;
|
|---|
| 488 | int timeout_secs = timeout / 1000;
|
|---|
| 489 |
|
|---|
| 490 | PDEBUG("%s\n", "state_results");
|
|---|
| 491 |
|
|---|
| 492 | clearState();
|
|---|
| 493 | reply = mDBus->call(ICD_DBUS_API_STATE_REQ);
|
|---|
| 494 | if (reply.type() != QVariant::List)
|
|---|
| 495 | return 0;
|
|---|
| 496 | vl = reply.toList();
|
|---|
| 497 | if (vl.isEmpty())
|
|---|
| 498 | return 0;
|
|---|
| 499 | reply = vl.first();
|
|---|
| 500 | signals_left = total_signals = reply.toUInt();
|
|---|
| 501 | if (!signals_left)
|
|---|
| 502 | return 0;
|
|---|
| 503 |
|
|---|
| 504 | started = time(0);
|
|---|
| 505 | state_results.clear();
|
|---|
| 506 | mError.clear();
|
|---|
| 507 | while (signals_left) {
|
|---|
| 508 | mInterface.clear();
|
|---|
| 509 | while ((time(0)<=(started+timeout_secs)) && mInterface.isEmpty()) {
|
|---|
| 510 | mDBus->synchronousDispatch(1000);
|
|---|
| 511 | QCoreApplication::sendPostedEvents(icd, QEvent::MetaCall);
|
|---|
| 512 | }
|
|---|
| 513 |
|
|---|
| 514 | if (time(0)>(started+timeout_secs)) {
|
|---|
| 515 | total_signals = 0;
|
|---|
| 516 | break;
|
|---|
| 517 | }
|
|---|
| 518 |
|
|---|
| 519 | if (mSignal != ICD_DBUS_API_STATE_SIG) {
|
|---|
| 520 | continue;
|
|---|
| 521 | }
|
|---|
| 522 |
|
|---|
| 523 | if (mError.isEmpty()) {
|
|---|
| 524 | if (!mArgs.isEmpty()) {
|
|---|
| 525 | if (mArgs.size()==2)
|
|---|
| 526 | get_state_all_result2(mArgs, result);
|
|---|
| 527 | else
|
|---|
| 528 | get_state_all_result(mArgs, result);
|
|---|
| 529 | state_results << result;
|
|---|
| 530 | }
|
|---|
| 531 | signals_left--;
|
|---|
| 532 | } else {
|
|---|
| 533 | qWarning() << "Error:" << mError;
|
|---|
| 534 | break;
|
|---|
| 535 | }
|
|---|
| 536 | }
|
|---|
| 537 |
|
|---|
| 538 | PDEBUG("total_signals=%d\n", total_signals);
|
|---|
| 539 | return total_signals;
|
|---|
| 540 | }
|
|---|
| 541 |
|
|---|
| 542 |
|
|---|
| 543 | static void get_statistics_all_result(QList<QVariant>& args,
|
|---|
| 544 | IcdStatisticsResult& ret)
|
|---|
| 545 | {
|
|---|
| 546 | int i=0;
|
|---|
| 547 |
|
|---|
| 548 | if (args.isEmpty())
|
|---|
| 549 | return;
|
|---|
| 550 |
|
|---|
| 551 | ret.params.service_type = args[i++].toString();
|
|---|
| 552 | ret.params.service_attrs = args[i++].toUInt();
|
|---|
| 553 | ret.params.service_id = args[i++].toString();
|
|---|
| 554 | ret.params.network_type = args[i++].toString();
|
|---|
| 555 | ret.params.network_attrs = args[i++].toUInt();
|
|---|
| 556 | ret.params.network_id = args[i++].toByteArray();
|
|---|
| 557 | ret.time_active = args[i++].toUInt();
|
|---|
| 558 | ret.signal_strength = (enum icd_nw_levels)args[i++].toUInt();
|
|---|
| 559 | ret.bytes_sent = args[i++].toUInt();
|
|---|
| 560 | ret.bytes_received = args[i++].toUInt();
|
|---|
| 561 | }
|
|---|
| 562 |
|
|---|
| 563 |
|
|---|
| 564 | uint IcdPrivate::statistics(QList<IcdStatisticsResult>& stats_results)
|
|---|
| 565 | {
|
|---|
| 566 | QTimer timer;
|
|---|
| 567 | QVariant reply;
|
|---|
| 568 | QVariantList vl;
|
|---|
| 569 | uint signals_left, total_signals;
|
|---|
| 570 | IcdStatisticsResult result;
|
|---|
| 571 |
|
|---|
| 572 | clearState();
|
|---|
| 573 | reply = mDBus->call(ICD_DBUS_API_STATISTICS_REQ);
|
|---|
| 574 | if (reply.type() != QVariant::List)
|
|---|
| 575 | return 0;
|
|---|
| 576 | vl = reply.toList();
|
|---|
| 577 | if (vl.isEmpty())
|
|---|
| 578 | return 0;
|
|---|
| 579 | reply = vl.first();
|
|---|
| 580 | if (reply.type() != QVariant::UInt)
|
|---|
| 581 | return 0;
|
|---|
| 582 | signals_left = total_signals = reply.toUInt();
|
|---|
| 583 |
|
|---|
| 584 | if (!signals_left)
|
|---|
| 585 | return 0;
|
|---|
| 586 |
|
|---|
| 587 | timer.setSingleShot(true);
|
|---|
| 588 | timer.start(timeout);
|
|---|
| 589 | stats_results.clear();
|
|---|
| 590 | while (signals_left) {
|
|---|
| 591 | mInterface.clear();
|
|---|
| 592 | while (timer.isActive() && mInterface.isEmpty()) {
|
|---|
| 593 | QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
|
|---|
| 594 | }
|
|---|
| 595 |
|
|---|
| 596 | if (!timer.isActive()) {
|
|---|
| 597 | total_signals = 0;
|
|---|
| 598 | break;
|
|---|
| 599 | }
|
|---|
| 600 |
|
|---|
| 601 | if (mSignal != ICD_DBUS_API_STATISTICS_SIG) {
|
|---|
| 602 | continue;
|
|---|
| 603 | }
|
|---|
| 604 |
|
|---|
| 605 | if (mError.isEmpty()) {
|
|---|
| 606 | get_statistics_all_result(mArgs, result);
|
|---|
| 607 | stats_results << result;
|
|---|
| 608 | signals_left--;
|
|---|
| 609 | } else {
|
|---|
| 610 | qWarning() << "Error:" << mError;
|
|---|
| 611 | break;
|
|---|
| 612 | }
|
|---|
| 613 | }
|
|---|
| 614 | timer.stop();
|
|---|
| 615 |
|
|---|
| 616 | return total_signals;
|
|---|
| 617 | }
|
|---|
| 618 |
|
|---|
| 619 |
|
|---|
| 620 | static void get_addrinfo_all_result(QList<QVariant>& args,
|
|---|
| 621 | IcdAddressInfoResult& ret)
|
|---|
| 622 | {
|
|---|
| 623 | int i=0;
|
|---|
| 624 |
|
|---|
| 625 | if (args.isEmpty())
|
|---|
| 626 | return;
|
|---|
| 627 |
|
|---|
| 628 | ret.params.service_type = args[i++].toString();
|
|---|
| 629 | ret.params.service_attrs = args[i++].toUInt();
|
|---|
| 630 | ret.params.service_id = args[i++].toString();
|
|---|
| 631 | ret.params.network_type = args[i++].toString();
|
|---|
| 632 | ret.params.network_attrs = args[i++].toUInt();
|
|---|
| 633 | ret.params.network_id = args[i++].toByteArray();
|
|---|
| 634 |
|
|---|
| 635 | QVariantList vl = args[i].toList();
|
|---|
| 636 | QVariant reply = vl.first();
|
|---|
| 637 | QList<QVariant> lst = reply.toList();
|
|---|
| 638 | for (int k=0; k<lst.size()/6; k=k+6) {
|
|---|
| 639 | IcdIPInformation ip_info;
|
|---|
| 640 | ip_info.address = lst[k].toString();
|
|---|
| 641 | ip_info.netmask = lst[k++].toString();
|
|---|
| 642 | ip_info.default_gateway = lst[k++].toString();
|
|---|
| 643 | ip_info.dns1 = lst[k++].toString();
|
|---|
| 644 | ip_info.dns2 = lst[k++].toString();
|
|---|
| 645 | ip_info.dns3 = lst[k++].toString();
|
|---|
| 646 |
|
|---|
| 647 | ret.ip_info << ip_info;
|
|---|
| 648 | }
|
|---|
| 649 | }
|
|---|
| 650 |
|
|---|
| 651 |
|
|---|
| 652 | /* Special version of the addrinfo() call which does not call event loop.
|
|---|
| 653 | * Needed in order to fix NB#175098 where Qt4.7 webkit crashes because event
|
|---|
| 654 | * loop is run when webkit does not expect it. This function is called from
|
|---|
| 655 | * bearer management API syncStateWithInterface() in QNetworkSession
|
|---|
| 656 | * constructor.
|
|---|
| 657 | */
|
|---|
| 658 | uint IcdPrivate::addrinfo(QList<IcdAddressInfoResult>& addr_results)
|
|---|
| 659 | {
|
|---|
| 660 | QVariant reply;
|
|---|
| 661 | QVariantList vl;
|
|---|
| 662 | uint signals_left, total_signals;
|
|---|
| 663 | IcdAddressInfoResult result;
|
|---|
| 664 | time_t started;
|
|---|
| 665 | int timeout_secs = timeout / 1000;
|
|---|
| 666 |
|
|---|
| 667 | PDEBUG("%s\n", "addr_results");
|
|---|
| 668 |
|
|---|
| 669 | clearState();
|
|---|
| 670 | reply = mDBus->call(ICD_DBUS_API_ADDRINFO_REQ);
|
|---|
| 671 | if (reply.type() != QVariant::List)
|
|---|
| 672 | return 0;
|
|---|
| 673 | vl = reply.toList();
|
|---|
| 674 | if (vl.isEmpty())
|
|---|
| 675 | return 0;
|
|---|
| 676 | reply = vl.first();
|
|---|
| 677 | if (reply.type() != QVariant::UInt)
|
|---|
| 678 | return 0;
|
|---|
| 679 | signals_left = total_signals = reply.toUInt();
|
|---|
| 680 | if (!signals_left)
|
|---|
| 681 | return 0;
|
|---|
| 682 |
|
|---|
| 683 | started = time(0);
|
|---|
| 684 | addr_results.clear();
|
|---|
| 685 | while (signals_left) {
|
|---|
| 686 | mInterface.clear();
|
|---|
| 687 | while ((time(0)<=(started+timeout_secs)) && mInterface.isEmpty()) {
|
|---|
| 688 | mDBus->synchronousDispatch(1000);
|
|---|
| 689 | QCoreApplication::sendPostedEvents(icd, QEvent::MetaCall);
|
|---|
| 690 | }
|
|---|
| 691 |
|
|---|
| 692 | if (time(0)>(started+timeout_secs)) {
|
|---|
| 693 | total_signals = 0;
|
|---|
| 694 | break;
|
|---|
| 695 | }
|
|---|
| 696 |
|
|---|
| 697 | if (mSignal != ICD_DBUS_API_ADDRINFO_SIG) {
|
|---|
| 698 | continue;
|
|---|
| 699 | }
|
|---|
| 700 |
|
|---|
| 701 | if (mError.isEmpty()) {
|
|---|
| 702 | get_addrinfo_all_result(mArgs, result);
|
|---|
| 703 | addr_results << result;
|
|---|
| 704 | signals_left--;
|
|---|
| 705 | } else {
|
|---|
| 706 | qWarning() << "Error:" << mError;
|
|---|
| 707 | break;
|
|---|
| 708 | }
|
|---|
| 709 | }
|
|---|
| 710 |
|
|---|
| 711 | PDEBUG("total_signals=%d\n", total_signals);
|
|---|
| 712 | return total_signals;
|
|---|
| 713 | }
|
|---|
| 714 |
|
|---|
| 715 |
|
|---|
| 716 | uint IcdPrivate::addrinfo(QString& service_type, uint service_attrs,
|
|---|
| 717 | QString& service_id, QString& network_type,
|
|---|
| 718 | uint network_attrs, QByteArray& network_id,
|
|---|
| 719 | IcdAddressInfoResult& addr_result)
|
|---|
| 720 | {
|
|---|
| 721 | QTimer timer;
|
|---|
| 722 | QVariant reply;
|
|---|
| 723 | uint total_signals;
|
|---|
| 724 | QVariantList vl;
|
|---|
| 725 |
|
|---|
| 726 | clearState();
|
|---|
| 727 |
|
|---|
| 728 | reply = mDBus->call(ICD_DBUS_API_ADDRINFO_REQ,
|
|---|
| 729 | service_type, service_attrs, service_id,
|
|---|
| 730 | network_type, network_attrs, network_id);
|
|---|
| 731 | if (reply.type() != QVariant::List)
|
|---|
| 732 | return 0;
|
|---|
| 733 | vl = reply.toList();
|
|---|
| 734 | if (vl.isEmpty())
|
|---|
| 735 | return 0;
|
|---|
| 736 | reply = vl.first();
|
|---|
| 737 | total_signals = reply.toUInt();
|
|---|
| 738 |
|
|---|
| 739 | if (!total_signals)
|
|---|
| 740 | return 0;
|
|---|
| 741 |
|
|---|
| 742 | timer.setSingleShot(true);
|
|---|
| 743 | timer.start(timeout);
|
|---|
| 744 |
|
|---|
| 745 | mInterface.clear();
|
|---|
| 746 | while (timer.isActive() && mInterface.isEmpty()) {
|
|---|
| 747 | QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
|
|---|
| 748 |
|
|---|
| 749 | if (mSignal != ICD_DBUS_API_ADDRINFO_SIG) {
|
|---|
| 750 | mInterface.clear();
|
|---|
| 751 | continue;
|
|---|
| 752 | }
|
|---|
| 753 | }
|
|---|
| 754 |
|
|---|
| 755 | timer.stop();
|
|---|
| 756 |
|
|---|
| 757 | if (mError.isEmpty()) {
|
|---|
| 758 | get_addrinfo_all_result(mArgs, addr_result);
|
|---|
| 759 | } else {
|
|---|
| 760 | qWarning() << "Error:" << mError;
|
|---|
| 761 | }
|
|---|
| 762 |
|
|---|
| 763 | // The returned value should be one because we asked for one addrinfo
|
|---|
| 764 | return total_signals;
|
|---|
| 765 | }
|
|---|
| 766 |
|
|---|
| 767 |
|
|---|
| 768 | Icd::Icd(QObject *parent)
|
|---|
| 769 | : QObject(parent), d(new IcdPrivate(this))
|
|---|
| 770 | {
|
|---|
| 771 | }
|
|---|
| 772 |
|
|---|
| 773 | Icd::Icd(unsigned int timeout, QObject *parent)
|
|---|
| 774 | : QObject(parent), d(new IcdPrivate(timeout, this))
|
|---|
| 775 | {
|
|---|
| 776 | }
|
|---|
| 777 |
|
|---|
| 778 | Icd::Icd(unsigned int timeout, IcdDbusInterfaceVer ver, QObject *parent)
|
|---|
| 779 | : QObject(parent), d(new IcdPrivate(timeout, ver, this))
|
|---|
| 780 | {
|
|---|
| 781 | }
|
|---|
| 782 |
|
|---|
| 783 | Icd::~Icd()
|
|---|
| 784 | {
|
|---|
| 785 | delete d;
|
|---|
| 786 | }
|
|---|
| 787 |
|
|---|
| 788 |
|
|---|
| 789 | QStringList Icd::scan(icd_scan_request_flags flags,
|
|---|
| 790 | QStringList &network_types,
|
|---|
| 791 | QList<IcdScanResult>& scan_results,
|
|---|
| 792 | QString& error)
|
|---|
| 793 | {
|
|---|
| 794 | return d->scan(flags, network_types, scan_results, error);
|
|---|
| 795 | }
|
|---|
| 796 |
|
|---|
| 797 |
|
|---|
| 798 | uint Icd::state(QString& service_type, uint service_attrs,
|
|---|
| 799 | QString& service_id, QString& network_type,
|
|---|
| 800 | uint network_attrs, QByteArray& network_id,
|
|---|
| 801 | IcdStateResult &state_result)
|
|---|
| 802 | {
|
|---|
| 803 | return d->state(service_type, service_attrs, service_id,
|
|---|
| 804 | network_type, network_attrs, network_id,
|
|---|
| 805 | state_result);
|
|---|
| 806 | }
|
|---|
| 807 |
|
|---|
| 808 |
|
|---|
| 809 | uint Icd::addrinfo(QString& service_type, uint service_attrs,
|
|---|
| 810 | QString& service_id, QString& network_type,
|
|---|
| 811 | uint network_attrs, QByteArray& network_id,
|
|---|
| 812 | IcdAddressInfoResult& addr_result)
|
|---|
| 813 | {
|
|---|
| 814 | return d->addrinfo(service_type, service_attrs, service_id,
|
|---|
| 815 | network_type, network_attrs, network_id,
|
|---|
| 816 | addr_result);
|
|---|
| 817 | }
|
|---|
| 818 |
|
|---|
| 819 |
|
|---|
| 820 | uint Icd::state(QList<IcdStateResult>& state_results)
|
|---|
| 821 | {
|
|---|
| 822 | return d->state(state_results);
|
|---|
| 823 | }
|
|---|
| 824 |
|
|---|
| 825 |
|
|---|
| 826 | uint Icd::statistics(QList<IcdStatisticsResult>& stats_results)
|
|---|
| 827 | {
|
|---|
| 828 | return d->statistics(stats_results);
|
|---|
| 829 | }
|
|---|
| 830 |
|
|---|
| 831 |
|
|---|
| 832 | uint Icd::addrinfo(QList<IcdAddressInfoResult>& addr_results)
|
|---|
| 833 | {
|
|---|
| 834 | return d->addrinfo(addr_results);
|
|---|
| 835 | }
|
|---|
| 836 |
|
|---|
| 837 |
|
|---|
| 838 | void Icd::icdSignalReceived(const QString& interface,
|
|---|
| 839 | const QString& signal,
|
|---|
| 840 | const QList<QVariant>& args)
|
|---|
| 841 | {
|
|---|
| 842 | d->signalReceived(interface, signal, args);
|
|---|
| 843 | }
|
|---|
| 844 |
|
|---|
| 845 |
|
|---|
| 846 | void Icd::icdCallReply(const QString& method,
|
|---|
| 847 | const QList<QVariant>& args,
|
|---|
| 848 | const QString& error)
|
|---|
| 849 | {
|
|---|
| 850 | d->callReply(method, args, error);
|
|---|
| 851 | }
|
|---|
| 852 |
|
|---|
| 853 | } // Maemo namespace
|
|---|
| 854 |
|
|---|
| 855 |
|
|---|