2 * This file is part of Jenirok.
4 * Jenirok is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Jenirok is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Jenirok. If not, see <http://www.gnu.org/licenses/>.
19 #include <QtCore/QDebug>
20 #include <QtCore/QTimer>
21 #include "calllistener.h"
24 #include "contactmanager.h"
25 #include "connectionmanager.h"
26 #include "sourcecoreconfig.h"
31 const QString CALL_SERVICE_NAME = "com.nokia.csd";
32 const QString CALL_SERVICE_PATH = "/com/nokia/csd/call";
33 const QString CALL_SERVICE_INTERFACE = "com.nokia.csd.Call";
34 const QString CALL_SERVICE_INSTANCE_NAME = "com.nokia.csd.Call.Instance";
35 const QString CALL_SIGNAL_INCOMING = "Coming";
36 const QString CALL_SIGNAL_RELEASE = "Release";
37 const QString CALL_SIGNAL_TERMINATED = "Terminated";
40 QDBusConnection CallListener::systemBus_ = QDBusConnection::systemBus();
42 CallListener::CallListener(): source_(0),
43 closeConnection_(false), initialized_(false), box_(0), label_(0),
44 retries_(-1), timer_(0)
48 CallListener::~CallListener()
53 bool CallListener::begin()
55 if(Settings::instance()->getConnectionType() == Settings::ALWAYS_ASK)
57 qDebug() << "Bad connection settings, unable to start";
61 sourceId_ = Source::stringToId(Settings::instance()->get("source"));
62 SourceCoreConfig* config = SourceCoreConfig::getCoreConfig(sourceId_);
63 config->getConfig(sourceConfig_);
66 systemBus_.connect(CALL_SERVICE_NAME,
68 CALL_SERVICE_INTERFACE,
71 SLOT(incomingCall(QDBusObjectPath, QString)));
73 systemBus_.connect(CALL_SERVICE_NAME,
75 CALL_SERVICE_INTERFACE,
78 SLOT(callTerminate()));
82 qDebug() << "Starting...";
88 void CallListener::end()
90 systemBus_.disconnect(CALL_SERVICE_NAME,
92 CALL_SERVICE_INTERFACE,
95 SLOT(incomingCall(QDBusObjectPath, QString)));
97 systemBus_.disconnect(CALL_SERVICE_NAME,
99 CALL_SERVICE_INTERFACE,
102 SLOT(callTerminate()));
105 sourceConfig_.clear();
109 void CallListener::search(Source::SearchDetails const& details)
111 qDebug() << "Search called";
115 Source::Result result;
117 if(Cache::instance().findItem(details.query, result))
120 qDebug() << "Found from cache";
122 showDelayedResult(createResult(result.name,
124 result.city), BANNER_DELAY);
129 currentSearch_ = details.query;
131 if(!handleConnection())
133 qDebug() << "Unable to connect";
137 showDelayedResult(tr("Searching..."), BANNER_DELAY);
139 qDebug() << "Starting to search...";
141 source_->search(details);
146 void CallListener::requestFinished(QVector <Source::Result> const& results,
147 Source::SearchDetails const& details,
150 // If box is not visible, the call must have been terminated already
151 if(!initialized_ || !box_->isVisible())
160 qDebug() << "Error: " << source_->errorString();
162 if(retries_ < SEARCH_RETRIES && retries_ >= 0)
165 source_->search(Source::SearchDetails(currentSearch_));
172 Source::Error error = source_->error();
176 case Source::TIMEOUT:
177 errorString = tr("Request timed out");
180 errorString = source_->errorString();
184 showError(tr("Searching failed:") + " " + errorString + ".");
191 if(results.size() == 0)
193 message = tr("Phone number was not found");
198 message = createResult(results.at(0).name, results.at(0).street,
201 Source::Result result = results.at(0);
202 result.number = details.query;
203 Cache::instance().addItem(result);
212 closeConnection_ = false;
213 ConnectionManager cm;
218 QString CallListener::createResult(QString const& name, QString const& street, QString const& city)
220 QString result = "<b>" + name + "</b>";
222 if(!street.isEmpty() || !city.isEmpty())
226 if(!street.isEmpty())
228 result += street + ", ";
237 void CallListener::showResult(QString const& text)
244 label_->setText("<font color='black'>" + text + "</font>");
246 if(box_->isVisible())
254 void CallListener::incomingCall(QDBusObjectPath path, QString number)
258 if(!cm.numberExists(number))
260 qDebug() << "Number doesn't exist";
262 systemBus_.connect(CALL_SERVICE_NAME,
264 CALL_SERVICE_INSTANCE_NAME,
265 CALL_SIGNAL_TERMINATED,
267 SLOT(callTerminate()));
269 search(Source::SearchDetails(number));
273 qDebug() << "Number exists";
277 void CallListener::callTerminate()
279 if(box_ && box_->isVisible())
286 closeConnection_ = false;
287 ConnectionManager cm;
293 if(gprsId_.isEmpty())
299 void CallListener::showDelayedResult(QString const& text, int delay)
301 timedMessage_ = text;
302 QTimer::singleShot(delay, this, SLOT(showTimedMessage()));
305 void CallListener::showTimedMessage()
307 if(timedMessage_.size() == 0 || !initialized_)
312 showResult(timedMessage_);
317 void CallListener::searchInit()
319 qDebug() << "Initializing search...";
323 qDebug() << "Already initialized";
327 source_ = Source::getSource(sourceId_);
328 SourceCoreConfig* config = SourceCoreConfig::getCoreConfig(sourceId_);
329 config->loadFromConfig(sourceConfig_);
330 config->apply(source_);
332 source_->setMaxResults(1);
333 source_->setFindNumber(false);
334 source_->setTimeout(REQUEST_TIMEOUT);
336 connect(source_, SIGNAL(requestFinished(QVector <Source::Result> const&,
337 Source::SearchDetails const&, bool)),
338 this, SLOT(requestFinished(QVector <Source::Result> const&,
339 Source::SearchDetails const&, bool)));
340 box_ = new InformationBox;
341 label_ = new QLabel("", box_);
342 label_->setMargin(8);
343 label_->setWordWrap(true);
344 box_->setWidget(label_);
348 void CallListener::searchClose()
350 initialized_ = false;
352 qDebug() << "Closing search...";
356 disconnect(source_, SIGNAL(requestFinished(QVector <Source::Result> const&,
357 Source::SearchDetails const&, bool)),
358 this, SLOT(requestFinished(QVector <Source::Result> const&,
359 Source::SearchDetails const&, bool)));
369 bool CallListener::handleConnection()
376 ConnectionManager cm;
380 closeConnection_ = false;
384 closeConnection_ = true;
386 Settings::ConnectionType configType = Settings::instance()->getConnectionType();
388 if(configType == Settings::ALWAYS_ASK)
390 showError(tr("Automatic connecting is not allowed by settings."), BANNER_DELAY);
394 showDelayedResult(tr("Connecting..."), BANNER_DELAY);
396 ConnectionManager::Connection best;
398 ConnectionManager::ConnectionType lookupType = ConnectionManager::NO_TYPE;
403 lookupType = ConnectionManager::WLAN;
406 lookupType = ConnectionManager::GPRS;
409 lookupType = ConnectionManager::NO_TYPE;
415 bool tryGprs = (!gprsId_.isEmpty() &&
416 (configType == Settings::ANY || configType == Settings::GPRS));
418 while(cretries < CONNECTION_LOOKUP_RETRIES)
425 if(cm.getBestConnection(best, lookupType))
430 // ICD doesn't always find gprs connection during call, so
431 // try to use gprs anyway.
432 if(tryGprs && is3g())
435 qDebug() << "Trying gprs";
439 qDebug() << "No connections found, retrying...";
443 sleep(WAIT_BETWEEN_RETRIES);
447 if(cretries >= CONNECTION_LOOKUP_RETRIES)
449 showError(tr("No available 3G or WLAN networks found."));
455 while(retries < CONNECT_RETRIES)
462 if(cm.connect(best.id))
466 else if(cm.error() == ConnectionManager::INVALID_IAP)
468 showError(tr("Selected access point doesn't exist."));
472 sleep(WAIT_BETWEEN_RETRIES);
474 qDebug() << "Unable to connect, retrying...";
479 if(initialized_ && retries >= CONNECT_RETRIES)
481 showError(tr("Unable to connect to network."));
488 void CallListener::showError(QString const& msg, int timeout)
490 qDebug() << "Error: " << msg;
491 box_->setTimeout(ERROR_BANNER_TIMEOUT);
495 showDelayedResult(msg, timeout);
503 void CallListener::timerEvent(QTimerEvent* event)
510 void CallListener::sleep(int ms)
517 timer_ = startTimer(ms);
521 QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
525 void CallListener::findGprsId()
527 ConnectionManager cm;
529 QList<ConnectionManager::Connection> connections;
531 if(cm.scanConnections(connections, ConnectionManager::GPRS) &&
532 connections.size() > 0)
534 gprsId_ = connections.at(0).id;
538 bool CallListener::is3g()
540 QDBusMessage msg = QDBusMessage::createMethodCall("com.nokia.phone.net",
541 "/com/nokia/phone/net",
543 "get_registration_status");
545 QDBusMessage rep = systemBus_.call(msg);
547 if(rep.type() == QDBusMessage::ErrorMessage)
549 qDebug() << "Unable to get network status";
553 uint status = rep.arguments().value(6).toUInt();
555 if(status & 0x10) // 3.5G (HSUPA)
559 else if(status & 0x08) // 3G (HSDPA)