Added SMS support in ofono-qt
authorSirpa Kemppainen <sirpa.h.kemppainen@nokia.com>
Mon, 21 Mar 2011 12:57:24 +0000 (14:57 +0200)
committerAlexander Kanavin <alexander.kanavin@nokia.com>
Thu, 7 Apr 2011 13:45:31 +0000 (16:45 +0300)
lib/lib.pro
lib/ofonomessage.cpp [new file with mode: 0644]
lib/ofonomessage.h [new file with mode: 0644]
lib/ofonomessagemanager.cpp
lib/ofonomessagemanager.h
tests/test_ofonomessagemanager.cpp

index b47fa19..49bae4e 100644 (file)
@@ -30,6 +30,7 @@ PUBLIC_HEADERS += ofonosupplementaryservices.h
 PUBLIC_HEADERS += ofonovoicecallmanager.h
 PUBLIC_HEADERS += ofonovoicecall.h
 PUBLIC_HEADERS += ofonocallvolume.h
+PUBLIC_HEADERS += ofonomessage.h
 
 HEADERS += $$PUBLIC_HEADERS
 HEADERS += ofonointerface.h 
@@ -53,6 +54,7 @@ SOURCES += ofonosupplementaryservices.cpp
 SOURCES += ofonovoicecallmanager.cpp
 SOURCES += ofonovoicecall.cpp
 SOURCES += ofonocallvolume.cpp
+SOURCES += ofonomessage.cpp
 
 target.path = $$[QT_INSTALL_PREFIX]/lib
 headers.files = $$PUBLIC_HEADERS
diff --git a/lib/ofonomessage.cpp b/lib/ofonomessage.cpp
new file mode 100644 (file)
index 0000000..5360f15
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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 "ofonointerface.h"
+#include "ofonomessage.h"
+
+
+OfonoMessage::OfonoMessage(const QString& messageId, QObject *parent)
+    : QObject(parent)
+{
+    m_if = new OfonoInterface(messageId, "org.ofono.Message", OfonoGetAllOnStartup, this);
+
+    connect(m_if, SIGNAL(propertyChanged(const QString&, const QVariant&)),
+            this, SLOT(propertyChanged(const QString&, const QVariant&)));
+}
+
+OfonoMessage::OfonoMessage(const OfonoMessage& message)
+    : QObject(message.parent())
+{
+    m_if = new OfonoInterface(message.path(), "org.ofono.Message", OfonoGetAllOnStartup, this);
+
+    connect(m_if, SIGNAL(propertyChanged(const QString&, const QVariant&)),
+            this, SLOT(propertyChanged(const QString&, const QVariant&)));
+}
+
+bool OfonoMessage::operator==(const OfonoMessage &message)
+{
+    return path() == message.path();
+}
+
+OfonoMessage::~OfonoMessage()
+{
+}
+
+QString OfonoMessage::state() const
+{
+    return m_if->properties()["State"].value<QString>();
+}
+
+void OfonoMessage::propertyChanged(const QString &property, const QVariant &value)
+{
+    if (property == "State") {
+        emit stateChanged(value.value<QString>());
+    }
+}
+
+QString OfonoMessage::path() const
+{
+    return m_if->path();
+}
+
+QString OfonoMessage::errorName() const
+{
+    return m_if->errorName();
+}
+
+QString OfonoMessage::errorMessage() const
+{
+    return m_if->errorMessage();
+}
diff --git a/lib/ofonomessage.h b/lib/ofonomessage.h
new file mode 100644 (file)
index 0000000..4cdda5e
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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 OFONOMESSAGE_H
+#define OFONOMESSAGE_H
+
+#include <QtCore/QObject>
+#include <QVariant>
+#include <QStringList>
+#include <QDBusError>
+
+#include "libofono-qt_global.h"
+
+class OfonoInterface;
+
+//! This class is used to access oFono message API
+/*!
+ * oFono message API is documented in
+ * http://git.kernel.org/?p=network/ofono/ofono.git;a=blob_plain;f=doc/message-api.txt
+ */
+class OFONO_QT_EXPORT OfonoMessage : public QObject
+{
+    Q_OBJECT
+public:
+    OfonoMessage(const QString &messageId, QObject *parent=0);
+    OfonoMessage(const OfonoMessage &message);
+    ~OfonoMessage();
+
+    OfonoMessage operator=(const OfonoMessage &message);
+    bool operator==(const OfonoMessage &message);
+
+    //! Returns the D-Bus object path of the message 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;
+
+    QString state() const;
+
+signals:
+    void stateChanged(const QString &state);
+
+private slots:
+    void propertyChanged(const QString &property, const QVariant &value);
+
+private:
+    OfonoInterface *m_if;
+
+};
+
+#endif // OFONOMESSAGE_H
index 279873f..64a1ff0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of ofono-qt
  *
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2010-2011 Nokia Corporation and/or its subsidiary(-ies).
  *
  * Contact: Alexander Kanavin <alexander.kanavin@nokia.com>
  *
 #include "ofonomessagemanager.h"
 #include "ofonointerface.h"
 
+QDBusArgument &operator<<(QDBusArgument &argument, const OfonoMessageManagerStruct &message)
+{
+    argument.beginStructure();
+    argument << message.path << message.properties;
+    argument.endStructure();
+    return argument;
+}
+
+const QDBusArgument &operator>>(const QDBusArgument &argument, OfonoMessageManagerStruct &message)
+{
+    argument.beginStructure();
+    argument >> message.path >> message.properties;
+    argument.endStructure();
+    return argument;
+}
+
 OfonoMessageManager::OfonoMessageManager(OfonoModem::SelectionSetting modemSetting, const QString &modemPath, QObject *parent)
     : OfonoModemInterface(modemSetting, modemPath, "org.ofono.MessageManager", OfonoGetAllOnFirstRequest, parent)
 {
+    QDBusReply<OfonoMessageManagerList> reply;
+    OfonoMessageManagerList messages;
+    QDBusMessage request;
+
+    qDBusRegisterMetaType<OfonoMessageManagerStruct>();
+    qDBusRegisterMetaType<OfonoMessageManagerList>();
+
+    request = QDBusMessage::createMethodCall("org.ofono",
+                                             path(), m_if->ifname(),
+                                             "GetMessages");
+    reply = QDBusConnection::systemBus().call(request);
+
+    messages = reply;
+    foreach(OfonoMessageManagerStruct message, messages) {
+        m_messagelist << message.path.path();
+    }
+
     connect(m_if, SIGNAL(propertyChanged(const QString&, const QVariant&)), 
             this, SLOT(propertyChanged(const QString&, const QVariant&)));
     connect(m_if, SIGNAL(setPropertyFailed(const QString&)), 
             this, SLOT(setPropertyFailed(const QString&)));
     connect(m_if, SIGNAL(requestPropertyComplete(bool, const QString&, const QVariant&)),
            this, SLOT(requestPropertyComplete(bool, const QString&, const QVariant&)));
+
+    QDBusConnection::systemBus().connect("org.ofono",path(),m_if->ifname(),
+                                         "MessageAdded",
+                                         this,
+                                         SLOT(onMessageAdded(const QDBusObjectPath&, const QVariantMap&)));
+
+    QDBusConnection::systemBus().connect("org.ofono",path(),m_if->ifname(),
+                                         "MessageRemoved",
+                                         this,
+                                         SLOT(onMessageRemoved(const QDBusObjectPath&)));
+
+    QDBusConnection::systemBus().connect("org.ofono", path(), m_if->ifname(),
+                                         "IncomingMessage",
+                                         this,
+                                         SIGNAL(incomingMessage(QString, QVariantMap)));
+
+    QDBusConnection::systemBus().connect("org.ofono", path(), m_if->ifname(),
+                                         "ImmediateMessage",
+                                         this,
+                                         SIGNAL(immediateMessage(QString, QVariantMap)));
 }
 
 OfonoMessageManager::~OfonoMessageManager()
@@ -47,29 +100,120 @@ void OfonoMessageManager::requestServiceCenterAddress()
     m_if->requestProperty("ServiceCenterAddress");
 }
 
-void OfonoMessageManager::requestPropertyComplete(bool success, const QString& property, const QVariant& value)
+void OfonoMessageManager::setServiceCenterAddress(QString address)
 {
-    if (property == "ServiceCenterAddress") {  
-        success ? emit serviceCenterAddressComplete(true, value.value<QString>()) : emit serviceCenterAddressComplete(false, QString());
-    }
+    m_if->setProperty("ServiceCenterAddress", qVariantFromValue(address));
 }
 
-void OfonoMessageManager::setServiceCenterAddress(QString address)
+void OfonoMessageManager::requestUseDeliveryReports()
 {
-    m_if->setProperty("ServiceCenterAddress", qVariantFromValue(address));
+    m_if->requestProperty("UseDeliveryReports");
+}
+
+void OfonoMessageManager::setUseDeliveryReports(bool useDeliveryReports)
+{
+    m_if->setProperty("UseDeliveryReports", qVariantFromValue(useDeliveryReports));
+}
+
+void OfonoMessageManager::requestBearer()
+{
+    m_if->requestProperty("Bearer");
 }
 
+void OfonoMessageManager::setBearer(QString bearer)
+{
+    m_if->setProperty("Bearer", qVariantFromValue(bearer));
+}
+
+void OfonoMessageManager::requestAlphabet()
+{
+    m_if->requestProperty("Alphabet");
+}
+
+void OfonoMessageManager::setAlphabet(QString alphabet)
+{
+    m_if->setProperty("Alphabet", qVariantFromValue(alphabet));
+}
+
+
+void OfonoMessageManager::sendMessage(const QString &to, const QString &message)
+{
+    QDBusMessage request;
+
+    request = QDBusMessage::createMethodCall("org.ofono",
+                                             path(), m_if->ifname(),
+                                             "SendMessage");
+
+    request << to << message;
+
+    QDBusConnection::systemBus().callWithCallback(request, this,
+                                        SLOT(sendMessageResp(const QDBusObjectPath&)),
+                                        SLOT(sendMessageErr(const QDBusError&)));
+}
+
+void OfonoMessageManager::requestPropertyComplete(bool success, const QString& property, const QVariant& value)
+{
+    if (property == "ServiceCenterAddress") {
+        success ? emit serviceCenterAddressComplete(true, value.value<QString>()) : emit serviceCenterAddressComplete(false, QString());
+    } else if (property == "UseDeliveryReports") {
+        success ? emit useDeliveryReportsComplete(true, value.value<bool>()) : emit useDeliveryReportsComplete(false, bool());
+    } else if (property == "Bearer") {
+        success ? emit bearerComplete(true, value.value<QString>()) : emit bearerComplete(false, QString());
+    } else if (property == "Alphabet") {
+        success ? emit alphabetComplete(true, value.value<QString>()) : emit alphabetComplete(false, QString());
+    }
+}
 
 void OfonoMessageManager::propertyChanged(const QString& property, const QVariant& value)
 {
     if (property == "ServiceCenterAddress") {  
         emit serviceCenterAddressChanged(value.value<QString>());
+    } else if (property == "UseDeliveryReports") {
+        emit useDeliveryReportsChanged(value.value<bool>());
+    } else if (property == "Bearer") {
+        emit bearerChanged(value.value<QString>());
+    } else if (property == "Alphabet") {
+        emit alphabetChanged(value.value<QString>());
     }
 }
 
 void OfonoMessageManager::setPropertyFailed(const QString& property)
 {
-    if (property == "ServiceCenterAddress")
+    if (property == "ServiceCenterAddress") {
         emit setServiceCenterAddressFailed();
+    } else if (property == "UseDeliveryReports") {
+        emit setUseDeliveryReportsFailed();
+    } else if (property == "Bearer") {
+        emit setBearerFailed();
+    } else if (property == "Alphabet") {
+        emit setAlphabetFailed();
+    }
+}
+
+void OfonoMessageManager::sendMessageResp(const QDBusObjectPath& objectPath)
+{
+    emit sendMessageComplete(true, objectPath);
+}
+
+void OfonoMessageManager::sendMessageErr(QDBusError error)
+{
+    m_if->setError(error.name(), error.message());
+    emit sendMessageComplete(false, QDBusObjectPath());
 }
 
+QStringList OfonoMessageManager::getMessages() const
+{
+    return m_messagelist;
+}
+
+void OfonoMessageManager::onMessageAdded(const QDBusObjectPath &path, const QVariantMap& /*properties*/)
+{
+    m_messagelist << path.path();
+    emit messageAdded(path.path());
+}
+
+void OfonoMessageManager::onMessageRemoved(const QDBusObjectPath &path)
+{
+    m_messagelist.removeAll(path.path());
+    emit messageRemoved(path.path());
+}
index 6abe2d6..1896cbb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of ofono-qt
  *
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2010-2011 Nokia Corporation and/or its subsidiary(-ies).
  *
  * Contact: Alexander Kanavin <alexander.kanavin@nokia.com>
  *
 #define OFONOMESSAGEMANAGER_H
 
 #include <QtCore/QObject>
+#include <QDBusError>
+#include <QDBusObjectPath>
 #include "ofonomodeminterface.h"
 #include "libofono-qt_global.h"
 
+struct OfonoMessageManagerStruct {
+    QDBusObjectPath path;
+    QVariantMap properties;
+};
+typedef QList<OfonoMessageManagerStruct> OfonoMessageManagerList;
+
+Q_DECLARE_METATYPE(OfonoMessageManagerStruct)
+Q_DECLARE_METATYPE(OfonoMessageManagerList)
+
 //! This class is used to access oFono message manager API
 /*!
  * oFono message manager API is documented in
- * http://git.kernel.org/?p=network/ofono/ofono.git;a=blob_plain;f=doc/message-api.txt
+ * http://git.kernel.org/?p=network/ofono/ofono.git;a=blob_plain;f=doc/messagemanager-api.txt
  */
 class OFONO_QT_EXPORT OfonoMessageManager : public OfonoModemInterface
 {
@@ -44,17 +55,49 @@ public:
     /* Properties */
     void requestServiceCenterAddress();
     void setServiceCenterAddress(QString address);
+    void requestUseDeliveryReports();
+    void setUseDeliveryReports(bool useDeliveryReports);
+    void requestBearer();
+    void setBearer(QString bearer);
+    void requestAlphabet();
+    void setAlphabet(QString alphabet);
+
+    QStringList getMessages() const;
+    void sendMessage(const QString &to, const QString &message);
 
 signals:
     void serviceCenterAddressChanged(const QString &address);
-    void setServiceCenterAddressFailed();
-    
+    void useDeliveryReportsChanged(const bool &useDeliveryReports);
+    void bearerChanged(const QString &bearer);
+    void alphabetChanged(const QString &alphabet);
+
     void serviceCenterAddressComplete(bool success, const QString &address);
+    void useDeliveryReportsComplete(bool success, const bool &useDeliveryReports);
+    void bearerComplete(bool success, const QString &bearer);
+    void alphabetComplete(bool success, const QString &alphabet);
+    void sendMessageComplete(bool success, const QDBusObjectPath& objectPath);
+
+    void setServiceCenterAddressFailed();
+    void setUseDeliveryReportsFailed();
+    void setBearerFailed();
+    void setAlphabetFailed();
+
+    void messageAdded(const QString &message);
+    void messageRemoved(const QString &message);
+    void immediateMessage(const QString &message, const QVariantMap &info);
+    void incomingMessage(const QString &message, const QVariantMap &info);
 
 private slots:
     void propertyChanged(const QString &property, const QVariant &value);
     void setPropertyFailed(const QString &property);
     void requestPropertyComplete(bool success, const QString &property, const QVariant &value);
+    void onMessageAdded(const QDBusObjectPath &message, const QVariantMap &properties);
+    void onMessageRemoved(const QDBusObjectPath &message);
+    void sendMessageResp(const QDBusObjectPath& objectPath);
+    void sendMessageErr(QDBusError error);
+
+private:
+    QStringList m_messagelist;
 };
 
 #endif  /* !OFONOMESSAGEMANAGER_H */
index abc518c..868dc32 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of ofono-qt
  *
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2010-2011 Nokia Corporation and/or its subsidiary(-ies).
  *
  * Contact: Alexander Kanavin <alexander.kanavin@nokia.com>
  *
 
 #include <QtTest/QtTest>
 #include <QtCore/QObject>
+#include <QDBusObjectPath>
 
 #include <ofonomessagemanager.h>
+#include <ofonomessage.h>
 
 #include <QtDebug>
 
@@ -51,6 +53,48 @@ private slots:
        QCOMPARE(m->isValid(), true);    
     }
 
+    void testOfonoMessageManager()
+    {
+        QSignalSpy sendMessage(m, SIGNAL(sendMessageComplete(bool, QDBusObjectPath)));
+        QSignalSpy messageAdded(m, SIGNAL(messageAdded(QString)));
+        QSignalSpy messageRemoved(m, SIGNAL(messageRemoved(QString)));
+        QSignalSpy immediateMessage(m, SIGNAL(immediateMessage(QString, QVariantMap)));
+        QSignalSpy incomingMessage(m, SIGNAL(incomingMessage(QString, QVariantMap)));
+
+
+        QStringList messages = m->getMessages();
+        QVERIFY(messages.count() == 0);
+
+        m->sendMessage("99999", "success");
+
+        QTest::qWait(1000);
+
+        QCOMPARE(sendMessage.count(), 1);
+        QVariantList params = sendMessage.takeFirst();
+        QCOMPARE(params.at(0).toBool(), true);
+        QDBusObjectPath objectPath = params.at(1).value<QDBusObjectPath>();
+        QVERIFY(objectPath.path().length() > 0);
+        qDebug() << objectPath.path();
+
+        QCOMPARE(messageAdded.count(), 1);
+        QCOMPARE(messageRemoved.count(), 1);
+
+        QString messageId = messageAdded.takeFirst().at(0).toString();
+        OfonoMessage* message = new OfonoMessage(messageId);
+        QSignalSpy state(message, SIGNAL(stateChanged(const QString)));
+        qDebug() << message->state();
+
+        m->sendMessage("abc", "fail");
+
+        QTest::qWait(1000);
+
+        QCOMPARE(sendMessage.count(), 1);
+        params = sendMessage.takeFirst();
+        QCOMPARE(params.at(0).toBool(), false);
+        objectPath = params.at(1).value<QDBusObjectPath>();
+        QVERIFY(objectPath.path().length() == 0);
+    }
+
     void testOfonoMessageManagerSca()
     {
         QSignalSpy scaComplete(m, SIGNAL(serviceCenterAddressComplete(bool, QString)));
@@ -103,6 +147,125 @@ private slots:
        QCOMPARE(scaChanged.takeFirst().at(0).toString(), sca);
     }
 
+    void testOfonoMessageManagerUseDeliveryReports()
+    {
+        QSignalSpy useDeliveryReportsComplete(m, SIGNAL(useDeliveryReportsComplete(bool, bool)));
+        QSignalSpy setUseDeliveryReportsFailed(m, SIGNAL(setUseDeliveryReportsFailed()));
+        QSignalSpy useDeliveryReportsChanged(m, SIGNAL(useDeliveryReportsChanged(bool)));
+
+        m->requestUseDeliveryReports();
+        for (int i=0; i<30; i++) {
+            if (useDeliveryReportsComplete.count() > 0)
+                break;
+            QTest::qWait(1000);
+        }
+        QCOMPARE(useDeliveryReportsComplete.count(), 1);
+        QVariantList params = useDeliveryReportsComplete.takeFirst();
+        QCOMPARE(params.at(0).toBool(), true);
+        QCOMPARE(params.at(1).toBool(), false);
+
+        m->setUseDeliveryReports(true);
+        for (int i=0; i<30; i++) {
+            if (setUseDeliveryReportsFailed.count() > 0 || useDeliveryReportsChanged.count() > 0)
+                break;
+            QTest::qWait(1000);
+        }
+        QCOMPARE(setUseDeliveryReportsFailed.count(), 0);
+        QCOMPARE(useDeliveryReportsChanged.count(), 1);
+        QCOMPARE(useDeliveryReportsChanged.takeFirst().at(0).toBool(), true);
+
+         m->setUseDeliveryReports(false);
+         for (int i=0; i<30; i++) {
+             if (setUseDeliveryReportsFailed.count() > 0 || useDeliveryReportsChanged.count() > 0)
+                 break;
+             QTest::qWait(1000);
+         }
+         QCOMPARE(setUseDeliveryReportsFailed.count(), 0);
+         QCOMPARE(useDeliveryReportsChanged.count(), 1);
+         QCOMPARE(useDeliveryReportsChanged.takeFirst().at(0).toBool(), false);
+    }
+
+    void testOfonoMessageManagerAlphabet()
+    {
+        QSignalSpy alphabetComplete(m, SIGNAL(alphabetComplete(bool, QString)));
+        QSignalSpy setAlphabetFailed(m, SIGNAL(setAlphabetFailed()));
+        QSignalSpy alphabetChanged(m, SIGNAL(alphabetChanged(QString)));
+
+        m->requestAlphabet();
+        for (int i=0; i<30; i++) {
+            if (alphabetComplete.count() > 0)
+                break;
+            QTest::qWait(1000);
+        }
+
+        QCOMPARE(alphabetComplete.count(), 1);
+        QVariantList params = alphabetComplete.takeFirst();
+        QCOMPARE(params.at(0).toBool(), true);
+        QString alphabet = params.at(1).toString();
+        QVERIFY(alphabet.length() > 0);
+        QCOMPARE(alphabet, QString("default"));
+        qDebug() << alphabet;
+
+        m->setAlphabet("spanish");
+        for (int i=0; i<30; i++) {
+            if (setAlphabetFailed.count() > 0 || alphabetChanged.count() > 0)
+                break;
+            QTest::qWait(1000);
+        }
+
+        QCOMPARE(setAlphabetFailed.count(), 0);
+        QCOMPARE(alphabetChanged.count(), 1);
+        QCOMPARE(alphabetChanged.takeFirst().at(0).toString(), QString("spanish"));
+
+        m->setAlphabet(alphabet);
+        for (int i=0; i<30; i++) {
+            if (setAlphabetFailed.count() > 0 || alphabetChanged.count() > 0)
+                break;
+            QTest::qWait(1000);
+        }
+
+        QCOMPARE(setAlphabetFailed.count(), 0);
+        QCOMPARE(alphabetChanged.count(), 1);
+        QCOMPARE(alphabetChanged.takeFirst().at(0).toString(), alphabet);
+    }
+
+    void testOfonoMessageManagerBearer()
+    {
+        QSignalSpy bearerComplete(m, SIGNAL(bearerComplete(bool, QString)));
+        QSignalSpy setBearerFailed(m, SIGNAL(setBearerFailed()));
+        QSignalSpy bearerChanged(m, SIGNAL(bearerChanged(QString)));
+
+        m->setBearer("cs-preferred"); // initialize
+        for (int i=0; i<30; i++) {
+            if (setBearerFailed.count() > 0 || bearerChanged.count() > 0)
+                break;
+            QTest::qWait(1000);
+        }
+        m->requestBearer();
+        for (int i=0; i<30; i++) {
+            if (bearerComplete.count() > 0)
+                break;
+            QTest::qWait(1000);
+        }
+
+        QCOMPARE(bearerComplete.count(), 1);
+        QVariantList params = bearerComplete.takeFirst();
+        QCOMPARE(params.at(0).toBool(), true);
+        QString bearer = params.at(1).toString();
+        QVERIFY(bearer.length() > 0);
+        QCOMPARE(bearer, QString("cs-preferred"));
+        qDebug() << bearer;
+
+        m->setBearer("ps-preferred"); // change value
+        for (int i=0; i<30; i++) {
+            if (setBearerFailed.count() > 0 || bearerChanged.count() > 0)
+                break;
+            QTest::qWait(1000);
+        }
+
+        QCOMPARE(setBearerFailed.count(), 0);
+        QCOMPARE(bearerChanged.count(), 1);
+    }
 
     void cleanupTestCase()
     {