PUBLIC_HEADERS += ofononetworkregistration.h
PUBLIC_HEADERS += ofonosupplementaryservices.h
PUBLIC_HEADERS += ofonovoicecallmanager.h
+PUBLIC_HEADERS += ofonovoicecall.h
HEADERS += $$PUBLIC_HEADERS
HEADERS += ofonointerface.h
SOURCES += ofononetworkregistration.cpp
SOURCES += ofonosupplementaryservices.cpp
SOURCES += ofonovoicecallmanager.cpp
+SOURCES += ofonovoicecall.cpp
+
target.path = $$[QT_INSTALL_PREFIX]/lib
headers.files = $$PUBLIC_HEADERS
--- /dev/null
+/*
+ * This file is part of ofono-qt
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Alexander Kanavin <alexander.kanavin@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <QtDBus/QtDBus>
+#include <QtCore/QObject>
+#include <QtCore/QDebug>
+
+#include "ofonointerface.h"
+#include "ofonovoicecall.h"
+
+#define VOICECALL_TIMEOUT 30000
+
+OfonoVoiceCall::OfonoVoiceCall(const QString& callId, QObject *parent)
+ : QObject(parent)
+{
+ m_if = new OfonoInterface(callId, "org.ofono.VoiceCall", OfonoGetAllOnStartup, this);
+
+ connect(m_if, SIGNAL(propertyChanged(const QString&, const QVariant&)),
+ this, SLOT(propertyChanged(const QString&, const QVariant&)));
+
+ QDBusConnection::systemBus().connect("org.ofono",path(),m_if->ifname(),
+ "DisconnectReason", this,
+ SIGNAL(disconnectReason(const QString&)));
+
+}
+
+OfonoVoiceCall::OfonoVoiceCall(const OfonoVoiceCall& call)
+ : QObject(call.parent())
+{
+ m_if = new OfonoInterface(call.path(), "org.ofono.VoiceCall", OfonoGetAllOnStartup, this);
+
+ connect(m_if, SIGNAL(propertyChanged(const QString&, const QVariant&)),
+ this, SLOT(propertyChanged(const QString&, const QVariant&)));
+
+ QDBusConnection::systemBus().connect("org.ofono",path(),m_if->ifname(),
+ "DisconnectReason", this,
+ SIGNAL(disconnectReason(const QString&)));
+}
+
+bool OfonoVoiceCall::operator==(const OfonoVoiceCall &call)
+{
+ return path() == call.path();
+}
+
+OfonoVoiceCall::~OfonoVoiceCall()
+{
+}
+
+void OfonoVoiceCall::answer()
+{
+ QDBusMessage request;
+
+ request = QDBusMessage::createMethodCall("org.ofono",
+ path(), m_if->ifname(),
+ "Answer");
+
+ QDBusConnection::systemBus().callWithCallback(request, this,
+ SLOT(answerResp()),
+ SLOT(answerErr(const QDBusError&)),
+ VOICECALL_TIMEOUT);
+}
+
+void OfonoVoiceCall::hangup()
+{
+ QDBusMessage request;
+
+ request = QDBusMessage::createMethodCall("org.ofono",
+ path(), m_if->ifname(),
+ "Hangup");
+
+ QDBusConnection::systemBus().callWithCallback(request, this,
+ SLOT(hangupResp()),
+ SLOT(hangupErr(const QDBusError&)),
+ VOICECALL_TIMEOUT);
+}
+
+void OfonoVoiceCall::deflect(const QString &number)
+{
+ QDBusMessage request;
+
+ request = QDBusMessage::createMethodCall("org.ofono",
+ path(), m_if->ifname(),
+ "Deflect");
+ QList<QVariant>arg;
+ arg.append(QVariant(number));
+ request.setArguments(arg);
+
+ QDBusConnection::systemBus().callWithCallback(request, this,
+ SLOT(deflectResp()),
+ SLOT(deflectErr(const QDBusError&)),
+ VOICECALL_TIMEOUT);
+}
+
+void OfonoVoiceCall::answerResp()
+{
+ emit answerComplete(TRUE);
+}
+
+void OfonoVoiceCall::answerErr(const QDBusError &error)
+{
+ qDebug() << "request failed" << error;
+ m_if->setError(error.name(), error.message());
+ emit answerComplete(FALSE);
+}
+
+void OfonoVoiceCall::hangupResp()
+{
+ emit hangupComplete(TRUE);
+}
+
+void OfonoVoiceCall::hangupErr(const QDBusError &error)
+{
+ qDebug() << "request failed" << error;
+ m_if->setError(error.name(), error.message());
+ emit hangupComplete(FALSE);
+}
+
+void OfonoVoiceCall::deflectResp()
+{
+ emit deflectComplete(TRUE);
+}
+
+void OfonoVoiceCall::deflectErr(const QDBusError &error)
+{
+ qDebug() << "request failed" << error;
+ m_if->setError(error.name(), error.message());
+ emit deflectComplete(FALSE);
+}
+
+QString OfonoVoiceCall::incomingLine() const
+{
+ return m_if->properties()["IncomingLine"].value<QString>();
+}
+
+QString OfonoVoiceCall::lineIdentification() const
+{
+ return m_if->properties()["LineIdentification"].value<QString>();
+}
+
+QString OfonoVoiceCall::name() const
+{
+ return m_if->properties()["Name"].value<QString>();
+}
+
+QString OfonoVoiceCall::state() const
+{
+ return m_if->properties()["State"].value<QString>();
+}
+
+QString OfonoVoiceCall::startTime() const
+{
+ return m_if->properties()["StartTime"].value<QString>();
+}
+
+QString OfonoVoiceCall::information() const
+{
+ return m_if->properties()["Information"].value<QString>();
+}
+
+bool OfonoVoiceCall::multiparty() const
+{
+ return m_if->properties()["Multiparty"].value<bool>();
+}
+
+bool OfonoVoiceCall::emergency() const
+{
+ return m_if->properties()["Emergency"].value<bool>();
+}
+
+void OfonoVoiceCall::propertyChanged(const QString &property, const QVariant &value)
+{
+ if (property == "LineIdentification") {
+ emit lineIdentificationChanged(value.value<QString>());
+ } else if (property == "Name") {
+ emit nameChanged(value.value<QString>());
+ } else if (property == "State") {
+ emit stateChanged(value.value<QString>());
+ } else if (property == "Information") {
+ emit informationChanged(value.value<QString>());
+ } else if (property == "IncomingLine") {
+ emit incomingLineChanged(value.value<QString>());
+ } else if (property == "Multiparty") {
+ emit multipartyChanged(value.value<bool>());
+ } else if (property == "Emergency") {
+ emit emergencyChanged(value.value<bool>());
+ } else if (property == "StartTime") {
+ emit startTimeChanged(value.value<QString>());
+ } else if (property == "Icon") {
+ emit iconChanged(value.value<quint8>());
+ }
+}
+
+QString OfonoVoiceCall::path() const
+{
+ return m_if->path();
+}
+
+QString OfonoVoiceCall::errorName() const
+{
+ return m_if->errorName();
+}
+
+QString OfonoVoiceCall::errorMessage() const
+{
+ return m_if->errorMessage();
+}
--- /dev/null
+/*
+ * This file is part of ofono-qt
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Alexander Kanavin <alexander.kanavin@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef OFONOVOICECALL_H
+#define OFONOVOICECALL_H
+
+#include <QtCore/QObject>
+#include <QVariant>
+#include <QStringList>
+#include <QDBusError>
+
+#include "libofono-qt_global.h"
+
+class OfonoInterface;
+
+//! This class is used to access oFono voice call API
+/*!
+ * The API is documented in
+ * http://git.kernel.org/?p=network/ofono/ofono.git;a=blob;f=doc/voicecall-api.txt
+ */
+class OFONO_QT_EXPORT OfonoVoiceCall : public QObject
+{
+ Q_OBJECT
+public:
+ OfonoVoiceCall(const QString &callId, QObject *parent=0);
+ OfonoVoiceCall(const OfonoVoiceCall &op);
+ ~OfonoVoiceCall();
+
+ bool operator==(const OfonoVoiceCall &op);
+
+ //! Returns the D-Bus object path of the voice call object
+ QString path() const;
+
+ //! Get the D-Bus error name of the last operation.
+ /*!
+ * Returns the D-Bus error name of the last operation (setting a property
+ * or calling a method) if it has failed
+ */
+ QString errorName() const;
+
+ //! Get the D-Bus error message of the last operation.
+ /*!
+ * Returns the D-Bus error message of the last operation (setting a property
+ * or calling a method) if it has failed
+ */
+ QString errorMessage() const;
+
+ void answer();
+ void hangup();
+ void deflect(const QString &number);
+ QString lineIdentification() const;
+ QString incomingLine() const;
+ QString name() const;
+ QString state() const;
+ QString startTime() const;
+ QString information() const;
+ bool multiparty() const;
+ bool emergency() const;
+
+signals:
+ void answerComplete(bool status);
+ void hangupComplete(bool status);
+ void deflectComplete(bool status);
+ void lineIdentificationChanged(const QString &name);
+ void nameChanged(const QString &name);
+ void stateChanged(const QString &state);
+ void startTimeChanged(const QString &time);
+ void informationChanged(const QString &mcc);
+ void incomingLineChanged(const QString &line);
+ void disconnectReason(const QString &reason);
+ void multipartyChanged(const bool multiparty);
+ void iconChanged(const quint8 &icon);
+ void emergencyChanged(const bool emergency);
+
+private slots:
+ void propertyChanged(const QString &property, const QVariant &value);
+ void answerResp();
+ void answerErr(const QDBusError &error);
+ void hangupResp();
+ void hangupErr(const QDBusError &error);
+ void deflectResp();
+ void deflectErr(const QDBusError &error);
+
+private:
+ OfonoInterface *m_if;
+
+};
+
+#endif // OFONOVOICECALL_H
--- /dev/null
+/*
+ * This file is part of ofono-qt
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Alexander Kanavin <alexander.kanavin@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <QtTest/QtTest>
+#include <QtCore/QObject>
+
+#include <ofonovoicecallmanager.h>
+#include <ofonovoicecall.h>
+#include <QtDebug>
+
+
+class TestOfonoVoiceCall : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase()
+ {
+ m = new OfonoVoiceCallManager(OfonoModem::ManualSelect, "/phonesim", this);
+ QCOMPARE(m->modem()->isValid(), true);
+ if (!m->modem()->powered()) {
+ m->modem()->setPowered(true);
+ QTest::qWait(5000);
+ }
+ if (!m->modem()->online()) {
+ m->modem()->setOnline(true);
+ QTest::qWait(5000);
+ }
+ QCOMPARE(m->isValid(), true);
+ }
+
+ void testOfonoVoiceCall()
+ {
+ QSignalSpy dialreg(m,SIGNAL(dialComplete(bool)));
+ QSignalSpy dspy(m, SIGNAL(callAdded(QString)));
+
+ // Dial and hangup
+ m->dial("123","");
+ QTest::qWait(1000);
+
+ QCOMPARE(dialreg.count(), 1);
+ QCOMPARE(dialreg.takeFirst().at(0).toBool(),true);
+ QCOMPARE(dspy.count(), 1);
+ QString callid = dspy.takeFirst().at(0).toString();
+
+ OfonoVoiceCall* call = new OfonoVoiceCall(callid);
+
+ QSignalSpy state(call, SIGNAL(stateChanged(const QString)));
+ QSignalSpy discreason(call,SIGNAL(disconnectReason(const QString)));
+ QSignalSpy hspy(call, SIGNAL(hangupComplete(bool)));
+ QSignalSpy li (call, SIGNAL(lineIdentificationChanged(QString)));
+ QSignalSpy name (call, SIGNAL(nameChanged(QString)));
+ QSignalSpy info (call, SIGNAL(informationChanged(QString)));
+ QSignalSpy mp (call, SIGNAL(multipartyChanged(bool)));
+ QSignalSpy em (call, SIGNAL(emergencyChanged(bool)));
+ QSignalSpy st (call, SIGNAL(startTimeChanged(QString)));
+ QSignalSpy ic (call, SIGNAL(iconChanged(quint8)));
+
+ QTest::qWait(10000);
+
+ QVERIFY(state.count()>0);
+ QVERIFY(st.count()>0);
+ QVERIFY(ic.count()==0);
+ QVERIFY(em.count()==0);
+ QVERIFY(mp.count()==0);
+ QVERIFY(info.count()==0);
+ QVERIFY(name.count()==0);
+ QVERIFY(li.count()==0);
+
+ QCOMPARE(call->state(),QString("active"));
+ QCOMPARE(call->lineIdentification(),QString("123"));
+ QCOMPARE(call->emergency(),false);
+ QCOMPARE(call->multiparty(),false);
+ QCOMPARE(call->name(),QString(""));
+ QCOMPARE(call->information(),QString(""));
+
+ call->hangup();
+ QTest::qWait(5000);
+ QCOMPARE(hspy.count(), 1);
+ QCOMPARE(hspy.takeFirst().at(0).toBool(),true);
+ QCOMPARE(discreason.count(), 1);
+ QCOMPARE(discreason.takeFirst().at(0).toString(), QString("local"));
+ delete call;
+ }
+
+ void testOfonoVoiceCallStep2()
+ {
+ //Dial failure, incoming, answer and local hangup
+ QSignalSpy callsignal(m, SIGNAL(callAdded(const QString)));
+
+ m->dial("199","");
+ QTest::qWait(8000);
+
+ QCOMPARE(callsignal.count(),1);
+ QString callid = callsignal.takeFirst().at(0).toString();
+
+ OfonoVoiceCall* call = new OfonoVoiceCall(callid);
+ QSignalSpy state(call, SIGNAL(stateChanged(const QString)));
+ QSignalSpy time(call,SIGNAL(startTimeChanged(const QString)));
+ QSignalSpy discreason(call,SIGNAL(disconnectReason(const QString)));
+ QSignalSpy hspy(call, SIGNAL(hangupComplete(bool)));
+ QSignalSpy aspy(call, SIGNAL(answerComplete(bool)));
+
+ QSignalSpy li (call, SIGNAL(lineIdentificationChanged(QString)));
+ QSignalSpy name (call, SIGNAL(nameChanged(QString)));
+ QSignalSpy info (call, SIGNAL(informationChanged(QString)));
+ QSignalSpy mp (call, SIGNAL(multipartyChanged(bool)));
+ QSignalSpy em (call, SIGNAL(emergencyChanged(bool)));
+ QSignalSpy ic (call, SIGNAL(iconChanged(quint8)));
+
+
+ QTest::qWait(8000);
+ QCOMPARE(call->state(),QString("incoming"));
+ call->answer();
+ QTest::qWait(10000);
+ QVERIFY(state.count()>0);
+ QCOMPARE(call->lineIdentification(),QString("1234567")); //PhoneSim specific value
+ QVERIFY(time.count()>0);
+ QCOMPARE(aspy.count(), 1);
+ QCOMPARE(aspy.takeFirst().at(0).toBool(),true);
+
+ QVERIFY(ic.count()==0);
+ QVERIFY(em.count()==0);
+ QVERIFY(mp.count()==0);
+ QVERIFY(info.count()==0);
+ QVERIFY(name.count()==0);
+ QVERIFY(li.count()==0);
+
+ call->hangup();
+ QTest::qWait(5000);
+ QCOMPARE(hspy.count(), 1);
+ QCOMPARE(hspy.takeFirst().at(0).toBool(), true);
+ QCOMPARE(discreason.count(), 1);
+ QCOMPARE(discreason.takeFirst().at(0).toString(), QString("local"));
+ delete call;
+ }
+
+ void testOfonoVoiceCallStep3()
+ {
+ //Dial failed, incoming, no answer and state change to disconnect
+ QSignalSpy callsignal(m, SIGNAL(callAdded(const QString)));
+
+ m->dial("177","");
+ QTest::qWait(3000);
+
+ QCOMPARE(callsignal.count(),1);
+ QString callid = callsignal.takeFirst().at(0).toString();
+
+ OfonoVoiceCall* call = new OfonoVoiceCall(callid);
+ QSignalSpy state(call, SIGNAL(stateChanged(const QString)));
+ QSignalSpy discreason(call,SIGNAL(disconnectReason(const QString)));
+
+ QTest::qWait(1000);
+ QCOMPARE(call->state(),QString("incoming"));
+ QTest::qWait(8000);
+ QVERIFY(state.count()>0);
+ QCOMPARE(discreason.count(), 1);
+ QCOMPARE(discreason.takeFirst().at(0).toString(), QString("remote"));
+ delete call;
+
+ }
+ void testOfonoVoiceCallStep4()
+ {
+ //Deflect
+ QSignalSpy callsignal(m, SIGNAL(callAdded(const QString)));
+ m->dial("199","");
+ QTest::qWait(8000);
+
+ QCOMPARE(callsignal.count(),1);
+ QString callid = callsignal.takeFirst().at(0).toString();
+
+ OfonoVoiceCall* call = new OfonoVoiceCall(callid);
+ QSignalSpy dfspy(call, SIGNAL(deflectComplete(bool)));
+
+ QTest::qWait(8000);
+ QCOMPARE(call->state(),QString("incoming"));
+ QCOMPARE(call->lineIdentification(),QString("1234567")); //PhoneSim specific value
+ call->deflect("2345");
+ QTest::qWait(8000);
+ QCOMPARE(dfspy.count(), 1);
+ QCOMPARE(dfspy.takeFirst().at(0).toBool(), true);
+ QTest::qWait(10000);
+
+ delete call;
+
+ }
+ void cleanupTestCase()
+ {
+
+ }
+
+
+private:
+ OfonoVoiceCallManager *m;
+};
+
+QTEST_MAIN(TestOfonoVoiceCall)
+#include "test_ofonovoicecall.moc"
--- /dev/null
+include(testcase.pri)
+SOURCES += test_ofonovoicecall.cpp
SUBDIRS += test_ofononetworkregistration.pro
SUBDIRS += test_ofonosupplementaryservices.pro
SUBDIRS += test_ofonovoicecallmanager.pro
+SUBDIRS += test_ofonovoicecall.pro