2 * hfdialer - Hands Free Voice Call Manager
3 * Copyright (c) 2012, 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
13 #include "callproxy.h"
14 #include "managerproxy.h"
16 // Returns a valid QDateTime if parsable as such, otherwise the result
18 static QDateTime qDateTimeFromOfono(const QString &val)
26 // NOTE: Ofono formats time to string with the following format spec:
27 // %Y-%m-%dT%H:%M:%S%z (for example: "2001-10-19T10:32:30-05:00")
29 // Start by trying to parse this as an ISODate "YYYY-MM-DDTHH:MM:SSTZD"
30 result = QDateTime::fromString(val,Qt::ISODate);
32 qDebug() << QString("Converted %1 with Qt::ISODate: %2")
34 .arg(result.toString());
37 if (!result.isValid()) {
38 // ISODate conversion has failed, fallback to manual method
39 // NOTE: QDateTime::fromString(val, Qt::ISODate) Fails since the date
40 // format from Ofono is in RFC 822 form, but QDateTime can't parse it
42 QByteArray bytes = val.toAscii();
43 const char *str = bytes.constData();
44 if (strptime(str, "%Y-%m-%dT%H:%M:%S%z", &time_tm) != NULL) {
45 time_t t = mktime(&time_tm);
46 if (t >= (time_t)(0)) {
49 qDebug() << QString("Converted %1 with strptime: %2")
51 .arg(result.toString());
56 if (!result.isValid())
57 qCritical() << QString("Format error, unknown date/time: %1")
64 CallProxy::CallProxy(const QString &callPath)
65 : org::ofono::VoiceCall(OFONO_SERVICE,
67 QDBusConnection::systemBus()),
70 m_startTime(QDateTime()),
77 if (!org::ofono::VoiceCall::isValid()) {
78 qCritical() << QString("Failed to connect to %1 for call %2:\n\t%3")
79 .arg(staticInterfaceName())
81 .arg(lastError().message());
83 QDBusPendingReply<QVariantMap> reply;
84 QDBusPendingCallWatcher *watcher;
86 reply = GetProperties();
87 watcher = new QDBusPendingCallWatcher(reply);
89 // Force this to be sync to ensure we have initial properties
90 watcher->waitForFinished();
91 getPropertiesFinished(watcher);
95 SIGNAL(PropertyChanged(const QString&,const QDBusVariant&)),
96 SLOT(propertyChanged(const QString&,const QDBusVariant&)));
97 connect(this, SIGNAL(DisconnectReason(const QString&)),
98 SLOT(disconnectReason(const QString&)));
100 qCritical() << QString("Invalid CallProxy instance: state == %1")
106 CallProxy::~CallProxy()
109 // FIXME: Do something here!!!
112 bool CallProxy::isValid()
115 return (org::ofono::VoiceCall::isValid() &&
117 (m_state != "disconnected"));
120 QString CallProxy::lineID() const
126 QString CallProxy::name() const
132 QString CallProxy::state() const
138 QDateTime CallProxy::startTime() const
144 int CallProxy::duration() const
147 if (m_startTime.isValid())
148 return m_startTime.secsTo(QDateTime::currentDateTime());
153 QString CallProxy::reason() const
159 bool CallProxy::multiparty() const
165 void CallProxy::answer()
171 void CallProxy::proceedCallAnswer()
175 QDBusPendingReply<QDBusObjectPath> reply;
176 QDBusPendingCallWatcher *watcher;
179 watcher = new QDBusPendingCallWatcher(reply);
181 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
182 SLOT(answerFinished(QDBusPendingCallWatcher*)));
185 void CallProxy::deniedCallAnswer()
189 // Hang up the incoming call, if resources to accept it are inavailabe
192 emit ManagerProxy::instance()->callManager()->deniedCallAnswer();
195 void CallProxy::deflect(const QString toNumber)
199 QDBusPendingReply<QDBusObjectPath> reply;
200 QDBusPendingCallWatcher *watcher;
202 reply = Deflect(toNumber);
203 watcher = new QDBusPendingCallWatcher(reply);
205 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
206 SLOT(deflectFinished(QDBusPendingCallWatcher*)));
209 void CallProxy::hangup()
213 QDBusPendingReply<> reply;
214 QDBusPendingCallWatcher *watcher;
217 watcher = new QDBusPendingCallWatcher(reply);
219 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
220 SLOT(hangupFinished(QDBusPendingCallWatcher*)));
223 void CallProxy::getPropertiesFinished(QDBusPendingCallWatcher *watcher)
227 QDBusPendingReply<QVariantMap> reply = *watcher;
229 if (reply.isError()) {
230 qCritical() << QString("Failed to connect to %1 for call %2:\n\t%3")
231 .arg(staticInterfaceName())
233 .arg(lastError().message());
237 QVariantMap props = reply.value();
241 m_lineid = qdbus_cast<QString>(props["LineIdentification"]);
242 m_name = qdbus_cast<QString>(props["Name"]);
243 m_state = qdbus_cast<QString>(props["State"]);
244 l_start = qdbus_cast<QString>(props["StartTime"]);
245 m_multiparty = qdbus_cast<bool>(props["Multiparty"]);
247 setStartTimeFromString(l_start);
249 // Indicate for this instance, that we've actually performed at least
250 // one round trip call to this VoiceCall and we are in sync with it
254 void CallProxy::answerFinished(QDBusPendingCallWatcher *watcher)
257 QDBusPendingReply<QDBusObjectPath> reply = *watcher;
259 qCritical() << QString("Answer() Failed: %1 - %2")
260 .arg(reply.error().name())
261 .arg(reply.error().message());
264 void CallProxy::deflectFinished(QDBusPendingCallWatcher *watcher)
267 QDBusPendingReply<QDBusObjectPath> reply = *watcher;
269 qCritical() << QString("Deflect() Failed: %1 - %2")
270 .arg(reply.error().name())
271 .arg(reply.error().message());
274 void CallProxy::hangupFinished(QDBusPendingCallWatcher *watcher)
277 QDBusPendingReply<> reply = *watcher;
279 qCritical() << QString("Hangup() Failed: %1 - %2")
280 .arg(reply.error().name())
281 .arg(reply.error().message());
284 void CallProxy::propertyChanged(const QString &in0, const QDBusVariant &in1)
288 if (in0 == "LineIdentification") {
289 m_lineid = qdbus_cast<QString>(in1.variant());
291 } else if (in0 == "State") {
292 m_state = qdbus_cast<QString>(in1.variant());
294 } else if (in0 == "StartTime") {
295 setStartTimeFromString(qdbus_cast<QString>(in1.variant()));
296 } else if (in0 == "Multiparty") {
297 m_multiparty = qdbus_cast<bool>(in1.variant());
298 emit multipartyChanged();
300 qDebug() << QString("Unexpected property \"%1\" changed...").arg(in0);
304 void CallProxy::disconnectReason(const QString &in0)
308 emit callDisconnected(in0);
311 void CallProxy::setStartTimeFromString(const QString &val)
317 m_startTime = qDateTimeFromOfono(val);
319 if (!m_startTime.isValid())
320 m_startTime = QDateTime::QDateTime::currentDateTime();
323 /* Local Variables: */
325 /* c-basic-offset:4 */
326 /* indent-tabs-mode: nil */