2 * meegotouchcp-connman - connectivity plugin for duicontrolpanel
3 * Copyright © 2010, Intel Corporation.
5 * This program is licensed under the terms and conditions of the
6 * Apache License, version 2.0. The full text of the Apache License is at
7 * http://www.apache.org/licenses/LICENSE-2.0
10 #include "networkitem.h"
12 #include "commondbustypes.h"
16 //FIXME: could reuse these static strings for getProperties and popertyChanged
17 const char* const NetworkItemModel::Name = "Name";
18 const char* const NetworkItemModel::Security = "Security";
19 const char* const NetworkItemModel::Strength = "Strength";
20 const char* const NetworkItemModel::State = "State";
21 const char* const NetworkItemModel::Type = "Type";
22 const char* const NetworkItemModel::PassphraseRequired = "PassphraseRequired";
23 const char* const NetworkItemModel::Passphrase = "Passphrase";
24 const char* const NetworkItemModel::IPv4 = "IPv4.Configuration";
25 const char* const NetworkItemModel::IPv4Normal = "IPv4";
26 const char* const NetworkItemModel::Nameservers = "Nameservers";
27 const char* const NetworkItemModel::DeviceAddress = "DeviceAddress";
28 const char* const NetworkItemModel::Mode = "Mode";
29 const char* const NetworkItemModel::APN = "APN";
30 const char* const NetworkItemModel::SetupRequired = "SetupRequired";
31 ///todo: not hooked up:
32 const char* const NetworkItemModel::LoginRequired = "LoginRequired";
34 int NetworkItemModel::instances = 0;
35 int NetworkItemModel::idCounter = 0;
37 NetworkItemModel::NetworkItemModel(const QString &path, QObject *parent) :
40 m_getPropertiesWatcher(NULL),
41 m_setPropertyWatcher(NULL),
42 m_disconnectWatcher(NULL),
43 m_connectWatcher(NULL),
46 m_passphraseRequired(false)
48 registerCommonDataTypes();
54 if (!path.isEmpty()) {
55 m_service = new Service("net.connman", path,
56 QDBusConnection::systemBus(),
58 if (!m_service->isValid()) {
59 qDebug("service %s is invalid!", STR(path));
62 QDBusPendingReply<QVariantMap> reply = m_service->GetProperties();
63 m_getPropertiesWatcher = new QDBusPendingCallWatcher(reply, this);
64 connect(m_getPropertiesWatcher,
65 SIGNAL(finished(QDBusPendingCallWatcher*)),
67 SLOT(getPropertiesReply(QDBusPendingCallWatcher*)));
70 SIGNAL(PropertyChanged(const QString&,
71 const QDBusVariant &)),
73 SLOT(propertyChanged(const QString&,
74 const QDBusVariant &)));
79 //this is an attempt to avoid having lots of networks show in the
80 //list with no type. The thought process is that the filter is
81 //matching on empty strings. It doesn't appear to work in the
82 //nothing in the list except one thing problem. But other problems
87 NetworkItemModel::~NetworkItemModel()
90 qDebug("destructing instance %d. There are %d models around", id, instances);
94 void NetworkItemModel::connectService()
97 qDebug("connectService pretending");
99 qDebug("connectService FOR REAL");
100 m_service->Connect();
104 void NetworkItemModel::disconnectService()
107 qDebug("disconnectService pretending");
109 qDebug("disconnectService FOR REAL");
110 m_service->Disconnect();
114 void NetworkItemModel::removeService()
117 qDebug("removeService pretending");
119 qDebug("removeService FOR REAL");
124 void NetworkItemModel::moveBefore(NetworkItemModel *other)
126 m_service->MoveBefore(QDBusObjectPath(other->servicePath()));
129 void NetworkItemModel::moveAfter(NetworkItemModel *other)
131 m_service->MoveAfter(QDBusObjectPath(other->servicePath()));
134 const QString& NetworkItemModel::name() const
139 const QString& NetworkItemModel::security() const
144 const NetworkItemModel::StateType& NetworkItemModel::state() const
149 const int& NetworkItemModel::strength() const
154 const QString& NetworkItemModel::type() const
159 const bool& NetworkItemModel::passphraseRequired() const
161 return m_passphraseRequired;
164 const QString& NetworkItemModel::passphrase() const
169 const NetworkItemModel::IPv4Type& NetworkItemModel::ipv4() const
174 const QString& NetworkItemModel::mode() const
179 const QString NetworkItemModel::ipv4address() const
181 return ipv4().Address;
184 const QString NetworkItemModel::ipv4netmask() const
186 return ipv4().Netmask;
189 const QString NetworkItemModel::ipv4gateway() const
191 return ipv4().Gateway;
194 const QString NetworkItemModel::ipv4method() const
196 return ipv4().Method;
199 const bool& NetworkItemModel::setupRequired() const
201 return m_setupRequired;
204 const QString NetworkItemModel::apn() const
209 const QString NetworkItemModel::error() const
214 void NetworkItemModel::setPassphrase(const QString &passphrase)
217 QDBusPendingReply<void> reply =
218 m_service->SetProperty("Passphrase", QDBusVariant(QVariant(passphrase)));
219 reply.waitForFinished(); //FIXME: BAD
220 if (reply.isError()) {
221 qDebug()<<"got error from setProperty: "<<reply.error().message();
222 //throw -1; //FIXME: don't throw
227 void NetworkItemModel::setIpv4(const IPv4Type &ipv4)
233 Q_ASSERT(!ipv4.Method.isEmpty());
234 dict.insert("Method", ipv4.Method);
235 if (ipv4.Method != "dhcp") {
236 //FIXME: what do to if address and such are empty!?!
237 dict.insert("Address", ipv4.Address);
238 dict.insert("Netmask", ipv4.Netmask);
239 dict.insert("Gateway", ipv4.Gateway);
241 QVariant variant = qVariantFromValue(dict);
242 QDBusPendingReply<void> reply =
243 m_service->SetProperty(QString(IPv4), QDBusVariant(variant));
244 if (m_setPropertyWatcher) {
245 delete m_setPropertyWatcher;
247 m_setPropertyWatcher = new QDBusPendingCallWatcher(reply, this);
248 connect(m_setPropertyWatcher,
249 SIGNAL(finished(QDBusPendingCallWatcher*)),
251 SLOT(setPropertyFinished(QDBusPendingCallWatcher*)));
254 void NetworkItemModel::setApn(QString value)
258 m_service->SetProperty(APN, QDBusVariant(QVariant(value)));
261 const QString& NetworkItemModel::servicePath() const
263 return m_servicePath;
266 const QStringList& NetworkItemModel::nameservers() const
268 return m_nameservers;
271 const QString& NetworkItemModel::deviceAddress() const
273 return m_deviceAddress;
276 void NetworkItemModel::setNameservers(const QStringList &nameservers)
280 if (!isListEqual(m_nameservers, nameservers)) {
281 QVariant variant = qVariantFromValue(nameservers);
282 QDBusPendingReply<void> reply =
283 m_service->SetProperty(Nameservers, QDBusVariant(variant));
284 //I hate to wait here, but I'm not sure what else to do
285 reply.waitForFinished();
286 if (reply.isError()) {
287 qDebug("got error from setProperty");
288 throw -1; //FIXME: don't throw
293 void NetworkItemModel::setIpv4Address(QString v)
299 void NetworkItemModel::setIpv4Netmask(QString v )
305 void NetworkItemModel::setIpv4Gateway(QString v)
311 void NetworkItemModel::setIpv4Method(QString v)
317 NetworkItemModel::StateType NetworkItemModel::state(const QString &state)
319 NetworkItemModel::StateType _state;
320 if (state == "idle") {
322 } else if (state == "failure") {
323 _state = StateFailure;
324 } else if (state == "association") {
325 _state = StateAssociation;
326 } else if (state == "configuration") {
327 _state = StateConfiguration;
328 } else if (state == "ready") {
330 } else if (state == "online") {
331 _state = StateOnline;
334 qDebug("setting to to STATE_NONE because of unknown state returned: \"%s\"", STR(state));
340 //This sets the m_ipv4 with data. It does not set the data on the
342 void NetworkItemModel::_setIpv4(const QVariantMap &ipv4)
344 bool modified = false;
347 string = ipv4["Method"].toString();
348 // qDebug("Method: %s", STR(string));
349 if (m_ipv4.Method != string) {
350 m_ipv4.Method = string;
354 string = ipv4["Address"].toString();
355 //qDebug("Address: %s", STR(string));
356 if (m_ipv4.Address != string) {
357 m_ipv4.Address = string;
361 string = ipv4["Netmask"].toString();
362 //qDebug("Netmask: %s", STR(string));
363 if (m_ipv4.Netmask != string) {
364 m_ipv4.Netmask = string;
368 string = ipv4["Gateway"].toString();
369 // qDebug("Gateway: %s", STR(string));
370 if (m_ipv4.Gateway != string) {
371 m_ipv4.Gateway = string;
377 bool NetworkItemModel::isListEqual(const QStringList &a, const QStringList &b) const
379 if (a.count() != b.count()) {
382 for (int i=0; i < a.count(); i++) {
383 if (a.at(i) != b.at(i)) {
392 void NetworkItemModel::getPropertiesReply(QDBusPendingCallWatcher *call)
394 QDBusPendingReply<QVariantMap> reply = *call;
395 if (reply.isError()) {
396 qDebug("getPropertiesReply is error!");
397 QDBusError error = reply.error();
398 qDebug("service: %s", STR(servicePath()));
399 qDebug()<<QString("type: %1 name: %2 message: %3").
400 arg(QDBusError::errorString(error.type()))
402 .arg(error.message());
405 qDebug()<<"getPropertiesReply";
406 QVariantMap properties = reply.value();
407 //although it seems dangerous as some of these properties are not
408 //present, grabbing them is not, because QMap will insert the
409 //default value into the map if it isn't present. That's "" for
410 //strings and 0 for ints/bools
412 m_name = qdbus_cast<QString>(properties[Name]);
414 m_type = qdbus_cast<QString>(properties[Type]);
416 m_mode= qdbus_cast<QString>(properties[Mode]);
418 QStringList sec = qdbus_cast<QStringList>(properties[Security]);
422 m_security = sec.at(0);
423 securityChanged(m_security);
426 m_passphraseRequired = qdbus_cast<bool>(properties[PassphraseRequired]);
427 m_passphrase = qdbus_cast<QString>(properties[Passphrase]);
428 passphraseChanged(m_passphrase);
429 m_strength = qdbus_cast<int>(properties[Strength]);
430 strengthChanged(m_strength);
431 m_state = state(qdbus_cast<QString>(properties[State]));
432 _setIpv4(qdbus_cast<QVariantMap>(properties[IPv4Normal]));
433 m_nameservers = qdbus_cast<QStringList>(properties[Nameservers]);
434 m_deviceAddress = qdbus_cast<QVariantMap>(properties["Ethernet"])["Address"].toString();
435 m_apn = qdbus_cast<QString>(properties[APN]);
436 m_error = qdbus_cast<QString>(properties["Error"]);
438 m_setupRequired = qdbus_cast<bool>(properties[SetupRequired]);
439 emit propertyChanged("","");
442 void NetworkItemModel::propertyChanged(const QString &name,
443 const QDBusVariant &value)
445 qDebug()<<"NetworkItemModel: property "<<STR(name)<<" changed: "<<value.variant();
447 m_state = state(value.variant().toString());
448 stateChanged(m_state);
449 } else if (name == Name) {
450 m_name = (value.variant().toString());
452 } else if (name == Type) {
453 m_type = (value.variant().toString());
455 } else if (name == Mode) {
456 m_mode = (value.variant().toString());
457 } else if (name == Security) {
458 QStringList sec = qdbus_cast<QStringList>(value.variant());
462 m_security = sec.at(0);
463 securityChanged(m_security);
465 } else if (name == PassphraseRequired) {
466 m_passphraseRequired = (value.variant().toBool());
467 } else if (name == Passphrase) {
468 m_passphrase = (value.variant().toString());
469 passphraseChanged(m_passphrase);
470 } else if (name == Strength) {
471 m_strength = (value.variant().toInt());
472 strengthChanged(m_strength);
473 } else if (name == IPv4 || name == IPv4Normal) {
474 _setIpv4(qdbus_cast<QVariantMap>(value.variant()));
475 } else if (name == Nameservers) {
476 m_nameservers = (value.variant().toStringList());
477 } else if (name == "Ethernet") {
478 m_deviceAddress = (qdbus_cast<QVariantMap>(value.variant())["Address"].toString());
479 } else if (name == SetupRequired) {
480 m_setupRequired = value.variant().toBool();
481 setupRequiredChanged(m_setupRequired);
482 } else if (name == APN) {
483 m_apn = value.variant().toString();
484 } else if (name == "Error") {
485 m_error = value.variant().toString();
488 qDebug("We don't do anything with property: %s", STR(name));
491 emit propertyChanged(name,value.variant());
494 void NetworkItemModel::setPropertyFinished(QDBusPendingCallWatcher *call)
496 QDBusPendingReply<void> reply = *call;
497 if (reply.isError()) {
498 qDebug()<<"not continuing because of error in setProperty!"<<reply.error().message();
499 m_error = reply.error().message();
502 QDBusPendingReply<void> nextReply = m_service->Disconnect();
503 if (m_setPropertyWatcher) {
504 delete m_setPropertyWatcher;
506 m_setPropertyWatcher = new QDBusPendingCallWatcher(nextReply, this);
507 connect(m_setPropertyWatcher,
508 SIGNAL(finished(QDBusPendingCallWatcher*)),
510 SLOT(disconnectFinished(QDBusPendingCallWatcher*)));
514 void NetworkItemModel::disconnectFinished(QDBusPendingCallWatcher *call)
516 QDBusPendingReply<void> reply = *call;
517 if (reply.isError()) {
518 qDebug("not continuing because of error in disconnect!");
520 QDBusPendingReply<void> nextReply = m_service->Connect();
521 if (m_setPropertyWatcher) {
522 delete m_setPropertyWatcher;
524 m_disconnectWatcher = new QDBusPendingCallWatcher(nextReply, this);
525 connect(m_disconnectWatcher,
526 SIGNAL(finished(QDBusPendingCallWatcher*)),
528 SLOT(connectFinished(QDBusPendingCallWatcher*)));
532 void NetworkItemModel::connectFinished(QDBusPendingCallWatcher *call)
534 QDBusPendingReply<void> reply = *call;
535 if (reply.isError()) {
536 qDebug("error calling connect!");
538 qDebug("connect finished without error");