telepathy-ofono-0.2+16.04.20151120/ 0000755 0000153 0000161 00000000000 12623676450 017030 5 ustar pbuser pbgroup 0000000 0000000 telepathy-ofono-0.2+16.04.20151120/mmsdservice.cpp 0000644 0000153 0000161 00000011234 12623675611 022054 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#include
#include
#include "dbustypes.h"
#include "mmsdservice.h"
QDBusArgument &operator<<(QDBusArgument &argument, const MessageStruct &message)
{
argument.beginStructure();
argument << message.path << message.properties;
argument.endStructure();
return argument;
}
const QDBusArgument &operator>>(const QDBusArgument &argument, MessageStruct &message)
{
argument.beginStructure();
argument >> message.path >> message.properties;
argument.endStructure();
return argument;
}
QDBusArgument &operator<<(QDBusArgument&argument, const OutgoingAttachmentStruct &attachment)
{
argument.beginStructure();
argument << attachment.id << attachment.contentType << attachment.filePath;
argument.endStructure();
return argument;
}
const QDBusArgument &operator>>(const QDBusArgument &argument, OutgoingAttachmentStruct &attachment)
{
argument.beginStructure();
argument >> attachment.id >> attachment.contentType >> attachment.filePath;
argument.endStructure();
return argument;
}
MMSDService::MMSDService(QString objectPath, oFonoConnection* connection, QObject *parent)
: QObject(parent),
m_servicePath(objectPath)
{
QDBusReply replyMessages;
QDBusReply replyProperties;
QDBusMessage request;
qDBusRegisterMetaType();
qDBusRegisterMetaType();
qDBusRegisterMetaType();
qDBusRegisterMetaType();
request = QDBusMessage::createMethodCall("org.ofono.mms",
m_servicePath, "org.ofono.mms.Service",
"GetProperties");
replyProperties = QDBusConnection::sessionBus().call(request);
m_properties = replyProperties;
request = QDBusMessage::createMethodCall("org.ofono.mms",
m_servicePath, "org.ofono.mms.Service",
"GetMessages");
replyMessages = QDBusConnection::sessionBus().call(request);
m_messages = replyMessages;
QDBusConnection::sessionBus().connect("org.ofono.mms", m_servicePath, "org.ofono.mms.Service",
"MessageAdded", this,
SLOT(onMessageAdded(const QDBusObjectPath&, const QVariantMap&)));
QDBusConnection::sessionBus().connect("org.ofono.mms", m_servicePath, "org.ofono.mms.Service",
"MessageRemoved", this,
SLOT(onMessageRemoved(const QDBusObjectPath&)));
}
MMSDService::~MMSDService()
{
}
QString MMSDService::path() const
{
return m_servicePath;
}
QString MMSDService::modemObjectPath() const
{
return m_properties["ModemObjectPath"].value().path();
}
QVariantMap MMSDService::properties() const
{
return m_properties;
}
MessageList MMSDService::messages() const
{
return m_messages;
}
void MMSDService::onMessageAdded(const QDBusObjectPath &path, const QVariantMap &properties)
{
qDebug() << "message added" << path.path() << properties;
Q_EMIT messageAdded(path.path(), properties);
}
void MMSDService::onMessageRemoved(const QDBusObjectPath& path)
{
qDebug() << "message removed" << path.path();
Q_EMIT messageRemoved(path.path());
}
QDBusObjectPath MMSDService::sendMessage(QStringList recipients, OutgoingAttachmentList attachments)
{
QDBusMessage request;
QList arguments;
QDBusReply reply;
arguments.append(recipients);
arguments.append(QVariant::fromValue(attachments));
request = QDBusMessage::createMethodCall("org.ofono.mms",
m_servicePath, "org.ofono.mms.Service",
"SendMessage");
request.setArguments(arguments);
reply = QDBusConnection::sessionBus().call(request);
return reply;
}
telepathy-ofono-0.2+16.04.20151120/powerddbus.h 0000644 0000153 0000161 00000002057 12623675611 021361 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2014 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Andreas Pokorny
*/
#ifndef POWERD_DUBS_H
#define POWERD_DBUS_H
#include "powerd.h"
#include
class QDBusInterface;
class PowerDDBus : public PowerD
{
public:
PowerDDBus();
void enableProximityHandling() override;
void disableProximityHandling() override;
private:
std::unique_ptr mPowerDIface;
};
#endif
telepathy-ofono-0.2+16.04.20151120/connection.h 0000644 0000153 0000161 00000015723 12623675611 021346 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#ifndef OFONOCONNECTION_H
#define OFONOCONNECTION_H
// telepathy-qt
#include
#include
#include
#include
#include
// ofono-qt
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// telepathy-ofono
#include "ofonotextchannel.h"
#include "ofonocallchannel.h"
#include "emergencymodeiface.h"
#include "voicemailiface.h"
#include "mmsdmanager.h"
#include "mmsdmessage.h"
#include "dbustypes.h"
#include "audiooutputsiface.h"
#include "ussdiface.h"
#ifdef USE_PULSEAUDIO
#include "qpulseaudioengine.h"
#endif
class oFonoConnection;
class oFonoTextChannel;
class oFonoCallChannel;
class oFonoConferenceCallChannel;
class MMSDService;
class oFonoConnection : public Tp::BaseConnection
{
Q_OBJECT
Q_DISABLE_COPY(oFonoConnection)
public:
oFonoConnection(const QDBusConnection &dbusConnection,
const QString &cmName,
const QString &protocolName,
const QVariantMap ¶meters);
QStringList inspectHandles(uint handleType, const Tp::UIntList& handles, Tp::DBusError *error);
Tp::UIntList requestHandles(uint handleType, const QStringList& identifiers, Tp::DBusError* error);
Tp::BaseChannelPtr createChannel(const QVariantMap &request, Tp::DBusError *error);
Tp::ContactAttributesMap getContactAttributes(const Tp::UIntList &handles, const QStringList &ifaces, Tp::DBusError *error);
uint setPresence(const QString& status, const QString& statusMessage, Tp::DBusError *error);
void connect(Tp::DBusError *error);
void setSpeakerMode(bool active);
void setActiveAudioOutput(const QString &id);
AudioOutputList audioOutputs();
QString activeAudioOutput();
QStringList emergencyNumbers(Tp::DBusError *error);
bool voicemailIndicator(Tp::DBusError *error);
QString voicemailNumber(Tp::DBusError *error);
uint voicemailCount(Tp::DBusError *error);
void USSDInitiate(const QString &command, Tp::DBusError *error);
void USSDRespond(const QString &reply, Tp::DBusError *error);
void USSDCancel(Tp::DBusError *error);
Tp::BaseConnectionRequestsInterfacePtr requestsIface;
Tp::BaseConnectionSimplePresenceInterfacePtr simplePresenceIface;
Tp::BaseConnectionContactsInterfacePtr contactsIface;
BaseConnectionEmergencyModeInterfacePtr emergencyModeIface;
BaseConnectionVoicemailInterfacePtr voicemailIface;
BaseConnectionUSSDInterfacePtr supplementaryServicesIface;
uint newHandle(const QString &identifier);
OfonoMessageManager *messageManager();
OfonoVoiceCallManager *voiceCallManager();
OfonoCallVolume *callVolume();
QMap callChannels();
uint ensureHandle(const QString &phoneNumber);
oFonoTextChannel* textChannelForMembers(const QStringList &members);
Tp::BaseChannelPtr createTextChannel(const QVariantMap &request, Tp::DBusError *error);
Tp::BaseChannelPtr createCallChannel(const QVariantMap &request, Tp::DBusError *error);
bool matchChannel(const Tp::BaseChannelPtr &channel, const QVariantMap &request, Tp::DBusError *error);
QString uniqueName() const;
QDBusObjectPath sendMMS(const QStringList &numbers, const OutgoingAttachmentList& attachments);
~oFonoConnection();
Q_SIGNALS:
void activeAudioOutputChanged(const QString &id);
void audioOutputsChanged(const AudioOutputList &outputs);
void channelMerged(const QDBusObjectPath &objPath);
void channelSplitted(const QDBusObjectPath &objPath);
void channelHangup(const QDBusObjectPath &objPath);
void lastChannelClosed();
public Q_SLOTS:
void updateAudioRoute();
void updateAudioRouteToEarpiece();
private Q_SLOTS:
void onOfonoIncomingMessage(const QString &message, const QVariantMap &info);
void onOfonoImmediateMessage(const QString &message, const QVariantMap &info);
void onOfonoCallAdded(const QString &call, const QVariantMap &properties);
void onTextChannelClosed();
void onCallChannelClosed();
void onCallChannelDestroyed();
void onValidityChanged(bool valid);
void onMMSDServiceAdded(const QString&);
void onMMSDServiceRemoved(const QString&);
void onMMSAdded(const QString &, const QVariantMap&);
void onMMSRemoved(const QString &);
void onCheckMMSServices();
void onMessageRead(const QString &id);
void onDeliveryReportReceived(const QString &messageId, const QVariantMap &info);
void onConferenceCallChannelClosed();
void onCallChannelMerged();
void onCallChannelSplitted();
void onMultipartyCallHeld();
void onMultipartyCallActive();
void updateOnlineStatus();
void onDisconnected();
#ifdef USE_PULSEAUDIO
void onAudioModeChanged(AudioMode mode);
void onAvailableAudioModesChanged(AudioModes modes);
#endif
private:
void updateMcc();
bool isNetworkRegistered();
void addMMSToService(const QString &path, const QVariantMap &properties, const QString &servicePath);
void ensureTextChannel(const QString &message, const QVariantMap &info, bool flash);
QMap mHandles;
#ifdef USE_PULSEAUDIO
bool mHasPulseAudio;
#endif
QList mTextChannels;
QMap mCallChannels;
QStringList mModems;
OfonoModemManager *mOfonoModemManager;
OfonoMessageManager *mOfonoMessageManager;
OfonoVoiceCallManager *mOfonoVoiceCallManager;
OfonoCallVolume *mOfonoCallVolume;
OfonoNetworkRegistration *mOfonoNetworkRegistration;
OfonoMessageWaiting *mOfonoMessageWaiting;
OfonoSupplementaryServices *mOfonoSupplementaryServices;
OfonoSimManager *mOfonoSimManager;
OfonoModem *mOfonoModem;
uint mHandleCount;
Tp::SimplePresence mSelfPresence;
MMSDManager *mMmsdManager;
QMap mMmsdServices;
QMap > mServiceMMSList;
oFonoConferenceCallChannel *mConferenceCall;
QString mModemPath;
QString mActiveAudioOutput;
AudioOutputList mAudioOutputs;
};
#endif
telepathy-ofono-0.2+16.04.20151120/voicemailiface.cpp 0000644 0000153 0000161 00000016321 12623675611 022475 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#include
#include
#include
#include "voicemailiface.h"
// Conn.I.Voicemail
BaseConnectionVoicemailInterface::Adaptee::Adaptee(BaseConnectionVoicemailInterface *interface)
: QObject(interface),
mInterface(interface)
{
}
struct TP_QT_NO_EXPORT BaseConnectionVoicemailInterface::Private {
Private(BaseConnectionVoicemailInterface *parent)
: adaptee(new BaseConnectionVoicemailInterface::Adaptee(parent)) {
}
VoicemailCountCallback voicemailCountCB;
VoicemailNumberCallback voicemailNumberCB;
VoicemailIndicatorCallback voicemailIndicatorCB;
BaseConnectionVoicemailInterface::Adaptee *adaptee;
};
BaseConnectionVoicemailInterface::Adaptee::~Adaptee()
{
}
void BaseConnectionVoicemailInterface::Adaptee::voicemailIndicator(const ConnectionInterfaceVoicemailAdaptor::VoicemailIndicatorContextPtr &context)
{
if (!mInterface->mPriv->voicemailIndicatorCB.isValid()) {
context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
return;
}
Tp::DBusError error;
bool active = mInterface->mPriv->voicemailIndicatorCB(&error);
if (error.isValid()) {
context->setFinishedWithError(error.name(), error.message());
return;
}
context->setFinished(active);
}
void BaseConnectionVoicemailInterface::Adaptee::voicemailNumber(const ConnectionInterfaceVoicemailAdaptor::VoicemailNumberContextPtr &context)
{
if (!mInterface->mPriv->voicemailNumberCB.isValid()) {
context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
return;
}
Tp::DBusError error;
QString number = mInterface->mPriv->voicemailNumberCB(&error);
if (error.isValid()) {
context->setFinishedWithError(error.name(), error.message());
return;
}
context->setFinished(number);
}
void BaseConnectionVoicemailInterface::Adaptee::voicemailCount(const ConnectionInterfaceVoicemailAdaptor::VoicemailCountContextPtr &context)
{
if (!mInterface->mPriv->voicemailCountCB.isValid()) {
context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
return;
}
Tp::DBusError error;
uint count = mInterface->mPriv->voicemailCountCB(&error);
if (error.isValid()) {
context->setFinishedWithError(error.name(), error.message());
return;
}
context->setFinished(count);
}
BaseConnectionVoicemailInterface::BaseConnectionVoicemailInterface()
: AbstractConnectionInterface(TP_QT_IFACE_CONNECTION_VOICEMAIL),
mPriv(new Private(this))
{
}
BaseConnectionVoicemailInterface::~BaseConnectionVoicemailInterface()
{
delete mPriv;
}
void BaseConnectionVoicemailInterface::setVoicemailIndicatorCallback(const VoicemailIndicatorCallback &cb)
{
mPriv->voicemailIndicatorCB = cb;
}
void BaseConnectionVoicemailInterface::setVoicemailNumberCallback(const VoicemailNumberCallback &cb)
{
mPriv->voicemailNumberCB = cb;
}
void BaseConnectionVoicemailInterface::setVoicemailCountCallback(const VoicemailCountCallback &cb)
{
mPriv->voicemailCountCB = cb;
}
void BaseConnectionVoicemailInterface::setVoicemailCount(int count)
{
Q_EMIT mPriv->adaptee->voicemailCountChanged(uint(count));
}
void BaseConnectionVoicemailInterface::setVoicemailNumber(const QString &voicemailNumber)
{
Q_EMIT mPriv->adaptee->voicemailNumberChanged(voicemailNumber);
}
void BaseConnectionVoicemailInterface::setVoicemailIndicator(bool active)
{
Q_EMIT mPriv->adaptee->voicemailIndicatorChanged(active);
}
QVariantMap BaseConnectionVoicemailInterface::immutableProperties() const
{
QVariantMap map;
return map;
}
void BaseConnectionVoicemailInterface::createAdaptor()
{
(void) new ConnectionInterfaceVoicemailAdaptor(dbusObject()->dbusConnection(),
mPriv->adaptee, dbusObject());
}
ConnectionInterfaceVoicemailAdaptor::ConnectionInterfaceVoicemailAdaptor(const QDBusConnection& bus, QObject* adaptee, QObject* parent)
: Tp::AbstractAdaptor(bus, adaptee, parent)
{
connect(adaptee, SIGNAL(voicemailCountChanged(uint)), SIGNAL(VoicemailCountChanged(uint)));
connect(adaptee, SIGNAL(voicemailIndicatorChanged(bool)), SIGNAL(VoicemailIndicatorChanged(bool)));
connect(adaptee, SIGNAL(voicemailNumberChanged(QString)), SIGNAL(VoicemailNumberChanged(QString)));
}
ConnectionInterfaceVoicemailAdaptor::~ConnectionInterfaceVoicemailAdaptor()
{
}
bool ConnectionInterfaceVoicemailAdaptor::VoicemailIndicator(const QDBusMessage& dbusMessage)
{
if (!adaptee()->metaObject()->indexOfMethod("voicemailIndicator(ConnectionInterfaceVoicemailAdaptor::VoicemailIndicatorContextPtr)") == -1) {
dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")));
return bool();
}
VoicemailIndicatorContextPtr ctx = VoicemailIndicatorContextPtr(
new Tp::MethodInvocationContext< bool >(dbusConnection(), dbusMessage));
QMetaObject::invokeMethod(adaptee(), "voicemailIndicator",
Q_ARG(ConnectionInterfaceVoicemailAdaptor::VoicemailIndicatorContextPtr, ctx));
return bool();
}
QString ConnectionInterfaceVoicemailAdaptor::VoicemailNumber(const QDBusMessage& dbusMessage)
{
if (!adaptee()->metaObject()->indexOfMethod("voicemailNumber(ConnectionInterfaceVoicemailAdaptor::VoicemailNumberContextPtr)") == -1) {
dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")));
return QString();
}
VoicemailNumberContextPtr ctx = VoicemailNumberContextPtr(
new Tp::MethodInvocationContext< QString >(dbusConnection(), dbusMessage));
QMetaObject::invokeMethod(adaptee(), "voicemailNumber",
Q_ARG(ConnectionInterfaceVoicemailAdaptor::VoicemailNumberContextPtr, ctx));
return QString();
}
uint ConnectionInterfaceVoicemailAdaptor::VoicemailCount(const QDBusMessage& dbusMessage)
{
if (!adaptee()->metaObject()->indexOfMethod("voicemailCount(ConnectionInterfaceVoicemailAdaptor::VoicemailCountContextPtr)") == -1) {
dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")));
return uint();
}
VoicemailCountContextPtr ctx = VoicemailCountContextPtr(
new Tp::MethodInvocationContext< uint >(dbusConnection(), dbusMessage));
QMetaObject::invokeMethod(adaptee(), "voicemailCount",
Q_ARG(ConnectionInterfaceVoicemailAdaptor::VoicemailCountContextPtr, ctx));
return uint();
}
telepathy-ofono-0.2+16.04.20151120/powerd.h 0000644 0000153 0000161 00000002044 12623675611 020477 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2014 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Andreas Pokorny
*/
#ifndef POWERD_H
#define POWERD_H
class PowerD
{
public:
PowerD() = default;
virtual ~PowerD() = default;
PowerD(PowerD const&) = delete;
PowerD& operator=(PowerD const&) = delete;
virtual void enableProximityHandling() = 0;
virtual void disableProximityHandling() = 0;
};
#endif // POWERD_H
telepathy-ofono-0.2+16.04.20151120/powerdaudiomodemediator.cpp 0000644 0000153 0000161 00000003746 12623675611 024460 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2014 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Andreas Pokorny
*/
#include
#include "powerdaudiomodemediator.h"
PowerDAudioModeMediator::PowerDAudioModeMediator(PowerD &powerd)
: powerd(powerd)
{
}
void PowerDAudioModeMediator::audioModeChanged(const QString &mode)
{
bool enableProximity = !(mode == "speaker" || mode == "bluetooth" || mode == "wired_headset");
if (mProximityEnabled != enableProximity)
{
mProximityEnabled = enableProximity;
apply();
}
}
void PowerDAudioModeMediator::apply() const
{
if (mProximityEnabled) {
powerd.enableProximityHandling();
} else {
// we need to power the screen on before disabling the proximity handling
QDBusInterface unityIface("com.canonical.Unity.Screen",
"/com/canonical/Unity/Screen",
"com.canonical.Unity.Screen",
QDBusConnection::systemBus());
QList args;
args.append("on");
args.append(3);
unityIface.callWithArgumentList(QDBus::NoBlock, "setScreenPowerMode", args);
powerd.disableProximityHandling();
}
}
void PowerDAudioModeMediator::audioOutputClosed()
{
if (mProximityEnabled)
{
mProximityEnabled = false;
apply();
}
}
telepathy-ofono-0.2+16.04.20151120/ofono.service.in 0000644 0000153 0000161 00000000201 12623675611 022126 0 ustar pbuser pbgroup 0000000 0000000 [D-BUS Service]
Name=org.freedesktop.Telepathy.ConnectionManager.ofono
Exec=@CMAKE_INSTALL_PREFIX@/@LIBEXEC_DIR@/telepathy-ofono
telepathy-ofono-0.2+16.04.20151120/mmsdmanager.cpp 0000644 0000153 0000161 00000006065 12623675611 022034 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#include
#include
#include "mmsdmanager.h"
struct ServiceStruct {
QDBusObjectPath path;
QVariantMap properties;
};
typedef QList ServiceList;
Q_DECLARE_METATYPE(ServiceStruct)
Q_DECLARE_METATYPE(ServiceList)
QDBusArgument &operator<<(QDBusArgument &argument, const ServiceStruct &service)
{
argument.beginStructure();
argument << service.path << service.properties;
argument.endStructure();
return argument;
}
const QDBusArgument &operator>>(const QDBusArgument &argument, ServiceStruct &service)
{
argument.beginStructure();
argument >> service.path >> service.properties;
argument.endStructure();
return argument;
}
MMSDManager::MMSDManager(QObject *parent)
: QObject(parent)
{
QDBusReply reply;
ServiceList services;
QDBusMessage request;
qDBusRegisterMetaType();
qDBusRegisterMetaType();
request = QDBusMessage::createMethodCall("org.ofono.mms",
"/org/ofono/mms", "org.ofono.mms.Manager",
"GetServices");
reply = QDBusConnection::sessionBus().call(request);
services = reply;
Q_FOREACH(ServiceStruct service, services) {
m_services << service.path.path();
}
QDBusConnection::sessionBus().connect("org.ofono.mms","/org/ofono/mms","org.ofono.mms.Manager",
"ServiceAdded", this,
SLOT(onServiceAdded(const QDBusObjectPath&, const QVariantMap&)));
QDBusConnection::sessionBus().connect("org.ofono.mms","/org/ofono/mms","org.ofono.mms.Manager",
"ServiceRemoved", this,
SLOT(onServiceRemoved(const QDBusObjectPath&)));
}
MMSDManager::~MMSDManager()
{
}
QStringList MMSDManager::services() const
{
return m_services;
}
void MMSDManager::onServiceAdded(const QDBusObjectPath& path, const QVariantMap& map)
{
qDebug() << "service added" << path.path() << map;
m_services << path.path();
Q_EMIT serviceAdded(path.path());
}
void MMSDManager::onServiceRemoved(const QDBusObjectPath& path)
{
qDebug() << "service removed" << path.path();
m_services.removeAll(path.path());
Q_EMIT serviceRemoved(path.path());
}
telepathy-ofono-0.2+16.04.20151120/main.cpp 0000644 0000153 0000161 00000002552 12623675611 020462 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#include
#include
#include
#include "protocol.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Tp::registerTypes();
Tp::enableDebug(true);
Tp::enableWarnings(true);
Tp::BaseProtocolPtr proto = Tp::BaseProtocol::create(
QDBusConnection::sessionBus(), QLatin1String("ofono"));
Tp::BaseConnectionManagerPtr cm = Tp::BaseConnectionManager::create(
QDBusConnection::sessionBus(), QLatin1String("ofono"));
cm->addProtocol(proto);
cm->registerObject();
return a.exec();
}
telepathy-ofono-0.2+16.04.20151120/phoneutils.cpp 0000644 0000153 0000161 00000011350 12623675611 021724 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright (C) 2012-2015 Canonical, Ltd.
*
* Authors:
* Gustavo Pichorim Boiko
* Renato Araujo Oliveira Filho
* Tiago Salem Herrmann
*
* This file is part of telepathy-ofono.
*
* telepathy-ofono is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* telepathy-ofono 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "phoneutils_p.h"
#include
#include
#include
#include
#include
#include
#include
QString PhoneUtils::mMcc = QString();
void PhoneUtils::setMcc(const QString &mcc)
{
mMcc = mcc;
}
QString PhoneUtils::countryCodeForMCC(const QString &mcc, bool useFallback)
{
static QMap countryCodes;
if (countryCodes.isEmpty()) {
QFile countryCodesFile(":/countrycodes.txt");
if (!countryCodesFile.open(QFile::ReadOnly)) {
qCritical() << "Failed to open " << countryCodesFile.fileName();
if (useFallback) {
return region();
}
return QString();
}
QTextStream stream(&countryCodesFile);
while (!stream.atEnd()) {
QString line = stream.readLine();
QStringList tuple = line.split(":");
if (tuple.size() != 2) {
qCritical() << "Failed to parse line" << line;
if (useFallback) {
return region();
}
return QString();
}
countryCodes[tuple[0]] = tuple[1];
}
}
if (!countryCodes.contains(mcc) && useFallback) {
return region();
}
return countryCodes[mcc];
}
QString PhoneUtils::region()
{
QString countryCode = QLocale::system().name().split("_").last();
if (countryCode.size() < 2) {
// fallback to US if no valid country code was provided, otherwise libphonenumber
// will fail to parse any numbers
return QString("US");
}
return countryCode;
}
QString PhoneUtils::normalizePhoneNumber(const QString &phoneNumber)
{
static i18n::phonenumbers::PhoneNumberUtil *phonenumberUtil = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
if (!isPhoneNumber(phoneNumber)) {
return phoneNumber;
}
std::string number = phoneNumber.toStdString();
phonenumberUtil->NormalizeDiallableCharsOnly(&number);
return QString::fromStdString(number);
}
bool PhoneUtils::comparePhoneNumbers(const QString &phoneNumberA, const QString &phoneNumberB)
{
static i18n::phonenumbers::PhoneNumberUtil *phonenumberUtil = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
// if any of the number isn't a phone number, just do a simple string comparison
if (!isPhoneNumber(phoneNumberA) || !isPhoneNumber(phoneNumberB)) {
return phoneNumberA == phoneNumberB;
}
i18n::phonenumbers::PhoneNumberUtil::MatchType match = phonenumberUtil->
IsNumberMatchWithTwoStrings(phoneNumberA.toStdString(),
phoneNumberB.toStdString());
return (match > i18n::phonenumbers::PhoneNumberUtil::NO_MATCH);
}
bool PhoneUtils::isPhoneNumber(const QString &phoneNumber)
{
static i18n::phonenumbers::PhoneNumberUtil *phonenumberUtil = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
std::string formattedNumber;
i18n::phonenumbers::PhoneNumber number;
i18n::phonenumbers::PhoneNumberUtil::ErrorType error;
error = phonenumberUtil->Parse(phoneNumber.toStdString(), countryCodeForMCC(mMcc, true).toStdString(), &number);
switch(error) {
case i18n::phonenumbers::PhoneNumberUtil::INVALID_COUNTRY_CODE_ERROR:
qWarning() << "Invalid country code for:" << phoneNumber;
return false;
case i18n::phonenumbers::PhoneNumberUtil::NOT_A_NUMBER:
qWarning() << "The phone number is not a valid number:" << phoneNumber;
return false;
case i18n::phonenumbers::PhoneNumberUtil::TOO_SHORT_AFTER_IDD:
case i18n::phonenumbers::PhoneNumberUtil::TOO_SHORT_NSN:
case i18n::phonenumbers::PhoneNumberUtil::TOO_LONG_NSN:
qWarning() << "Invalid phone number" << phoneNumber;
return false;
default:
break;
}
return true;
}
telepathy-ofono-0.2+16.04.20151120/phoneutils_p.h 0000644 0000153 0000161 00000003036 12623675611 021712 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright (C) 2015 Canonical, Ltd.
*
* Authors:
* Gustavo Pichorim Boiko
* Renato Araujo Oliveira Filho
* Tiago Salem Herrmann
*
* This file is part of telepathy-ofono.
*
* telepathy-ofono is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* telepathy-ofono 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef TELEPHONY_PHONEUTILS_H
#define TELEPHONY_PHONEUTILS_H
#include
class PhoneUtils : public QObject
{
Q_OBJECT
public:
enum PhoneNumberFormat {
E164 = 0,
International,
National,
RFC3966,
Auto
};
static QString normalizePhoneNumber(const QString &phoneNumber);
static bool comparePhoneNumbers(const QString &phoneNumberA,const QString &phoneNumberB);
static bool isPhoneNumber(const QString &identifier);
static QString countryCodeForMCC(const QString &mcc, bool useFallback = true);
static void setMcc(const QString &mcc);
private:
static QString region();
static QString mMcc;
};
#endif
telepathy-ofono-0.2+16.04.20151120/ussdiface.cpp 0000644 0000153 0000161 00000024713 12623675611 021507 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#include
#include
#include
#include "ussdiface.h"
// Conn.I.USSD
BaseConnectionUSSDInterface::Adaptee::Adaptee(BaseConnectionUSSDInterface *interface)
: QObject(interface),
mInterface(interface)
{
}
struct TP_QT_NO_EXPORT BaseConnectionUSSDInterface::Private {
Private(BaseConnectionUSSDInterface *parent)
: adaptee(new BaseConnectionUSSDInterface::Adaptee(parent)) {
}
QString state;
QString serial;
InitiateCallback initiateCB;
RespondCallback respondCB;
CancelCallback cancelCB;
BaseConnectionUSSDInterface::Adaptee *adaptee;
};
BaseConnectionUSSDInterface::Adaptee::~Adaptee()
{
}
void BaseConnectionUSSDInterface::Adaptee::initiate(const QString &command, const ConnectionInterfaceUSSDAdaptor::InitiateContextPtr &context)
{
if (!mInterface->mPriv->initiateCB.isValid()) {
context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
return;
}
Tp::DBusError error;
mInterface->mPriv->initiateCB(command, &error);
if (error.isValid()) {
context->setFinishedWithError(error.name(), error.message());
return;
}
context->setFinished();
}
void BaseConnectionUSSDInterface::Adaptee::respond(const QString &reply, const ConnectionInterfaceUSSDAdaptor::RespondContextPtr &context)
{
if (!mInterface->mPriv->respondCB.isValid()) {
context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
return;
}
Tp::DBusError error;
mInterface->mPriv->respondCB(reply, &error);
if (error.isValid()) {
context->setFinishedWithError(error.name(), error.message());
return;
}
context->setFinished();
}
void BaseConnectionUSSDInterface::Adaptee::cancel(const ConnectionInterfaceUSSDAdaptor::CancelContextPtr &context)
{
if (!mInterface->mPriv->cancelCB.isValid()) {
context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
return;
}
Tp::DBusError error;
mInterface->mPriv->cancelCB(&error);
if (error.isValid()) {
context->setFinishedWithError(error.name(), error.message());
return;
}
context->setFinished();
}
BaseConnectionUSSDInterface::BaseConnectionUSSDInterface()
: AbstractConnectionInterface(TP_QT_IFACE_CONNECTION_USSD),
mPriv(new Private(this))
{
}
BaseConnectionUSSDInterface::~BaseConnectionUSSDInterface()
{
delete mPriv;
}
void BaseConnectionUSSDInterface::setInitiateCallback(const InitiateCallback &cb)
{
mPriv->initiateCB = cb;
}
void BaseConnectionUSSDInterface::setRespondCallback(const RespondCallback &cb)
{
mPriv->respondCB = cb;
}
void BaseConnectionUSSDInterface::setCancelCallback(const CancelCallback &cb)
{
mPriv->cancelCB = cb;
}
QString BaseConnectionUSSDInterface::state() const
{
return mPriv->state;
}
void BaseConnectionUSSDInterface::setSerial(const QString &serial) const
{
mPriv->serial = serial;
}
QString BaseConnectionUSSDInterface::serial() const
{
return mPriv->serial;
}
void BaseConnectionUSSDInterface::StateChanged(const QString &state)
{
mPriv->state = state;
Q_EMIT mPriv->adaptee->stateChanged(state);
}
void BaseConnectionUSSDInterface::InitiateUSSDComplete(const QString &ussdResp)
{
Q_EMIT mPriv->adaptee->initiateUSSDComplete(ussdResp);
}
void BaseConnectionUSSDInterface::RespondComplete(bool success, const QString &ussdResp)
{
Q_EMIT mPriv->adaptee->respondComplete(success, ussdResp);
}
void BaseConnectionUSSDInterface::BarringComplete(const QString &ssOp, const QString &cbService, const QVariantMap &cbMap)
{
Q_EMIT mPriv->adaptee->barringComplete(ssOp, cbService, cbMap);
}
void BaseConnectionUSSDInterface::ForwardingComplete(const QString &ssOp, const QString &cfService, const QVariantMap &cfMap)
{
Q_EMIT mPriv->adaptee->forwardingComplete(ssOp, cfService, cfMap);
}
void BaseConnectionUSSDInterface::WaitingComplete(const QString &ssOp, const QVariantMap &cwMap)
{
Q_EMIT mPriv->adaptee->waitingComplete(ssOp, cwMap);
}
void BaseConnectionUSSDInterface::CallingLinePresentationComplete(const QString &ssOp, const QString &status)
{
Q_EMIT mPriv->adaptee->callingLinePresentationComplete(ssOp, status);
}
void BaseConnectionUSSDInterface::ConnectedLinePresentationComplete(const QString &ssOp, const QString &status)
{
Q_EMIT mPriv->adaptee->connectedLinePresentationComplete(ssOp, status);
}
void BaseConnectionUSSDInterface::CallingLineRestrictionComplete(const QString &ssOp, const QString &status)
{
Q_EMIT mPriv->adaptee->callingLineRestrictionComplete(ssOp, status);
}
void BaseConnectionUSSDInterface::ConnectedLineRestrictionComplete(const QString &ssOp, const QString &status)
{
Q_EMIT mPriv->adaptee->connectedLineRestrictionComplete(ssOp, status);
}
void BaseConnectionUSSDInterface::InitiateFailed()
{
Q_EMIT mPriv->adaptee->initiateFailed();
}
void BaseConnectionUSSDInterface::NotificationReceived(const QString &message)
{
Q_EMIT mPriv->adaptee->notificationReceived(message);
}
void BaseConnectionUSSDInterface::RequestReceived(const QString &message)
{
Q_EMIT mPriv->adaptee->requestReceived(message);
}
QVariantMap BaseConnectionUSSDInterface::immutableProperties() const
{
QVariantMap map;
return map;
}
void BaseConnectionUSSDInterface::createAdaptor()
{
(void) new ConnectionInterfaceUSSDAdaptor(dbusObject()->dbusConnection(),
mPriv->adaptee, dbusObject());
}
ConnectionInterfaceUSSDAdaptor::ConnectionInterfaceUSSDAdaptor(const QDBusConnection& bus, QObject* adaptee, QObject* parent)
: Tp::AbstractAdaptor(bus, adaptee, parent)
{
connect(adaptee, SIGNAL(notificationReceived(const QString &)), SIGNAL(NotificationReceived(const QString &)));
connect(adaptee, SIGNAL(requestReceived(const QString &)), SIGNAL(RequestReceived(const QString &)));
connect(adaptee, SIGNAL(initiateUSSDComplete(const QString &)), SIGNAL(InitiateUSSDComplete(const QString &)));
connect(adaptee, SIGNAL(barringComplete(const QString &, const QString &, const QVariantMap &)),
SIGNAL(BarringComplete(const QString &, const QString &, const QVariantMap &)));
connect(adaptee, SIGNAL(forwardingComplete(const QString &, const QString &, const QVariantMap &)),
SIGNAL(ForwardingComplete(const QString &, const QString &, const QVariantMap &)));
connect(adaptee, SIGNAL(waitingComplete(const QString &, const QVariantMap &)),
SIGNAL(WaitingComplete(const QString &, const QVariantMap &)));
connect(adaptee, SIGNAL(callingLinePresentationComplete(const QString &, const QString &)),
SIGNAL(CallingLinePresentationComplete(const QString &, const QString &)));
connect(adaptee, SIGNAL(connectedLinePresentationComplete(const QString &, const QString &)),
SIGNAL(ConnectedLinePresentationComplete(const QString &, const QString &)));
connect(adaptee, SIGNAL(callingLineRestrictionComplete(const QString &, const QString &)),
SIGNAL(CallingLineRestrictionComplete(const QString &, const QString &)));
connect(adaptee, SIGNAL(connectedLineRestrictionComplete(const QString &, const QString &)),
SIGNAL(ConnectedLineRestrictionComplete(const QString &, const QString &)));
connect(adaptee, SIGNAL(initiateFailed()), SIGNAL(InitiateFailed()));
connect(adaptee, SIGNAL(stateChanged(const QString&)), SIGNAL(StateChanged(const QString&)));
connect(adaptee, SIGNAL(respondComplete(bool, const QString &)), SIGNAL(RespondComplete(bool, const QString &)));
}
ConnectionInterfaceUSSDAdaptor::~ConnectionInterfaceUSSDAdaptor()
{
}
void ConnectionInterfaceUSSDAdaptor::Initiate(const QString &command, const QDBusMessage& dbusMessage)
{
if (!adaptee()->metaObject()->indexOfMethod("initiate(const QString &,ConnectionInterfaceUSSDAdaptor::InitiateContextPtr)") == -1) {
dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")));
return;
}
InitiateContextPtr ctx = InitiateContextPtr(
new Tp::MethodInvocationContext< >(dbusConnection(), dbusMessage));
QMetaObject::invokeMethod(adaptee(), "initiate",
Q_ARG(QString, command),
Q_ARG(ConnectionInterfaceUSSDAdaptor::InitiateContextPtr, ctx));
return;
}
void ConnectionInterfaceUSSDAdaptor::Respond(const QString &reply, const QDBusMessage& dbusMessage)
{
if (!adaptee()->metaObject()->indexOfMethod("respond(QConnectionInterfaceUSSDAdaptor::RespondContextPtr)") == -1) {
dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")));
return;
}
RespondContextPtr ctx = RespondContextPtr(
new Tp::MethodInvocationContext< >(dbusConnection(), dbusMessage));
QMetaObject::invokeMethod(adaptee(), "respond",
Q_ARG(QString, reply),
Q_ARG(ConnectionInterfaceUSSDAdaptor::RespondContextPtr, ctx));
return;
}
void ConnectionInterfaceUSSDAdaptor::Cancel(const QDBusMessage& dbusMessage)
{
if (!adaptee()->metaObject()->indexOfMethod("cancel(ConnectionInterfaceUSSDAdaptor::CancelContextPtr)") == -1) {
dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")));
return;
}
CancelContextPtr ctx = CancelContextPtr(
new Tp::MethodInvocationContext< >(dbusConnection(), dbusMessage));
QMetaObject::invokeMethod(adaptee(), "cancel",
Q_ARG(ConnectionInterfaceUSSDAdaptor::CancelContextPtr, ctx));
return;
}
QString ConnectionInterfaceUSSDAdaptor::Serial() const
{
return qvariant_cast< QString >(adaptee()->property("serial"));
}
QString ConnectionInterfaceUSSDAdaptor::State() const
{
return qvariant_cast< QString >(adaptee()->property("state"));
}
telepathy-ofono-0.2+16.04.20151120/CMakeLists.txt 0000644 0000153 0000161 00000010665 12623675611 021576 0 ustar pbuser pbgroup 0000000 0000000 project(telepathy-ofono)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
set(TELEPATHY_OFONO telepathy-ofono)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Standard install paths
include(GNUInstallDirs)
# Check for include files
include(CheckIncludeFileCXX)
include(EnableCoverageReport)
#####################################################################
# Enable code coverage calculation with gcov/gcovr/lcov
# Usage:
# * Switch build type to coverage (use ccmake or cmake-gui)
# * Invoke make, make test, make coverage
# * Find html report in subdir coveragereport
# * Find xml report feasible for jenkins in coverage.xml
#####################################################################
IF(CMAKE_BUILD_TYPE MATCHES [cC][oO][vV][eE][rR][aA][gG][eE])
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage -fprofile-arcs" )
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -coverage" )
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -coverage" )
ENABLE_COVERAGE_REPORT(TARGETS ${TELEPATHY_OFONO})
ENDIF(CMAKE_BUILD_TYPE MATCHES [cC][oO][vV][eE][rR][aA][gG][eE])
find_package(LibPhoneNumber REQUIRED)
find_package(Qt5Core)
find_package(Qt5DBus)
add_definitions(-DQT_NO_KEYWORDS)
find_package(PkgConfig REQUIRED)
pkg_check_modules(TP_QT5 REQUIRED TelepathyQt5)
pkg_check_modules(SQLITE3 REQUIRED sqlite3)
pkg_check_modules(MC_PLUGINS REQUIRED mission-control-plugins)
pkg_check_modules(PULSEAUDIO libpulse)
if (PULSEAUDIO_FOUND)
add_definitions(-DUSE_PULSEAUDIO)
set(USE_PULSEAUDIO ON)
include_directories(${PULSEAUDIO_INCLUDE_DIRS})
endif (PULSEAUDIO_FOUND)
find_program(DBUS_RUNNER dbus-test-runner)
if(NOT DAEMON_DIR)
set(DAEMON_DIR lib/telepathy)
endif(NOT DAEMON_DIR)
set(CMAKE_AUTOMOC ON)
include_directories(${TP_QT5_INCLUDE_DIRS})
include_directories(${Qt5Core_INCLUDE_DIRS})
include_directories(${Qt5DBus_INCLUDE_DIRS})
include_directories(${SQLITE3_INCLUDE_DIRS})
include_directories(${LibPhoneNumber_INCLUDE_DIRS})
include_directories(/usr/include/telepathy-qt5/)
include_directories(/usr/include/ofono-qt/)
find_library(TELEPATHY_QT5_LIBRARIES telepathy-qt5)
find_library(TELEPATHY_QT5_SERVICE_LIBRARIES telepathy-qt5-service)
find_library(OFONO_QT_LIBRARIES ofono-qt)
qt5_add_resources(telepathyfono_RES sqlitetelepathyofono.qrc countrycodes.qrc)
# update the .qrc file automatically when there are new schema files
file(GLOB QRC_RESOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/schema/*.sql ${CMAKE_CURRENT_SOURCE_DIR}/schema/*.info)
set(QRC_FILE ${CMAKE_CURRENT_SOURCE_DIR}/sqlitetelepathyofono.qrc)
add_custom_command(
OUTPUT ${QRC_FILE}
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/update_qrc.sh ${QRC_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${QRC_RESOURCE_FILES}
)
add_custom_target(qrc_update DEPENDS ${QRC_FILE} schema_update)
set(TELEPATHY_OFONO_SRC
main.cpp
protocol.cpp
connection.cpp
ofonotextchannel.cpp
ofonocallchannel.cpp
ofonoconferencecallchannel.cpp
emergencymodeiface.cpp
voicemailiface.cpp
audiooutputsiface.cpp
mmsdmanager.cpp
mmsdservice.cpp
mmsdmessage.cpp
pendingmessagesmanager.cpp
phoneutils.cpp
powerdaudiomodemediator.cpp
powerddbus.cpp
sqlitedatabase.cpp
ussdiface.cpp
${telepathyfono_RES})
if(USE_PULSEAUDIO)
add_executable(${TELEPATHY_OFONO} qpulseaudioengine.cpp ${TELEPATHY_OFONO_SRC})
else(USE_PULSEAUDIO)
add_executable(${TELEPATHY_OFONO} ${TELEPATHY_OFONO_SRC})
endif(USE_PULSEAUDIO)
qt5_use_modules(${TELEPATHY_OFONO} Core DBus Sql)
add_dependencies(${TELEPATHY_OFONO} schema_update qrc_update)
enable_testing()
target_link_libraries(${TELEPATHY_OFONO} ${Qt5Core_LIBRARIES} ${Qt5DBus_LIBRARIES} ${WAUDIO_LIBRARIES} -ltelepathy-qt5 ${TELEPATHY_QT5_SERVICE_LIBRARIES} ${OFONO_QT_LIBRARIES} ${PULSEAUDIO_LIBRARIES} ${SQLITE3_LIBRARIES} ${LibPhoneNumber_LIBRARIES})
install(TARGETS ${TELEPATHY_OFONO} DESTINATION ${DAEMON_DIR})
configure_file(ofono.service.in org.freedesktop.Telepathy.ConnectionManager.ofono.service)
install (FILES ofono.manager DESTINATION share/telepathy/managers)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.ConnectionManager.ofono.service DESTINATION share/dbus-1/services)
add_subdirectory(schema)
add_subdirectory(tests)
add_subdirectory(mc-plugin)
telepathy-ofono-0.2+16.04.20151120/emergencymodeiface.cpp 0000644 0000153 0000161 00000013517 12623675611 023354 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
* Gustavo Pichorim Boiko
*/
#include
#include
#include
#include "emergencymodeiface.h"
BaseConnectionEmergencyModeInterface::Adaptee::Adaptee(BaseConnectionEmergencyModeInterface *interface)
: QObject(interface),
mInterface(interface)
{
}
struct TP_QT_NO_EXPORT BaseConnectionEmergencyModeInterface::Private {
Private(BaseConnectionEmergencyModeInterface *parent)
: adaptee(new BaseConnectionEmergencyModeInterface::Adaptee(parent)) {
}
EmergencyNumbersCallback emergencyNumbersCB;
BaseConnectionEmergencyModeInterface::Adaptee *adaptee;
QString fakeEmergencyNumber;
QString countryCode;
};
BaseConnectionEmergencyModeInterface::Adaptee::~Adaptee()
{
}
void BaseConnectionEmergencyModeInterface::Adaptee::emergencyNumbers(const ConnectionInterfaceEmergencyModeAdaptor::EmergencyNumbersContextPtr &context)
{
if (!mInterface->mPriv->emergencyNumbersCB.isValid()) {
context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
return;
}
Tp::DBusError error;
QStringList numbers = mInterface->mPriv->emergencyNumbersCB(&error);
if (error.isValid()) {
context->setFinishedWithError(error.name(), error.message());
return;
}
if (mInterface->mPriv->fakeEmergencyNumber.isEmpty()) {
context->setFinished(numbers);
} else {
context->setFinished(QStringList() << numbers << mInterface->mPriv->fakeEmergencyNumber);
}
}
void BaseConnectionEmergencyModeInterface::Adaptee::countryCode(const ConnectionInterfaceEmergencyModeAdaptor::CountryCodeContextPtr &context)
{
context->setFinished(mInterface->mPriv->countryCode);
}
BaseConnectionEmergencyModeInterface::BaseConnectionEmergencyModeInterface()
: AbstractConnectionInterface(TP_QT_IFACE_CONNECTION_EMERGENCYMODE),
mPriv(new Private(this))
{
}
BaseConnectionEmergencyModeInterface::~BaseConnectionEmergencyModeInterface()
{
delete mPriv;
}
void BaseConnectionEmergencyModeInterface::setEmergencyNumbersCallback(const EmergencyNumbersCallback &cb)
{
mPriv->emergencyNumbersCB = cb;
}
void BaseConnectionEmergencyModeInterface::setEmergencyNumbers(const QStringList &numbers)
{
QStringList finalEmergencyList(numbers);
if (!mPriv->fakeEmergencyNumber.isEmpty()) {
finalEmergencyList << mPriv->fakeEmergencyNumber;
}
Q_EMIT mPriv->adaptee->emergencyNumbersChanged(finalEmergencyList);
}
void BaseConnectionEmergencyModeInterface::setCountryCode(const QString &countryCode)
{
if (mPriv->countryCode == countryCode) {
return;
}
mPriv->countryCode = countryCode;
Q_EMIT mPriv->adaptee->countryCodeChanged(mPriv->countryCode);
}
void BaseConnectionEmergencyModeInterface::setFakeEmergencyNumber(const QString &fakeEmergencyNumber)
{
mPriv->fakeEmergencyNumber = fakeEmergencyNumber;
}
QVariantMap BaseConnectionEmergencyModeInterface::immutableProperties() const
{
QVariantMap map;
return map;
}
void BaseConnectionEmergencyModeInterface::createAdaptor()
{
(void) new ConnectionInterfaceEmergencyModeAdaptor(dbusObject()->dbusConnection(),
mPriv->adaptee, dbusObject());
}
ConnectionInterfaceEmergencyModeAdaptor::ConnectionInterfaceEmergencyModeAdaptor(const QDBusConnection& bus, QObject* adaptee, QObject* parent)
: Tp::AbstractAdaptor(bus, adaptee, parent)
{
connect(adaptee, SIGNAL(emergencyNumbersChanged(QStringList)), SIGNAL(EmergencyNumbersChanged(QStringList)));
connect(adaptee, SIGNAL(countryCodeChanged(QString)), SIGNAL(CountryCodeChanged(QString)));
}
ConnectionInterfaceEmergencyModeAdaptor::~ConnectionInterfaceEmergencyModeAdaptor()
{
}
QStringList ConnectionInterfaceEmergencyModeAdaptor::EmergencyNumbers(const QDBusMessage& dbusMessage)
{
if (!adaptee()->metaObject()->indexOfMethod("emergencyNumbers(ConnectionInterfaceEmergencyModeAdaptor::EmergencyNumbersContextPtr)") == -1) {
dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")));
return QStringList();
}
EmergencyNumbersContextPtr ctx = EmergencyNumbersContextPtr(
new Tp::MethodInvocationContext< QStringList >(dbusConnection(), dbusMessage));
QMetaObject::invokeMethod(adaptee(), "emergencyNumbers",
Q_ARG(ConnectionInterfaceEmergencyModeAdaptor::EmergencyNumbersContextPtr, ctx));
return QStringList();
}
QString ConnectionInterfaceEmergencyModeAdaptor::CountryCode(const QDBusMessage& dbusMessage)
{
if (!adaptee()->metaObject()->indexOfMethod("countryCode(ConnectionInterfaceEmergencyModeAdaptor::CountryCodeContextPtr)") == -1) {
dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")));
return QString();
}
CountryCodeContextPtr ctx = CountryCodeContextPtr(
new Tp::MethodInvocationContext< QString >(dbusConnection(), dbusMessage));
QMetaObject::invokeMethod(adaptee(), "countryCode",
Q_ARG(ConnectionInterfaceEmergencyModeAdaptor::CountryCodeContextPtr, ctx));
return QString();
}
telepathy-ofono-0.2+16.04.20151120/mmsdmessage.cpp 0000644 0000153 0000161 00000004304 12623675611 022040 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#include
#include
#include "mmsdmessage.h"
MMSDMessage::MMSDMessage(QString objectPath, QVariantMap properties, QObject *parent)
: QObject(parent),
m_messagePath(objectPath),
m_properties(properties)
{
QDBusConnection::sessionBus().connect("org.ofono.mms", m_messagePath, "org.ofono.mms.Message",
"PropertyChanged", this,
SLOT(onPropertyChanged(QString,QDBusVariant)));
}
MMSDMessage::~MMSDMessage()
{
}
QString MMSDMessage::path() const
{
return m_messagePath;
}
QVariantMap MMSDMessage::properties() const
{
return m_properties;
}
void MMSDMessage::onPropertyChanged(const QString &property, const QDBusVariant &value)
{
QVariant variantValue = value.variant();
m_properties[property] = variantValue;
Q_EMIT propertyChanged(property, variantValue);
}
void MMSDMessage::markRead() const
{
QDBusMessage request;
request = QDBusMessage::createMethodCall("org.ofono.mms",
m_messagePath, "org.ofono.mms.Message",
"MarkRead");
QDBusConnection::sessionBus().call(request);
}
void MMSDMessage::remove() const
{
QDBusMessage request;
request = QDBusMessage::createMethodCall("org.ofono.mms",
m_messagePath, "org.ofono.mms.Message",
"Delete");
QDBusConnection::sessionBus().call(request);
}
telepathy-ofono-0.2+16.04.20151120/pendingmessagesmanager.h 0000644 0000153 0000161 00000002400 12623675611 023702 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#include
#include
struct PendingMessage
{
QString recipientId;
QDateTime timestamp;
};
class PendingMessagesManager : public QObject
{
Q_OBJECT
public:
static PendingMessagesManager *instance();
void addPendingMessage(const QString &objectPath, const QString &id);
void removePendingMessage(const QString &objectPath);
QString recipientIdForMessageId(const QString &messageId);
private:
explicit PendingMessagesManager(QObject *parent = 0);
QSqlDatabase mDatabase;
};
telepathy-ofono-0.2+16.04.20151120/audiooutputsiface.h 0000644 0000153 0000161 00000011461 12623675611 022737 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#ifndef OFONOAUDIOOUTPUTSIFACE_H
#define OFONOAUDIOOUTPUTSIFACE_H
// telepathy-qt
#include
#include
#include
#include
#include
#include "dbustypes.h"
#define TP_QT_IFACE_CHANNEL_AUDIOOUTPUTS "com.canonical.Telephony.AudioOutputs"
class BaseChannelAudioOutputsInterface;
typedef Tp::SharedPtr BaseChannelAudioOutputsInterfacePtr;
class TP_QT_EXPORT BaseChannelAudioOutputsInterface : public Tp::AbstractChannelInterface
{
Q_OBJECT
Q_DISABLE_COPY(BaseChannelAudioOutputsInterface)
public:
static BaseChannelAudioOutputsInterfacePtr create() {
return BaseChannelAudioOutputsInterfacePtr(new BaseChannelAudioOutputsInterface());
}
template
static Tp::SharedPtr create() {
return Tp::SharedPtr(
new BaseChannelAudioOutputsInterfaceSubclass());
}
QVariantMap immutableProperties() const;
virtual ~BaseChannelAudioOutputsInterface();
AudioOutputList audioOutputs() const;
QString activeAudioOutput() const;
typedef Tp::Callback2 SetActiveAudioOutputCallback;
void setSetActiveAudioOutputCallback(const SetActiveAudioOutputCallback &cb);
public Q_SLOTS:
void setActiveAudioOutput(const QString &id);
void setAudioOutputs(const AudioOutputList &outputs);
protected:
BaseChannelAudioOutputsInterface();
private:
void createAdaptor();
class Adaptee;
friend class Adaptee;
struct Private;
friend struct Private;
Private *mPriv;
};
class TP_QT_EXPORT ChannelInterfaceAudioOutputsAdaptor : public Tp::AbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", TP_QT_IFACE_CHANNEL_AUDIOOUTPUTS)
Q_CLASSINFO("D-Bus Introspection", ""
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
"")
Q_PROPERTY(AudioOutputList AudioOutputs READ AudioOutputs)
Q_PROPERTY(QString ActiveAudioOutput READ ActiveAudioOutput)
public:
ChannelInterfaceAudioOutputsAdaptor(const QDBusConnection& dbusConnection, QObject* adaptee, QObject* parent);
virtual ~ChannelInterfaceAudioOutputsAdaptor();
typedef Tp::MethodInvocationContextPtr< > SetActiveAudioOutputContextPtr;
public: // PROPERTIES
QString ActiveAudioOutput() const;
AudioOutputList AudioOutputs() const;
public Q_SLOTS: // METHODS
void SetActiveAudioOutput(const QString &id, const QDBusMessage& dbusMessage);
Q_SIGNALS: // SIGNALS
void AudioOutputsChanged(const AudioOutputList &outputs);
void ActiveAudioOutputChanged(const QString &id);
};
class TP_QT_NO_EXPORT BaseChannelAudioOutputsInterface::Adaptee : public QObject
{
Q_OBJECT
Q_PROPERTY(AudioOutputList audioOutputs READ audioOutputs)
Q_PROPERTY(QString activeAudioOutput READ activeAudioOutput)
public:
Adaptee(BaseChannelAudioOutputsInterface *interface);
~Adaptee();
AudioOutputList audioOutputs() const
{
return mInterface->audioOutputs();
}
QString activeAudioOutput() const
{
return mInterface->activeAudioOutput();
}
private Q_SLOTS:
void setActiveAudioOutput(const QString &id, const ChannelInterfaceAudioOutputsAdaptor::SetActiveAudioOutputContextPtr &context);
Q_SIGNALS:
void activeAudioOutputChanged(const QString &id);
void audioOutputsChanged(const AudioOutputList &outputs);
public:
BaseChannelAudioOutputsInterface *mInterface;
};
#endif
telepathy-ofono-0.2+16.04.20151120/qpulseaudioengine.cpp 0000644 0000153 0000161 00000073446 12623675611 023271 0 ustar pbuser pbgroup 0000000 0000000 /****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file was taken from qt5 and modified by
** David Henningsson for usage in
** telepathy-ofono.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
****************************************************************************/
#include
#include "qpulseaudioengine.h"
#include
#include
#define PULSEAUDIO_PROFILE_HSP "headset_head_unit"
#define PULSEAUDIO_PROFILE_A2DP "a2dp_sink"
QT_BEGIN_NAMESPACE
static void contextStateCallbackInit(pa_context *context, void *userdata)
{
Q_UNUSED(context);
QPulseAudioEngineWorker *pulseEngine = reinterpret_cast(userdata);
pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
}
static void contextStateCallback(pa_context *context, void *userdata)
{
Q_UNUSED(userdata);
Q_UNUSED(context);
}
static void success_cb(pa_context *context, int success, void *userdata)
{
QPulseAudioEngineWorker *pulseEngine = reinterpret_cast(userdata);
pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
}
/* Callbacks used when handling events from PulseAudio */
static void plug_card_cb(pa_context *c, const pa_card_info *info, int isLast, void *userdata)
{
QPulseAudioEngineWorker *pulseEngine = static_cast(userdata);
if (isLast != 0 || !pulseEngine || !info) {
pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
return;
}
pulseEngine->plugCardCallback(info);
}
static void update_card_cb(pa_context *c, const pa_card_info *info, int isLast, void *userdata)
{
QPulseAudioEngineWorker *pulseEngine = static_cast(userdata);
if (isLast != 0 || !pulseEngine || !info) {
pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
return;
}
pulseEngine->updateCardCallback(info);
}
static void unplug_card_cb(pa_context *c, const pa_card_info *info, int isLast, void *userdata)
{
QPulseAudioEngineWorker *pulseEngine = static_cast(userdata);
if (!pulseEngine) {
pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
return;
}
if (info == NULL) {
/* That means that the card used to query card_info was removed */
pulseEngine->unplugCardCallback();
}
}
static void subscribeCallback(pa_context *context, pa_subscription_event_type_t t, uint32_t idx, void *userdata)
{
/* For card change events (slot plug/unplug and add/remove card) */
if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_CARD) {
if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_CHANGE) {
QMetaObject::invokeMethod((QPulseAudioEngineWorker *) userdata, "handleCardEvent",
Qt::QueuedConnection, Q_ARG(int, PA_SUBSCRIPTION_EVENT_CHANGE), Q_ARG(unsigned int, idx));
} else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
QMetaObject::invokeMethod((QPulseAudioEngineWorker *) userdata, "handleCardEvent",
Qt::QueuedConnection, Q_ARG(int, PA_SUBSCRIPTION_EVENT_NEW), Q_ARG(unsigned int, idx));
} else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
QMetaObject::invokeMethod((QPulseAudioEngineWorker *) userdata, "handleCardEvent",
Qt::QueuedConnection, Q_ARG(int, PA_SUBSCRIPTION_EVENT_REMOVE), Q_ARG(unsigned int, idx));
}
}
}
QPulseAudioEngineWorker::QPulseAudioEngineWorker(QObject *parent)
: QObject(parent)
, m_mainLoopApi(0)
, m_context(0)
, m_callstatus(CallEnded)
, m_audiomode(AudioModeSpeaker)
, m_micmute(false)
, m_defaultsink("sink.primary")
, m_defaultsource("source.primary")
, m_voicecallcard("")
, m_voicecallhighest("")
, m_voicecallprofile("")
, m_bt_hsp("")
, m_bt_hsp_a2dp("")
{
m_mainLoop = pa_threaded_mainloop_new();
if (m_mainLoop == 0) {
qWarning("Unable to create pulseaudio mainloop");
return;
}
if (pa_threaded_mainloop_start(m_mainLoop) != 0) {
qWarning("Unable to start pulseaudio mainloop");
pa_threaded_mainloop_free(m_mainLoop);
m_mainLoop = 0;
return;
}
createPulseContext();
}
bool QPulseAudioEngineWorker::createPulseContext()
{
bool keepGoing = true;
bool ok = true;
if (m_context)
return true;
m_mainLoopApi = pa_threaded_mainloop_get_api(m_mainLoop);
pa_threaded_mainloop_lock(m_mainLoop);
m_context = pa_context_new(m_mainLoopApi, QString(QLatin1String("QtmPulseContext:%1")).arg(::getpid()).toLatin1().constData());
pa_context_set_state_callback(m_context, contextStateCallbackInit, this);
if (!m_context) {
qWarning("Unable to create new pulseaudio context");
pa_threaded_mainloop_unlock(m_mainLoop);
return false;
}
if (pa_context_connect(m_context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL) < 0) {
qWarning("Unable to create a connection to the pulseaudio context");
pa_threaded_mainloop_unlock(m_mainLoop);
releasePulseContext();
return false;
}
pa_threaded_mainloop_wait(m_mainLoop);
while (keepGoing) {
switch (pa_context_get_state(m_context)) {
case PA_CONTEXT_CONNECTING:
case PA_CONTEXT_AUTHORIZING:
case PA_CONTEXT_SETTING_NAME:
break;
case PA_CONTEXT_READY:
qDebug("Pulseaudio connection established.");
keepGoing = false;
break;
case PA_CONTEXT_TERMINATED:
qCritical("Pulseaudio context terminated.");
keepGoing = false;
ok = false;
break;
case PA_CONTEXT_FAILED:
default:
qCritical() << QString("Pulseaudio connection failure: %1").arg(pa_strerror(pa_context_errno(m_context)));
keepGoing = false;
ok = false;
}
if (keepGoing) {
pa_threaded_mainloop_wait(m_mainLoop);
}
}
if (ok) {
pa_context_set_state_callback(m_context, contextStateCallback, this);
pa_context_set_subscribe_callback(m_context, subscribeCallback, this);
pa_context_subscribe(m_context, PA_SUBSCRIPTION_MASK_CARD, NULL, this);
} else {
if (m_context) {
pa_context_unref(m_context);
m_context = 0;
}
}
pa_threaded_mainloop_unlock(m_mainLoop);
return true;
}
void QPulseAudioEngineWorker::releasePulseContext()
{
if (m_context) {
pa_threaded_mainloop_lock(m_mainLoop);
pa_context_disconnect(m_context);
pa_context_unref(m_context);
pa_threaded_mainloop_unlock(m_mainLoop);
m_context = 0;
}
}
QPulseAudioEngineWorker::~QPulseAudioEngineWorker()
{
releasePulseContext();
if (m_mainLoop) {
pa_threaded_mainloop_stop(m_mainLoop);
pa_threaded_mainloop_free(m_mainLoop);
m_mainLoop = 0;
}
}
void QPulseAudioEngineWorker::cardInfoCallback(const pa_card_info *info)
{
pa_card_profile_info2 *voice_call = NULL, *highest = NULL;
pa_card_profile_info2 *hsp = NULL, *a2dp = NULL;
/* For now we only support one card with the voicecall feature */
for (int i = 0; i < info->n_profiles; i++) {
if (!highest || info->profiles2[i]->priority > highest->priority)
highest = info->profiles2[i];
if (!strcmp(info->profiles2[i]->name, "voicecall"))
voice_call = info->profiles2[i];
else if (!strcmp(info->profiles2[i]->name, PULSEAUDIO_PROFILE_HSP) &&
info->profiles2[i]->available != 0)
hsp = info->profiles2[i];
else if (!strcmp(info->profiles2[i]->name, PULSEAUDIO_PROFILE_A2DP) &&
info->profiles2[i]->available != 0)
a2dp = info->profiles2[i];
}
/* Record the card that supports voicecall (default one to be used) */
if (voice_call) {
qDebug("Found card that supports voicecall: '%s'", info->name);
m_voicecallcard = info->name;
m_voicecallhighest = highest->name;
m_voicecallprofile = voice_call->name;
}
/* Handle the use cases needed for bluetooth */
if (hsp && a2dp) {
qDebug("Found card that supports hsp and a2dp: '%s'", info->name);
m_bt_hsp_a2dp = info->name;
} else if (hsp && (a2dp == NULL)) {
/* This card only provides the hsp profile */
qDebug("Found card that supports only hsp: '%s'", info->name);
m_bt_hsp = info->name;
}
}
void QPulseAudioEngineWorker::sinkInfoCallback(const pa_sink_info *info)
{
pa_sink_port_info *earpiece = NULL, *speaker = NULL;
pa_sink_port_info *wired_headset = NULL, *wired_headphone = NULL;
pa_sink_port_info *preferred = NULL;
pa_sink_port_info *bluetooth_sco = NULL;
pa_sink_port_info *speaker_and_wired_headphone = NULL;
AudioMode audiomodetoset;
AudioModes modes;
for (int i = 0; i < info->n_ports; i++) {
if (!strcmp(info->ports[i]->name, "output-earpiece"))
earpiece = info->ports[i];
else if (!strcmp(info->ports[i]->name, "output-wired_headset") &&
(info->ports[i]->available != PA_PORT_AVAILABLE_NO))
wired_headset = info->ports[i];
else if (!strcmp(info->ports[i]->name, "output-wired_headphone") &&
(info->ports[i]->available != PA_PORT_AVAILABLE_NO))
wired_headphone = info->ports[i];
else if (!strcmp(info->ports[i]->name, "output-speaker"))
speaker = info->ports[i];
else if (!strcmp(info->ports[i]->name, "output-bluetooth_sco"))
bluetooth_sco = info->ports[i];
else if (!strcmp(info->ports[i]->name, "output-speaker+wired_headphone"))
speaker_and_wired_headphone = info->ports[i];
}
if (!earpiece || !speaker)
return; /* Not the right sink */
/* Refresh list of available audio modes */
modes.append(AudioModeEarpiece);
modes.append(AudioModeSpeaker);
if (wired_headset || wired_headphone)
modes.append(AudioModeWiredHeadset);
if (bluetooth_sco && ((m_bt_hsp != "") || (m_bt_hsp_a2dp != "")))
modes.append(AudioModeBluetooth);
/* Check if the requested mode is available (earpiece*/
if (((m_audiomode == AudioModeWiredHeadset) && !modes.contains(AudioModeWiredHeadset)) ||
((m_audiomode == AudioModeBluetooth) && !modes.contains(AudioModeBluetooth)))
return;
/* Now to decide which output to be used, depending on the active mode */
if (m_audiomode & AudioModeEarpiece) {
preferred = earpiece;
audiomodetoset = AudioModeEarpiece;
}
if (m_audiomode & AudioModeSpeaker) {
preferred = speaker;
audiomodetoset = AudioModeSpeaker;
}
if ((m_audiomode & AudioModeWiredHeadset) && (modes.contains(AudioModeWiredHeadset))) {
preferred = wired_headset ? wired_headset : wired_headphone;
audiomodetoset = AudioModeWiredHeadset;
}
if (m_callstatus == CallRinging && speaker_and_wired_headphone) {
preferred = speaker_and_wired_headphone;
}
if ((m_audiomode & AudioModeBluetooth) && (modes.contains(AudioModeBluetooth))) {
preferred = bluetooth_sco;
audiomodetoset = AudioModeBluetooth;
}
m_audiomode = audiomodetoset;
m_nametoset = info->name;
if (info->active_port != preferred)
m_valuetoset = preferred->name;
if (modes != m_availableAudioModes)
m_availableAudioModes = modes;
}
void QPulseAudioEngineWorker::sourceInfoCallback(const pa_source_info *info)
{
pa_source_port_info *builtin_mic = NULL, *preferred = NULL;
pa_source_port_info *wired_headset = NULL, *bluetooth_sco = NULL;
if (info->monitor_of_sink != PA_INVALID_INDEX)
return; /* Not the right source */
for (int i = 0; i < info->n_ports; i++) {
if (!strcmp(info->ports[i]->name, "input-builtin_mic"))
builtin_mic = info->ports[i];
else if (!strcmp(info->ports[i]->name, "input-wired_headset") &&
(info->ports[i]->available != PA_PORT_AVAILABLE_NO))
wired_headset = info->ports[i];
else if (!strcmp(info->ports[i]->name, "input-bluetooth_sco_headset"))
bluetooth_sco = info->ports[i];
}
if (!builtin_mic)
return; /* Not the right source */
/* Now to decide which output to be used, depending on the active mode */
if ((m_audiomode & AudioModeEarpiece) || (m_audiomode & AudioModeSpeaker))
preferred = builtin_mic;
if ((m_audiomode & AudioModeWiredHeadset) && (m_availableAudioModes.contains(AudioModeWiredHeadset)))
preferred = wired_headset ? wired_headset : builtin_mic;
if ((m_audiomode & AudioModeBluetooth) && (m_availableAudioModes.contains(AudioModeBluetooth)))
preferred = bluetooth_sco;
m_nametoset = info->name;
if (info->active_port != preferred)
m_valuetoset = preferred->name;
}
void QPulseAudioEngineWorker::serverInfoCallback(const pa_server_info *info)
{
/* Saving default sink/source to restore after call hangup */
m_defaultsink = info->default_sink_name;
m_defaultsource = info->default_source_name;
/* In the case of a server callback we need to signal the mainloop */
pa_threaded_mainloop_signal(mainloop(), 0);
}
static void cardinfo_cb(pa_context *context, const pa_card_info *info, int isLast, void *userdata)
{
QPulseAudioEngineWorker *pulseEngine = static_cast(userdata);
if (isLast != 0 || !pulseEngine || !info) {
pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
return;
}
pulseEngine->cardInfoCallback(info);
}
static void sinkinfo_cb(pa_context *context, const pa_sink_info *info, int isLast, void *userdata)
{
QPulseAudioEngineWorker *pulseEngine = static_cast(userdata);
if (isLast != 0 || !pulseEngine || !info) {
pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
return;
}
pulseEngine->sinkInfoCallback(info);
}
static void sourceinfo_cb(pa_context *context, const pa_source_info *info, int isLast, void *userdata)
{
QPulseAudioEngineWorker *pulseEngine = static_cast(userdata);
if (isLast != 0 || !pulseEngine || !info) {
pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
return;
}
pulseEngine->sourceInfoCallback(info);
}
static void serverinfo_cb(pa_context *context, const pa_server_info *info, void *userdata)
{
QPulseAudioEngineWorker *pulseEngine = static_cast(userdata);
if (!pulseEngine || !info) {
pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
return;
}
pulseEngine->serverInfoCallback(info);
}
bool QPulseAudioEngineWorker::handleOperation(pa_operation *operation, const char *func_name)
{
if (!operation) {
qCritical("'%s' failed (lost PulseAudio connection?)", func_name);
/* Free resources so it can retry a new connection during next operation */
pa_threaded_mainloop_unlock(m_mainLoop);
releasePulseContext();
return false;
}
while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING)
pa_threaded_mainloop_wait(m_mainLoop);
pa_operation_unref(operation);
return true;
}
int QPulseAudioEngineWorker::setupVoiceCall()
{
pa_operation *o;
qDebug("Setting up pulseaudio for voice call");
pa_threaded_mainloop_lock(m_mainLoop);
/* Get and set the default sink/source to be restored later */
o = pa_context_get_server_info(m_context, serverinfo_cb, this);
if (!handleOperation(o, "pa_context_get_server_info"))
return -1;
qDebug("Recorded default sink: %s default source: %s",
m_defaultsink.c_str(), m_defaultsource.c_str());
/* Walk through the list of devices, find the voice call capable card and
* identify if we have bluetooth capable devices (hsp and a2dp) */
m_voicecallcard = m_voicecallhighest = m_voicecallprofile = "";
m_bt_hsp = m_bt_hsp_a2dp = "";
o = pa_context_get_card_info_list(m_context, cardinfo_cb, this);
if (!handleOperation(o, "pa_context_get_card_info_list"))
return -1;
/* In case we have only one bt device that provides hsp and a2dp, we need
* to make sure we switch the default profile for that card (to hsp) */
if ((m_bt_hsp_a2dp != "") && (m_bt_hsp == "")) {
qDebug("Setting PulseAudio card '%s' profile '%s'",
m_bt_hsp_a2dp.c_str(), PULSEAUDIO_PROFILE_HSP);
o = pa_context_set_card_profile_by_name(m_context,
m_bt_hsp_a2dp.c_str(), PULSEAUDIO_PROFILE_HSP, success_cb, this);
if (!handleOperation(o, "pa_context_set_card_profile_by_name"))
return -1;
}
pa_threaded_mainloop_unlock(m_mainLoop);
return 0;
}
void QPulseAudioEngineWorker::restoreVoiceCall()
{
pa_operation *o;
qDebug("Restoring pulseaudio previous state");
/* Then restore previous settings */
pa_threaded_mainloop_lock(m_mainLoop);
/* See if we need to restore any HSP+AD2P device state */
if ((m_bt_hsp_a2dp != "") && (m_bt_hsp == "")) {
qDebug("Restoring PulseAudio card '%s' to profile '%s'",
m_bt_hsp_a2dp.c_str(), PULSEAUDIO_PROFILE_A2DP);
o = pa_context_set_card_profile_by_name(m_context,
m_bt_hsp_a2dp.c_str(), PULSEAUDIO_PROFILE_A2DP, success_cb, this);
if (!handleOperation(o, "pa_context_set_card_profile_by_name"))
return;
}
/* Restore default sink/source */
if (m_defaultsink != "") {
qDebug("Restoring PulseAudio default sink to '%s'", m_defaultsink.c_str());
o = pa_context_set_default_sink(m_context, m_defaultsink.c_str(), success_cb, this);
if (!handleOperation(o, "pa_context_set_default_sink"))
return;
}
if (m_defaultsource != "") {
qDebug("Restoring PulseAudio default source to '%s'", m_defaultsource.c_str());
o = pa_context_set_default_source(m_context, m_defaultsource.c_str(), success_cb, this);
if (!handleOperation(o, "pa_context_set_default_source"))
return;
}
pa_threaded_mainloop_unlock(m_mainLoop);
}
void QPulseAudioEngineWorker::setCallMode(CallStatus callstatus, AudioMode audiomode)
{
if (!createPulseContext()) {
return;
}
CallStatus p_callstatus = m_callstatus;
AudioMode p_audiomode = m_audiomode;
AudioModes p_availableAudioModes = m_availableAudioModes;
pa_operation *o;
/* Check if we need to save the current pulseaudio state (e.g. when starting a call) */
if ((callstatus != CallEnded) && (p_callstatus == CallEnded)) {
if (setupVoiceCall() < 0) {
qCritical("Failed to setup PulseAudio for Voice Call");
return;
}
}
/* If we have an active call, update internal state (used later when updating sink/source ports) */
m_callstatus = callstatus;
m_audiomode = audiomode;
pa_threaded_mainloop_lock(m_mainLoop);
/* Switch the virtual card mode when call is active and not active
* This needs to be done before sink/source gets updated, because after changing mode
* it will automatically move to input/output-parking */
if ((m_callstatus == CallActive) && (p_callstatus != CallActive) &&
(m_voicecallcard != "") && (m_voicecallprofile != "")) {
qDebug("Setting PulseAudio card '%s' profile '%s'",
m_voicecallcard.c_str(), m_voicecallprofile.c_str());
o = pa_context_set_card_profile_by_name(m_context,
m_voicecallcard.c_str(), m_voicecallprofile.c_str(), success_cb, this);
if (!handleOperation(o, "pa_context_set_card_profile_by_name"))
return;
} else if ((m_callstatus == CallEnded) && (m_voicecallcard != "") && (m_voicecallhighest != "")) {
/* If using droid, make sure to restore to the profile that has the highest score */
qDebug("Restoring PulseAudio card '%s' to profile '%s'",
m_voicecallcard.c_str(), m_voicecallhighest.c_str());
o = pa_context_set_card_profile_by_name(m_context,
m_voicecallcard.c_str(), m_voicecallhighest.c_str(), success_cb, this);
if (!handleOperation(o, "pa_context_set_card_profile_by_name"))
return;
}
/* Find highest compatible sink/source elements from the voicecall
compatible card (on touch this means the pulse droid element) */
m_nametoset = m_valuetoset = "";
o = pa_context_get_sink_info_list(m_context, sinkinfo_cb, this);
if (!handleOperation(o, "pa_context_get_sink_info_list"))
return;
if ((m_nametoset != "") && (m_nametoset != m_defaultsink)) {
qDebug("Setting PulseAudio default sink to '%s'", m_nametoset.c_str());
o = pa_context_set_default_sink(m_context, m_nametoset.c_str(), success_cb, this);
if (!handleOperation(o, "pa_context_set_default_sink"))
return;
}
if (m_valuetoset != "") {
qDebug("Setting PulseAudio sink '%s' port '%s'",
m_nametoset.c_str(), m_valuetoset.c_str());
o = pa_context_set_sink_port_by_name(m_context, m_nametoset.c_str(),
m_valuetoset.c_str(), success_cb, this);
if (!handleOperation(o, "pa_context_set_sink_port_by_name"))
return;
}
/* Same for source */
m_nametoset = m_valuetoset = "";
o = pa_context_get_source_info_list(m_context, sourceinfo_cb, this);
if (!handleOperation(o, "pa_context_get_source_info_list"))
return;
if ((m_nametoset != "") && (m_nametoset != m_defaultsource)) {
qDebug("Setting PulseAudio default source to '%s'", m_nametoset.c_str());
o = pa_context_set_default_source(m_context, m_nametoset.c_str(), success_cb, this);
if (!handleOperation(o, "pa_context_set_default_source"))
return;
}
if (m_valuetoset != "") {
qDebug("Setting PulseAudio source '%s' port '%s'",
m_nametoset.c_str(), m_valuetoset.c_str());
o = pa_context_set_source_port_by_name(m_context, m_nametoset.c_str(),
m_valuetoset.c_str(), success_cb, this);
if (!handleOperation(o, "pa_context_set_source_port_by_name"))
return;
}
pa_threaded_mainloop_unlock(m_mainLoop);
/* Notify if the list of audio modes changed */
if (p_availableAudioModes != m_availableAudioModes)
Q_EMIT availableAudioModesChanged(m_availableAudioModes);
/* Notify if call mode changed */
if (p_audiomode != m_audiomode) {
Q_EMIT audioModeChanged(m_audiomode);
}
/* If no more active voicecall, restore previous saved pulseaudio state */
if (callstatus == CallEnded) {
restoreVoiceCall();
}
/* In case the app had set mute when the call wasn't active, make sure we reflect it here */
if (m_callstatus != CallEnded)
setMicMute(m_micmute);
}
void QPulseAudioEngineWorker::setMicMute(bool muted)
{
if (!createPulseContext()) {
return;
}
m_micmute = muted;
if (m_callstatus == CallEnded)
return;
pa_threaded_mainloop_lock(m_mainLoop);
m_nametoset = "";
pa_operation *o = pa_context_get_source_info_list(m_context, sourceinfo_cb, this);
if (!handleOperation(o, "pa_context_get_source_info_list"))
return;
if (m_nametoset != "") {
int m = m_micmute ? 1 : 0;
qDebug("Setting PulseAudio source '%s' muted '%d'", m_nametoset.c_str(), m);
o = pa_context_set_source_mute_by_name(m_context,
m_nametoset.c_str(), m, success_cb, this);
if (!handleOperation(o, "pa_context_set_source_mute_by_name"))
return;
}
pa_threaded_mainloop_unlock(m_mainLoop);
}
void QPulseAudioEngineWorker::plugCardCallback(const pa_card_info *info)
{
qDebug("Notified about card (%s) add event from PulseAudio", info->name);
/* We only care about BT (HSP) devices, and if one is not already available */
if ((m_callstatus != CallEnded) && ((m_bt_hsp == "") || (m_bt_hsp_a2dp == ""))) {
/* Check if it's indeed a BT device (with at least one hsp profile) */
pa_card_profile_info *hsp = NULL;
for (int i = 0; i < info->n_profiles; i++) {
if (!strcmp(info->profiles[i].name, PULSEAUDIO_PROFILE_HSP))
hsp = &info->profiles[i];
}
if (hsp)
m_handleevent = true;
}
}
void QPulseAudioEngineWorker::updateCardCallback(const pa_card_info *info)
{
qDebug("Notified about card (%s) changes event from PulseAudio", info->name);
/* We only care if the card event for the voicecall capable card */
if ((m_callstatus == CallActive) && (!strcmp(info->name, m_voicecallcard.c_str()))) {
if (m_audiomode == AudioModeWiredHeadset) {
/* If previous mode is wired, it means it got unplugged */
m_handleevent = true;
m_audiomodetoset = AudioModeBtOrWiredOrEarpiece;
} else if ((m_audiomode == AudioModeEarpiece) || ((m_audiomode == AudioModeSpeaker))) {
/* Now only trigger the event in case wired headset/headphone is now available */
pa_card_port_info *port_info = NULL;
for (int i = 0; i < info->n_ports; i++) {
if (info->ports[i] && (info->ports[i]->available == PA_PORT_AVAILABLE_YES) && (
!strcmp(info->ports[i]->name, "output-wired_headset") ||
!strcmp(info->ports[i]->name, "output-wired_headphone"))) {
m_handleevent = true;
m_audiomodetoset = AudioModeWiredOrEarpiece;
}
}
} else if (m_audiomode == AudioModeBluetooth) {
/* Handle the event so we can update the audiomodes */
m_handleevent = true;
m_audiomodetoset = AudioModeBluetooth;
}
}
}
void QPulseAudioEngineWorker::unplugCardCallback()
{
if (m_callstatus != CallEnded) {
m_handleevent = true;
}
}
void QPulseAudioEngineWorker::handleCardEvent(const int evt, const unsigned int idx)
{
pa_operation *o = NULL;
/* Internal state var used to know if we need to update our internal state */
m_handleevent = false;
if (evt == PA_SUBSCRIPTION_EVENT_NEW) {
o = pa_context_get_card_info_by_index(m_context, idx, plug_card_cb, this);
if (!handleOperation(o, "pa_context_get_card_info_by_index"))
return;
if (m_handleevent) {
qDebug("Adding new BT-HSP capable device");
/* In case A2DP is available, switch to HSP */
if (setupVoiceCall() < 0)
return;
/* Enable the HSP output port */
setCallMode(m_callstatus, AudioModeBluetooth);
}
} else if (evt == PA_SUBSCRIPTION_EVENT_CHANGE) {
o = pa_context_get_card_info_by_index(m_context, idx, update_card_cb, this);
if (!handleOperation(o, "pa_context_get_card_info_by_index"))
return;
if (m_handleevent) {
/* In this case it means the handset state changed */
qDebug("Notifying card changes for the voicecall capable card");
setCallMode(m_callstatus, m_audiomodetoset);
}
} else if (evt == PA_SUBSCRIPTION_EVENT_REMOVE) {
/* Check if the main HSP card was removed */
if (m_bt_hsp != "") {
o = pa_context_get_card_info_by_name(m_context, m_bt_hsp.c_str(), unplug_card_cb, this);
if (!handleOperation(o, "pa_context_get_sink_info_by_name"))
return;
}
if (m_bt_hsp_a2dp != "") {
o = pa_context_get_card_info_by_name(m_context, m_bt_hsp_a2dp.c_str(), unplug_card_cb, this);
if (!handleOperation(o, "pa_context_get_sink_info_by_name"))
return;
}
if (m_handleevent) {
qDebug("Notifying about BT-HSP card removal");
/* Needed in order to save the default sink/source */
if (setupVoiceCall() < 0)
return;
/* Enable the default handset output port */
setCallMode(m_callstatus, AudioModeWiredOrEarpiece);
}
}
}
Q_GLOBAL_STATIC(QPulseAudioEngine, pulseEngine);
QPulseAudioEngine::QPulseAudioEngine(QObject *parent) :
QObject(parent)
{
qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaType();
mWorker = new QPulseAudioEngineWorker();
QObject::connect(mWorker, SIGNAL(audioModeChanged(const AudioMode)), this, SIGNAL(audioModeChanged(const AudioMode)), Qt::QueuedConnection);
QObject::connect(mWorker, SIGNAL(availableAudioModesChanged(const AudioModes)), this, SIGNAL(availableAudioModesChanged(const AudioModes)), Qt::QueuedConnection);
mWorker->createPulseContext();
mWorker->moveToThread(&mThread);
mThread.start();
}
QPulseAudioEngine::~QPulseAudioEngine()
{
mThread.quit();
mThread.wait();
}
QPulseAudioEngine *QPulseAudioEngine::instance()
{
QPulseAudioEngine *engine = pulseEngine();
return engine;
}
void QPulseAudioEngine::setCallMode(CallStatus callstatus, AudioMode audiomode)
{
QMetaObject::invokeMethod(mWorker, "setCallMode", Qt::QueuedConnection, Q_ARG(CallStatus, callstatus), Q_ARG(AudioMode, audiomode));
}
void QPulseAudioEngine::setMicMute(bool muted)
{
QMetaObject::invokeMethod(mWorker, "setMicMute", Qt::QueuedConnection, Q_ARG(bool, muted));
}
QT_END_NAMESPACE
telepathy-ofono-0.2+16.04.20151120/ofonotextchannel.h 0000644 0000153 0000161 00000005661 12623675611 022565 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#ifndef OFONOTEXTCHANNEL_H
#define OFONOTEXTCHANNEL_H
#include
#include
#include
#include
#include
#include "connection.h"
class oFonoConnection;
class oFonoTextChannel : public QObject
{
Q_OBJECT
public:
oFonoTextChannel(oFonoConnection *conn, QStringList phoneNumbers, bool flash = false, QObject *parent = 0);
QString sendMessage(Tp::MessagePartList message, uint flags, Tp::DBusError* error);
void messageReceived(const QString & message, uint handle, const QVariantMap &info);
Tp::BaseChannelPtr baseChannel();
void messageAcknowledged(const QString &id);
void mmsReceived(const QString &id, uint handle, const QVariantMap &properties);
void deliveryReportReceived(const QString& messageId, uint handle, bool success);
void sendDeliveryReport(const QString &messageId, uint handle, Tp::DeliveryStatus status);
void addMembers(QStringList phoneNumbers);
Tp::UIntList members();
void onAddMembers(const Tp::UIntList& handles, const QString& message, Tp::DBusError* error);
void onRemoveMembers(const Tp::UIntList& handles, const QString& message, Tp::DBusError* error);
private Q_SLOTS:
void onMMSPropertyChanged(QString property, QVariant value);
void onOfonoMessageStateChanged(QString status);
void onProcessPendingDeliveryReport();
Q_SIGNALS:
void messageRead(const QString &id);
private:
~oFonoTextChannel();
Tp::BaseChannelPtr mBaseChannel;
QStringList mPhoneNumbers;
oFonoConnection *mConnection;
Tp::BaseChannelMessagesInterfacePtr mMessagesIface;
Tp::BaseChannelGroupInterfacePtr mGroupIface;
Tp::BaseChannelSMSInterfacePtr mSMSIface;
Tp::BaseChannelTextTypePtr mTextChannel;
uint mMessageCounter;
QMap mPendingDeliveryReportTemporarilyFailed;
QMap mPendingDeliveryReportPermanentlyFailed;
QMap mPendingDeliveryReportAccepted;
QMap mPendingDeliveryReportDelivered;
QMap mPendingDeliveryReportUnknown;
Tp::UIntList mMembers;
QMap mFilesToRemove;
bool mFlash;
};
#endif // OFONOTEXTCHANNEL_H
telepathy-ofono-0.2+16.04.20151120/audiooutputsiface.cpp 0000644 0000153 0000161 00000012574 12623675611 023300 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#include
#include
#include
#include "audiooutputsiface.h"
QDBusArgument &operator<<(QDBusArgument &argument, const AudioOutput &output)
{
argument.beginStructure();
argument << output.id << output.type << output.name;
argument.endStructure();
return argument;
}
const QDBusArgument &operator>>(const QDBusArgument &argument, AudioOutput &output)
{
argument.beginStructure();
argument >> output.id >> output.type >> output.name;
argument.endStructure();
return argument;
}
// Chan.I.AudioOutputs
BaseChannelAudioOutputsInterface::Adaptee::Adaptee(BaseChannelAudioOutputsInterface *interface)
: QObject(interface),
mInterface(interface)
{
qDBusRegisterMetaType();
qDBusRegisterMetaType();
}
struct TP_QT_NO_EXPORT BaseChannelAudioOutputsInterface::Private {
Private(BaseChannelAudioOutputsInterface *parent)
: adaptee(new BaseChannelAudioOutputsInterface::Adaptee(parent)) {
}
AudioOutputList audioOutputs;
QString activeAudioOutput;
SetActiveAudioOutputCallback setActiveAudioOutputCB;
BaseChannelAudioOutputsInterface::Adaptee *adaptee;
};
BaseChannelAudioOutputsInterface::Adaptee::~Adaptee()
{
}
void BaseChannelAudioOutputsInterface::Adaptee::setActiveAudioOutput(const QString &id, const ChannelInterfaceAudioOutputsAdaptor::SetActiveAudioOutputContextPtr &context)
{
if (!mInterface->mPriv->setActiveAudioOutputCB.isValid()) {
context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
return;
}
Tp::DBusError error;
mInterface->mPriv->setActiveAudioOutputCB(id, &error);
if (error.isValid()) {
context->setFinishedWithError(error.name(), error.message());
return;
}
context->setFinished();
}
BaseChannelAudioOutputsInterface::BaseChannelAudioOutputsInterface()
: AbstractChannelInterface(TP_QT_IFACE_CHANNEL_AUDIOOUTPUTS),
mPriv(new Private(this))
{
}
BaseChannelAudioOutputsInterface::~BaseChannelAudioOutputsInterface()
{
delete mPriv;
}
QString BaseChannelAudioOutputsInterface::activeAudioOutput() const
{
return mPriv->activeAudioOutput;
}
AudioOutputList BaseChannelAudioOutputsInterface::audioOutputs() const
{
return mPriv->audioOutputs;
}
void BaseChannelAudioOutputsInterface::setSetActiveAudioOutputCallback(const SetActiveAudioOutputCallback &cb)
{
mPriv->setActiveAudioOutputCB = cb;
}
void BaseChannelAudioOutputsInterface::setActiveAudioOutput(const QString &id)
{
mPriv->activeAudioOutput = id;
Q_EMIT mPriv->adaptee->activeAudioOutputChanged(id);
}
void BaseChannelAudioOutputsInterface::setAudioOutputs(const AudioOutputList &outputs)
{
mPriv->audioOutputs = outputs;
Q_EMIT mPriv->adaptee->audioOutputsChanged(outputs);
}
QVariantMap BaseChannelAudioOutputsInterface::immutableProperties() const
{
QVariantMap map;
return map;
}
void BaseChannelAudioOutputsInterface::createAdaptor()
{
(void) new ChannelInterfaceAudioOutputsAdaptor(dbusObject()->dbusConnection(),
mPriv->adaptee, dbusObject());
}
ChannelInterfaceAudioOutputsAdaptor::ChannelInterfaceAudioOutputsAdaptor(const QDBusConnection& bus, QObject* adaptee, QObject* parent)
: Tp::AbstractAdaptor(bus, adaptee, parent)
{
connect(adaptee, SIGNAL(audioOutputsChanged(AudioOutputList)), SIGNAL(AudioOutputsChanged(AudioOutputList)));
connect(adaptee, SIGNAL(activeAudioOutputChanged(QString)), SIGNAL(ActiveAudioOutputChanged(QString)));
}
ChannelInterfaceAudioOutputsAdaptor::~ChannelInterfaceAudioOutputsAdaptor()
{
}
void ChannelInterfaceAudioOutputsAdaptor::SetActiveAudioOutput(const QString &id, const QDBusMessage& dbusMessage)
{
if (!adaptee()->metaObject()->indexOfMethod("setActiveAudioOutput(QString,ChannelInterfaceAudioOutputsAdaptor::SetActiveAudioOutputContextPtr)") == -1) {
dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")));
return;
}
SetActiveAudioOutputContextPtr ctx = SetActiveAudioOutputContextPtr(
new Tp::MethodInvocationContext< >(dbusConnection(), dbusMessage));
QMetaObject::invokeMethod(adaptee(), "setActiveAudioOutput",
Q_ARG(QString, id),
Q_ARG(ChannelInterfaceAudioOutputsAdaptor::SetActiveAudioOutputContextPtr, ctx));
return;
}
QString ChannelInterfaceAudioOutputsAdaptor::ActiveAudioOutput() const
{
return qvariant_cast< QString >(adaptee()->property("activeAudioOutput"));
}
AudioOutputList ChannelInterfaceAudioOutputsAdaptor::AudioOutputs() const
{
return qvariant_cast< AudioOutputList >(adaptee()->property("audioOutputs"));
}
telepathy-ofono-0.2+16.04.20151120/schema/ 0000755 0000153 0000161 00000000000 12623676450 020270 5 ustar pbuser pbgroup 0000000 0000000 telepathy-ofono-0.2+16.04.20151120/schema/CMakeLists.txt 0000644 0000153 0000161 00000000777 12623675611 023041 0 ustar pbuser pbgroup 0000000 0000000 file(GLOB SCHEMA_FILES ${CMAKE_CURRENT_SOURCE_DIR}/v*.sql)
set(SCHEMA_FILE ${CMAKE_CURRENT_SOURCE_DIR}/schema.sql)
set(VERSION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/version.info)
add_custom_command(
OUTPUT ${SCHEMA_FILE} ${VERSION_FILE}
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/update_schema.sh ${CMAKE_CURRENT_SOURCE_DIR} ${SCHEMA_FILE} ${VERSION_FILE}
WORKING DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${SCHEMA_FILES}
)
add_custom_target(schema_update DEPENDS ${SCHEMA_FILE} ${VERSION_FILE})
telepathy-ofono-0.2+16.04.20151120/schema/update_schema.sh 0000755 0000153 0000161 00000001002 12623675611 023420 0 ustar pbuser pbgroup 0000000 0000000 #!/bin/sh
if [ $# -lt 3 ]; then
echo "Usage: $0 "
fi
SOURCE_DIR=$1
TARGET_FILE=$2
VERSION_FILE=$3
VERSION="1"
LATEST_VERSION="1"
TMPFILE=`tempfile`
SCHEMA_FILE="$SOURCE_DIR/v${VERSION}.sql"
while [ -e $SCHEMA_FILE ]; do
cat $SCHEMA_FILE >> $TMPFILE
LATEST_VERSION=$VERSION
VERSION=$(($VERSION+1))
SCHEMA_FILE="$SOURCE_DIR/v${VERSION}.sql"
done
sqlite3 -init $TMPFILE :memory: .schema > $TARGET_FILE
echo $LATEST_VERSION > $VERSION_FILE
telepathy-ofono-0.2+16.04.20151120/schema/v1.sql 0000644 0000153 0000161 00000000246 12623675611 021337 0 ustar pbuser pbgroup 0000000 0000000 CREATE TABLE schema_version (
version int
);
CREATE TABLE pending_messages (
messageId varchar(255),
recipientId varchar(255),
timestamp datetime
);
telepathy-ofono-0.2+16.04.20151120/sqlitedatabase.cpp 0000644 0000153 0000161 00000015513 12623675611 022525 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Gustavo Pichorim Boiko
*/
#include "phoneutils_p.h"
#include "sqlite3.h"
#include "sqlitedatabase.h"
#include
#include
#include
#include
#include
#include
#include
Q_DECLARE_OPAQUE_POINTER(sqlite3*)
Q_DECLARE_METATYPE(sqlite3*)
// custom sqlite function "comparePhoneNumbers" used to compare IDs if necessary
void comparePhoneNumbers(sqlite3_context *context, int argc, sqlite3_value **argv)
{
QString arg1((const char*)sqlite3_value_text(argv[0]));
QString arg2((const char*)sqlite3_value_text(argv[1]));
sqlite3_result_int(context, (int)PhoneUtils::comparePhoneNumbers(arg1, arg2));
}
SQLiteDatabase::SQLiteDatabase(QObject *parent) :
QObject(parent), mSchemaVersion(0)
{
initializeDatabase();
}
SQLiteDatabase *SQLiteDatabase::instance()
{
static SQLiteDatabase *self = new SQLiteDatabase();
return self;
}
bool SQLiteDatabase::initializeDatabase()
{
mDatabasePath = qgetenv("TP_OFONO_SQLITE_DBPATH");
if (mDatabasePath.isEmpty()) {
mDatabasePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
QDir dir(mDatabasePath);
if (!dir.exists("telepathy-ofono") && !dir.mkpath("telepathy-ofono")) {
qCritical() << "Failed to create dir";
return false;
}
dir.cd("telepathy-ofono");
mDatabasePath = dir.absoluteFilePath("telepathy-ofono.sqlite");
}
mDatabase = QSqlDatabase::addDatabase("QSQLITE");
mDatabase.setDatabaseName(mDatabasePath);
// always run the createDatabase function at least during the development
if (!createOrUpdateDatabase()) {
qCritical() << "Failed to create or update the database";
return false;
}
return true;
}
QSqlDatabase SQLiteDatabase::database() const
{
return mDatabase;
}
bool SQLiteDatabase::beginTransation()
{
return mDatabase.transaction();
}
bool SQLiteDatabase::finishTransaction()
{
return mDatabase.commit();
}
bool SQLiteDatabase::rollbackTransaction()
{
return mDatabase.rollback();
}
/// this method is to be used mainly by unit tests in order to clean up the database between
/// tests.
bool SQLiteDatabase::reopen()
{
mDatabase.close();
mDatabase.open();
// make sure the database is up-to-date after reopening.
// this is mainly required for the memory backend used for testing
createOrUpdateDatabase();
}
bool SQLiteDatabase::createOrUpdateDatabase()
{
bool create = !QFile(mDatabasePath).exists();
if (!mDatabase.open()) {
return false;
}
// create the comparePhoneNumbers custom sqlite function
sqlite3 *handle = database().driver()->handle().value();
sqlite3_create_function(handle, "comparePhoneNumbers", 2, SQLITE_ANY, NULL, &comparePhoneNumbers, NULL, NULL);
parseVersionInfo();
QSqlQuery query(mDatabase);
QStringList statements;
if (create) {
statements = parseSchemaFile(":/database/schema/schema.sql");
} else {
// if the database already exists, we don´t need to create the tables
// only check if an update is needed
query.exec("SELECT * FROM schema_version");
if (!query.exec() || !query.next()) {
return false;
}
int upgradeToVersion = query.value(0).toInt() + 1;
while (upgradeToVersion <= mSchemaVersion) {
statements += parseSchemaFile(QString(":/database/schema/v%1.sql").arg(QString::number(upgradeToVersion)));
++upgradeToVersion;
}
}
// if at this point needsUpdate is still false, it means the database is up-to-date
if (statements.isEmpty()) {
return true;
}
beginTransation();
Q_FOREACH(const QString &statement, statements) {
if (!query.exec(statement)) {
qCritical() << "Failed to create or update database. SQL Statements:" << query.lastQuery() << "Error:" << query.lastError();
rollbackTransaction();
return false;
}
}
// now set the new database schema version
if (!query.exec("DELETE FROM schema_version")) {
qCritical() << "Failed to remove previous schema versions. SQL Statement:" << query.lastQuery() << "Error:" << query.lastError();
rollbackTransaction();
return false;
}
if (!query.exec(QString("INSERT INTO schema_version VALUES (%1)").arg(mSchemaVersion))) {
qCritical() << "Failed to insert new schema version. SQL Statement:" << query.lastQuery() << "Error:" << query.lastError();
rollbackTransaction();
return false;
}
finishTransaction();
return true;
}
QStringList SQLiteDatabase::parseSchemaFile(const QString &fileName)
{
QFile schema(fileName);
if (!schema.open(QFile::ReadOnly)) {
qCritical() << "Failed to open " << fileName;
return QStringList();
}
bool parsingBlock = false;
QString statement;
QStringList statements;
// FIXME: this parser is very basic, it needs to be improved in the future
// it does a lot of assumptions based on the structure of the schema.sql file
QTextStream stream(&schema);
while (!stream.atEnd()) {
QString line = stream.readLine();
bool statementEnded = false;
statement += line;
// check if we are parsing a trigger command
if (line.trimmed().startsWith("CREATE TRIGGER", Qt::CaseInsensitive)) {
parsingBlock = true;
} else if (parsingBlock) {
if (line.contains("END;")) {
parsingBlock = false;
statementEnded = true;
}
} else if (statement.contains(";")) {
statementEnded = true;
}
statement += "\n";
if (statementEnded) {
statements.append(statement);
statement.clear();
}
}
return statements;
}
void SQLiteDatabase::parseVersionInfo()
{
QFile schema(":/database/schema/version.info");
if (!schema.open(QFile::ReadOnly)) {
qDebug() << schema.error();
qCritical() << "Failed to get database version";
}
QString version = schema.readAll();
mSchemaVersion = version.toInt();
}
telepathy-ofono-0.2+16.04.20151120/qpulseaudioengine.h 0000644 0000153 0000161 00000007504 12623675611 022726 0 ustar pbuser pbgroup 0000000 0000000 /****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file was taken from qt5 and modified by
** David Henningsson for usage in
** telepathy-ofono.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
****************************************************************************/
#ifndef QPULSEAUDIOENGINE_H
#define QPULSEAUDIOENGINE_H
#include
#include
#include
#include
enum AudioMode {
AudioModeEarpiece = 0x0001,
AudioModeWiredHeadset = 0x0002,
AudioModeSpeaker = 0x0004,
AudioModeBluetooth = 0x0008,
AudioModeBtOrWiredOrEarpiece = AudioModeBluetooth | AudioModeWiredHeadset | AudioModeEarpiece,
AudioModeWiredOrEarpiece = AudioModeWiredHeadset | AudioModeEarpiece,
AudioModeWiredOrSpeaker = AudioModeWiredHeadset | AudioModeSpeaker
};
Q_DECLARE_METATYPE(AudioMode)
typedef QList AudioModes;
Q_DECLARE_METATYPE(AudioModes)
enum CallStatus {
CallRinging,
CallActive,
CallEnded
};
Q_DECLARE_METATYPE(CallStatus)
QT_BEGIN_NAMESPACE
class QPulseAudioEngineWorker : public QObject
{
Q_OBJECT
public:
QPulseAudioEngineWorker(QObject *parent = 0);
~QPulseAudioEngineWorker();
pa_threaded_mainloop *mainloop() { return m_mainLoop; }
pa_context *context() { return m_context; }
bool createPulseContext(void);
int setupVoiceCall(void);
void restoreVoiceCall(void);
/* Callbacks to be used internally */
void cardInfoCallback(const pa_card_info *card);
void sinkInfoCallback(const pa_sink_info *sink);
void sourceInfoCallback(const pa_source_info *source);
void serverInfoCallback(const pa_server_info *server);
void plugCardCallback(const pa_card_info *card);
void updateCardCallback(const pa_card_info *card);
void unplugCardCallback();
Q_SIGNALS:
void audioModeChanged(const AudioMode mode);
void availableAudioModesChanged(const AudioModes modes);
public Q_SLOTS:
void handleCardEvent(const int evt, const unsigned int idx);
void setCallMode(CallStatus callstatus, AudioMode audiomode);
void setMicMute(bool muted); /* True if muted, false if unmuted */
private:
pa_mainloop_api *m_mainLoopApi;
pa_threaded_mainloop *m_mainLoop;
pa_context *m_context;
AudioModes m_availableAudioModes;
CallStatus m_callstatus;
AudioMode m_audiomode;
AudioMode m_audiomodetoset;
bool m_micmute, m_handleevent;
std::string m_nametoset, m_valuetoset;
std::string m_defaultsink, m_defaultsource;
std::string m_bt_hsp, m_bt_hsp_a2dp;
std::string m_voicecallcard, m_voicecallhighest, m_voicecallprofile;
bool handleOperation(pa_operation *operation, const char *func_name);
void releasePulseContext(void);
};
class QPulseAudioEngine : public QObject
{
Q_OBJECT
public:
explicit QPulseAudioEngine(QObject *parent = 0);
~QPulseAudioEngine();
static QPulseAudioEngine *instance();
void setCallMode(CallStatus callstatus, AudioMode audiomode);
void setMicMute(bool muted); /* True if muted, false if unmuted */
Q_SIGNALS:
void audioModeChanged(const AudioMode mode);
void availableAudioModesChanged(const AudioModes modes);
private:
QPulseAudioEngineWorker *mWorker;
QThread mThread;
};
QT_END_NAMESPACE
#endif
telepathy-ofono-0.2+16.04.20151120/mc-plugin/ 0000755 0000153 0000161 00000000000 12623676450 020723 5 ustar pbuser pbgroup 0000000 0000000 telepathy-ofono-0.2+16.04.20151120/mc-plugin/mcp-account-manager-ofono.h 0000644 0000153 0000161 00000002671 12623675611 026037 0 ustar pbuser pbgroup 0000000 0000000 #ifndef __MCP_ACCOUNT_MANAGER_OFONO_H__
#define __MCP_ACCOUNT_MANAGER_OFONO_H__
#include
G_BEGIN_DECLS
#define MCP_TYPE_ACCOUNT_MANAGER_OFONO \
(mcp_account_manager_ofono_get_type ())
#define MCP_ACCOUNT_MANAGER_OFONO(o) \
(G_TYPE_CHECK_INSTANCE_CAST ((o), MCP_TYPE_ACCOUNT_MANAGER_OFONO, \
McpAccountManagerOfono))
#define MCP_ACCOUNT_MANAGER_OFONO_CLASS(k) \
(G_TYPE_CHECK_CLASS_CAST((k), MCP_TYPE_ACCOUNT_MANAGER_OFONO, \
McpAccountManagerOfonoClass))
#define MCP_IS_ACCOUNT_MANAGER_OFONO(o) \
(G_TYPE_CHECK_INSTANCE_TYPE ((o), MCP_TYPE_ACCOUNT_MANAGER_OFONO))
#define MCP_IS_ACCOUNT_MANAGER_OFONO_CLASS(k) \
(G_TYPE_CHECK_CLASS_TYPE ((k), MCP_TYPE_ACCOUNT_MANAGER_OFONO))
#define MCP_ACCOUNT_MANAGER_OFONO_GET_CLASS(o) \
(G_TYPE_INSTANCE_GET_CLASS ((o), MCP_TYPE_ACCOUNT_MANAGER_OFONO, \
McpAccountManagerOfonoClass))
typedef struct _McpAccountManagerOfonoPrivate McpAccountManagerOfonoPrivate;
typedef struct {
GObject parent;
McpAccountManagerOfonoPrivate *priv;
} _McpAccountManagerOfono;
typedef struct {
GObjectClass parent_class;
} _McpAccountManagerOfonoClass;
typedef _McpAccountManagerOfono McpAccountManagerOfono;
typedef _McpAccountManagerOfonoClass McpAccountManagerOfonoClass;
GType mcp_account_manager_ofono_get_type (void) G_GNUC_CONST;
McpAccountManagerOfono *mcp_account_manager_ofono_new (void);
G_END_DECLS
#endif
telepathy-ofono-0.2+16.04.20151120/mc-plugin/CMakeLists.txt 0000644 0000153 0000161 00000001322 12623675611 023457 0 ustar pbuser pbgroup 0000000 0000000 set(MCP_ACCOUNT_MANAGER_NAME mcp-account-manager-ofono)
set(MC_PLUGIN_SRC
mcp-account-manager-ofono.c
mission-control-plugin.c
)
set(MC_PLUGIN_HDRS
mcp-account-manager-ofono.h
)
execute_process(COMMAND pkg-config --variable=plugindir mission-control-plugins
OUTPUT_VARIABLE MC_PLUGINS_DIR)
string(REPLACE "\n" "" MC_PLUGINS_DIR ${MC_PLUGINS_DIR})
include_directories(${MC_PLUGINS_INCLUDE_DIRS})
add_library(${MCP_ACCOUNT_MANAGER_NAME} SHARED ${MC_PLUGIN_SRC} ${MC_PLUGIN_HDRS})
set_target_properties(${MCP_ACCOUNT_MANAGER_NAME} PROPERTIES PREFIX "")
target_link_libraries(${MCP_ACCOUNT_MANAGER_NAME} ${MC_PLUGINS_LIBRARIES})
install(TARGETS ${MCP_ACCOUNT_MANAGER_NAME} DESTINATION ${MC_PLUGINS_DIR})
telepathy-ofono-0.2+16.04.20151120/mc-plugin/mission-control-plugin.c 0000644 0000153 0000161 00000002303 12623675611 025516 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright (C) 2012 Jolla Ltd.
* Contact: John Brooks
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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, see .
*/
#include
#include "mcp-account-manager-ofono.h"
GObject *
mcp_plugin_ref_nth_object (guint n)
{
static void *plugin_0 = NULL;
switch (n) {
case 0:
if (plugin_0 == NULL) {
plugin_0 = g_object_new (MCP_TYPE_ACCOUNT_MANAGER_OFONO, NULL);
} else {
g_object_ref (plugin_0);
}
return plugin_0;
default:
return NULL;
}
}
telepathy-ofono-0.2+16.04.20151120/mc-plugin/mcp-account-manager-ofono.c 0000644 0000153 0000161 00000030360 12623675611 026026 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright (C) 2015 Canonical, Ltd.
* Contact: Tiago Salem Herrmann
*
* Based on Empathy ubuntu-online-accounts, mcp-account-manager-ring:
* Contact: John Brooks
* Copyright (C) 2012 Jolla Ltd.
* Copyright (C) 2012 Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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, see .
*/
#include
#include
#include
#include
#include
#include "mcp-account-manager-ofono.h"
#define PLUGIN_NAME "ofono-account"
#define PLUGIN_PRIORITY (MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_DEFAULT - 10)
#define PLUGIN_DESCRIPTION "Provide ril modem accounts for telepathy-ofono"
#define PLUGIN_PROVIDER "im.telepathy.Account.Storage.Ofono"
static void account_storage_iface_init(McpAccountStorageIface *iface);
G_DEFINE_TYPE_WITH_CODE (McpAccountManagerOfono, mcp_account_manager_ofono,
G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (MCP_TYPE_ACCOUNT_STORAGE,
account_storage_iface_init));
struct ofono_account {
gchar *account_name;
int index;
GHashTable *params;
};
typedef struct ofono_account OfonoAccount;
struct _McpAccountManagerOfonoPrivate
{
GList *accounts;
};
void free_ofono_struct (gpointer data)
{
OfonoAccount *account = (OfonoAccount*)data;
g_hash_table_unref(account->params);
g_free(account->account_name);
}
static void mcp_account_manager_ofono_dispose(GObject *object)
{
McpAccountManagerOfono *self = (McpAccountManagerOfono*) object;
g_list_free_full(self->priv->accounts, free_ofono_struct);
G_OBJECT_CLASS (mcp_account_manager_ofono_parent_class)->dispose(object);
}
static void mcp_account_manager_ofono_init(McpAccountManagerOfono *self)
{
g_debug("MC ril ofono accounts plugin initialized");
gchar *output = NULL;
gchar *output2 = NULL;
const gchar *force_num_modems = g_getenv("FORCE_RIL_NUM_MODEMS");
GError *error = NULL;
int num_modems = 0;
int index;
setlocale(LC_ALL, "");
self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, MCP_TYPE_ACCOUNT_MANAGER_OFONO,
McpAccountManagerOfonoPrivate);
if (force_num_modems) {
num_modems = atoi(force_num_modems);
g_debug("forced number of modems: %d", num_modems);
} else {
if (!g_file_test ("/usr/bin/getprop", G_FILE_TEST_IS_EXECUTABLE)) {
return;
}
if (!g_spawn_command_line_sync("/usr/bin/getprop rild.libpath ''",
&output, NULL, NULL,
&error)) {
g_debug("%s", error->message);
g_error_free (error);
return;
}
if (strlen(g_strstrip(output)) != 0) {
g_spawn_command_line_sync("/usr/bin/getprop ril.num_slots 1",
&output2,
NULL,
NULL,
&error);
num_modems = atoi(output2);
}
}
GSettings *settings = NULL;
GSettingsSchemaSource *source = g_settings_schema_source_get_default();
if (source != NULL && g_settings_schema_source_lookup(source, "com.ubuntu.phone", TRUE) != NULL) {
settings = g_settings_new("com.ubuntu.phone");
}
for (index = 0; index < num_modems; index++) {
OfonoAccount *account = (OfonoAccount*)malloc(sizeof(OfonoAccount));
char account_name[30] = {0};
char ril_modem[10] = {0};
account->index = index;
sprintf(account_name, "ofono/ofono/account%d", index);
sprintf(ril_modem, "/ril_%d", index);
account->params = g_hash_table_new(g_str_hash, g_str_equal);
account->account_name = g_strdup(account_name);
g_hash_table_insert(account->params, g_strdup("manager"), g_strdup("ofono"));
g_hash_table_insert(account->params, g_strdup("protocol"), g_strdup("ofono"));
g_hash_table_insert(account->params, g_strdup("Enabled"), g_strdup("true"));
g_hash_table_insert(account->params, g_strdup("ConnectAutomatically"), g_strdup("true"));
g_hash_table_insert(account->params, g_strdup("always_dispatch"), g_strdup("true"));
g_hash_table_insert(account->params, g_strdup("param-modem-objpath"), g_strdup(ril_modem));
if (settings) {
GVariant *sim_names = g_settings_get_value(settings, "sim-names");
if (sim_names) {
GVariantIter iter;
GVariant *value;
GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("a(ss)"));
gchar *key;
int found = 0;
g_variant_iter_init (&iter, sim_names);
while (g_variant_iter_next (&iter, "{ss}", &key, &value)) {
g_variant_builder_add(builder, "(ss)", key, value);
if (!strcmp(key, ril_modem)) {
g_hash_table_insert(account->params, g_strdup("DisplayName"), g_strdup((char *)value));
found = 1;
}
g_free (key);
g_free (value);
}
if (!found) {
char *sim_name = dgettext("telephony-service", "SIM %1");
char *final_sim_name = NULL;
char sim_index[10] = {0};
const char *placeholder = "%1";
sprintf(sim_index, "%d", index+1);
const char *pos = strstr(sim_name, placeholder);
if (pos) {
// this is used to replace %1 by the actual index
// FIXME: change telephony-service's string to %d to make everything easier
final_sim_name = calloc(1, strlen(sim_name) - strlen(placeholder) + strlen(sim_index) + 1);
strncpy(final_sim_name, sim_name, pos - sim_name);
strcat(final_sim_name, sim_index);
strcat(final_sim_name, pos + strlen(placeholder));
} else {
final_sim_name = strdup(sim_name);
}
g_hash_table_insert(account->params, g_strdup("DisplayName"), g_strdup(final_sim_name));
g_settings_set_value(settings, "sim-names", g_variant_new("a(ss)", builder));
free(final_sim_name);
}
g_variant_builder_unref(builder);
}
if (sim_names) {
g_variant_unref(sim_names);
}
}
self->priv->accounts = g_list_append(self->priv->accounts, account);
}
if (settings) {
g_object_unref (settings);
}
if (output) {
g_free(output);
}
if (output2) {
g_free (output2);
}
}
static void mcp_account_manager_ofono_class_init(McpAccountManagerOfonoClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
gobject_class->dispose = mcp_account_manager_ofono_dispose;
g_type_class_add_private(gobject_class, sizeof(McpAccountManagerOfonoPrivate));
}
static GList *account_manager_ofono_list(const McpAccountStorage *storage, const McpAccountManager *am)
{
McpAccountManagerOfono *self = (McpAccountManagerOfono*) storage;
GList *accounts = NULL;
OfonoAccount *account = NULL;
GList *l;
for (l = self->priv->accounts; l != NULL; l = l->next) {
account = (OfonoAccount*)l->data;
accounts = g_list_prepend(accounts, g_strdup(account->account_name));
}
return accounts;
}
static gboolean account_manager_ofono_get(const McpAccountStorage *storage, const McpAccountManager *am,
const gchar *account_name, const gchar *key)
{
McpAccountManagerOfono *self = (McpAccountManagerOfono*) storage;
GList *l;
OfonoAccount *account = NULL;
int found = 0;
for (l = self->priv->accounts; l != NULL; l = l->next) {
account = (OfonoAccount*)l->data;
if (!strcmp(account_name, account->account_name)) {
found = 1;
break;
}
}
if (!found) {
return FALSE;
}
if (key == NULL) {
GHashTableIter iter;
gpointer itkey, value;
g_hash_table_iter_init(&iter, account->params);
while (g_hash_table_iter_next(&iter, &itkey, &value)) {
g_debug("%s: %s, %s %s", G_STRFUNC, account_name, (char*)itkey, (char*)value);
mcp_account_manager_set_value(am, account_name, itkey, value);
}
} else {
gchar *value = g_hash_table_lookup(account->params, key);
g_debug("%s: %s, %s %s", G_STRFUNC, account_name, (char*)key, (char*)value);
mcp_account_manager_set_value(am, account_name, key, value);
}
return TRUE;
}
static gboolean account_manager_ofono_set(const McpAccountStorage *storage, const McpAccountManager *am,
const gchar *account_name, const gchar *key, const gchar *val)
{
return FALSE;
}
static gchar *account_manager_ofono_create(const McpAccountStorage *storage, const McpAccountManager *am,
const gchar *cm_name, const gchar *protocol_name, GHashTable *params, GError **error)
{
g_set_error(error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Ofono ril account manager cannot create accounts");
return NULL;
}
static gboolean account_manager_ofono_delete(const McpAccountStorage *storage, const McpAccountManager *am,
const gchar *account_name, const gchar *key)
{
g_debug("%s: %s, %s", G_STRFUNC, account_name, key);
return FALSE;
}
static gboolean account_manager_ofono_commit(const McpAccountStorage *storage, const McpAccountManager *am)
{
g_debug("%s", G_STRFUNC);
return FALSE;
}
static void account_manager_ofono_get_identifier(const McpAccountStorage *storage, const gchar *account_name,
GValue *identifier)
{
McpAccountManagerOfono *self = (McpAccountManagerOfono*) storage;
GList *l;
OfonoAccount *account = NULL;
int found = 0;
for (l = self->priv->accounts; l != NULL; l = l->next) {
account = (OfonoAccount*)l->data;
if (!strcmp(account_name, account->account_name)) {
found = 1;
break;
}
}
if (!found) {
return;
}
g_debug("%s: %s", G_STRFUNC, account_name);
g_value_init(identifier, G_TYPE_UINT);
g_value_set_uint(identifier, account->index);
}
static guint account_manager_ofono_get_restrictions(const McpAccountStorage *storage, const gchar *account_name)
{
McpAccountManagerOfono *self = (McpAccountManagerOfono*) storage;
GList *l;
OfonoAccount *account = NULL;
int found = 0;
for (l = self->priv->accounts; l != NULL; l = l->next) {
account = (OfonoAccount*)l->data;
if (!strcmp(account_name, account->account_name)) {
found = 1;
break;
}
}
if (!found) {
return G_MAXUINT;
}
return TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PARAMETERS |
TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_ENABLED |
TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PRESENCE |
TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_SERVICE;
}
static void account_storage_iface_init(McpAccountStorageIface *iface)
{
iface->name = PLUGIN_NAME;
iface->desc = PLUGIN_DESCRIPTION;
iface->priority = PLUGIN_PRIORITY;
iface->provider = PLUGIN_PROVIDER;
#define IMPLEMENT(x) iface->x = account_manager_ofono_##x
IMPLEMENT (get);
IMPLEMENT (list);
IMPLEMENT (set);
IMPLEMENT (create);
IMPLEMENT (delete);
IMPLEMENT (commit);
IMPLEMENT (get_identifier);
IMPLEMENT (get_restrictions);
#undef IMPLEMENT
}
McpAccountManagerOfono *mcp_account_manager_ofono_new(void)
{
return g_object_new(MCP_TYPE_ACCOUNT_MANAGER_OFONO, NULL);
}
telepathy-ofono-0.2+16.04.20151120/sqlitedatabase.h 0000644 0000153 0000161 00000002624 12623675611 022171 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Gustavo Pichorim Boiko
*/
#ifndef SQLITEDATABASE_H
#define SQLITEDATABASE_H
#include
#include
class SQLiteDatabase : public QObject
{
Q_OBJECT
public:
static SQLiteDatabase *instance();
bool initializeDatabase();
QSqlDatabase database() const;
bool beginTransation();
bool finishTransaction();
bool rollbackTransaction();
bool reopen();
protected:
bool createOrUpdateDatabase();
QStringList parseSchemaFile(const QString &fileName);
void parseVersionInfo();
private:
explicit SQLiteDatabase(QObject *parent = 0);
QString mDatabasePath;
QSqlDatabase mDatabase;
int mSchemaVersion;
};
#endif // SQLITEDATABASE_H
telepathy-ofono-0.2+16.04.20151120/protocol.cpp 0000644 0000153 0000161 00000005210 12623675611 021371 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#include "protocol.h"
#include "connection.h"
#include
#include
#include
Protocol::Protocol(const QDBusConnection &dbusConnection, const QString &name)
: Tp::BaseProtocol(dbusConnection, name), mAudioModeMediator(mPowerDDBus)
{
addressingIface = Tp::BaseProtocolAddressingInterface::create();
addressingIface->setAddressableVCardFields(QStringList() << QLatin1String("tel"));
addressingIface->setAddressableUriSchemes(QStringList() << QLatin1String("tel"));
plugInterface(Tp::AbstractProtocolInterfacePtr::dynamicCast(addressingIface));
setRequestableChannelClasses(Tp::RequestableChannelClassSpecList() <<
Tp::RequestableChannelClassSpec::textChat() <<
Tp::RequestableChannelClassSpec::audioCall());
setCreateConnectionCallback(memFun(this, &Protocol::createConnection));
Tp::ProtocolParameterList parameters;
Tp::ProtocolParameter parameter("modem-objpath", "s", 0);
Tp::ProtocolParameter parameter2("fakeEmergencyNumber", "s", 0);
parameters << parameter << parameter2;
setParameters(parameters);
}
Tp::BaseConnectionPtr Protocol::createConnection(const QVariantMap ¶meters, Tp::DBusError *error) {
Q_UNUSED(error);
Tp::BaseConnectionPtr connection_ptr = Tp::BaseConnection::create("ofono", name().toLatin1(), parameters);
connect(
static_cast(connection_ptr.data()), &oFonoConnection::activeAudioOutputChanged,
Tp::memFun(&mAudioModeMediator, &PowerDAudioModeMediator::audioModeChanged)
);
connect(
static_cast(connection_ptr.data()), &oFonoConnection::lastChannelClosed,
Tp::memFun(&mAudioModeMediator, &PowerDAudioModeMediator::audioOutputClosed)
);
return connection_ptr;
}
telepathy-ofono-0.2+16.04.20151120/ofonocallchannel.cpp 0000644 0000153 0000161 00000034147 12623675611 023050 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#include "ofonocallchannel.h"
#ifdef USE_PULSEAUDIO
#include "qpulseaudioengine.h"
#endif
oFonoCallChannel::oFonoCallChannel(oFonoConnection *conn, QString phoneNumber, uint targetHandle, QString voiceObj, QObject *parent):
OfonoVoiceCall(voiceObj),
mIncoming(false),
mRequestedHangup(false),
mConnection(conn),
mPhoneNumber(phoneNumber),
mTargetHandle(targetHandle),
mDtmfLock(false),
mMultiparty(false)
{
Tp::BaseChannelPtr baseChannel = Tp::BaseChannel::create(mConnection, TP_QT_IFACE_CHANNEL_TYPE_CALL, Tp::HandleTypeContact, targetHandle);
Tp::BaseChannelCallTypePtr callType = Tp::BaseChannelCallType::create(baseChannel.data(),
true,
Tp::StreamTransportTypeUnknown,
true,
false, "","");
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(callType));
mHoldIface = Tp::BaseChannelHoldInterface::create();
mHoldIface->setSetHoldStateCallback(Tp::memFun(this,&oFonoCallChannel::onHoldStateChanged));
mMuteIface = Tp::BaseCallMuteInterface::create();
mMuteIface->setSetMuteStateCallback(Tp::memFun(this,&oFonoCallChannel::onMuteStateChanged));
mAudioOutputsIface = BaseChannelAudioOutputsInterface::create();
mAudioOutputsIface->setSetActiveAudioOutputCallback(Tp::memFun(this,&oFonoCallChannel::onSetActiveAudioOutput));
mSplittableIface = Tp::BaseChannelSplittableInterface::create();
mSplittableIface->setSplitCallback(Tp::memFun(this,&oFonoCallChannel::onSplit));
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mHoldIface));
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mMuteIface));
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mAudioOutputsIface));
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mSplittableIface));
mBaseChannel = baseChannel;
mCallChannel = Tp::BaseChannelCallTypePtr::dynamicCast(mBaseChannel->interface(TP_QT_IFACE_CHANNEL_TYPE_CALL));
mCallChannel->setHangupCallback(Tp::memFun(this,&oFonoCallChannel::onHangup));
mCallChannel->setAcceptCallback(Tp::memFun(this,&oFonoCallChannel::onAccept));
QObject::connect(this, SIGNAL(hangupComplete(bool)), this, SLOT(onHangupComplete(bool)));
QObject::connect(this, SIGNAL(answerComplete(bool)), this, SLOT(onAnswerComplete(bool)));
// init must be called after initialization, otherwise we will have no object path registered.
QTimer::singleShot(0, this, SLOT(init()));
#ifdef USE_PULSEAUDIO
QByteArray pulseAudioDisabled = qgetenv("PA_DISABLED");
mHasPulseAudio = true;
if (!pulseAudioDisabled.isEmpty())
mHasPulseAudio = false;
#endif
}
Tp::CallState oFonoCallChannel::callState()
{
return (Tp::CallState)mCallChannel->callState();
}
void oFonoCallChannel::onSplit(Tp::DBusError *error)
{
mConnection->voiceCallManager()->privateChat(path());
}
void oFonoCallChannel::onSetActiveAudioOutput(const QString &id, Tp::DBusError *error)
{
#ifdef USE_PULSEAUDIO
// fallback to earpiece/headset
AudioMode mode = AudioModeWiredOrEarpiece;
if (id == "bluetooth") {
mode = AudioModeBluetooth;
} else if (id == "speaker") {
mode = AudioModeSpeaker;
}
if (mHasPulseAudio)
QPulseAudioEngine::instance()->setCallMode(CallActive, mode);
#endif
}
void oFonoCallChannel::onHangupComplete(bool status)
{
if (!status) {
QTimer::singleShot(2000, this, SLOT(hangup()));
}
}
void oFonoCallChannel::onAnswerComplete(bool status)
{
if (!status) {
QTimer::singleShot(1000, this, SLOT(answer()));
}
}
void oFonoCallChannel::onHangup(uint reason, const QString &detailedReason, const QString &message, Tp::DBusError *error)
{
// TODO: use the parameters sent by telepathy
mRequestedHangup = true;
hangup();
}
void oFonoCallChannel::onAccept(Tp::DBusError*)
{
QVariantMap stateDetails;
Tp::CallStateReason reason;
reason.actor = 0;
reason.reason = Tp::CallStateChangeReasonUserRequested;
reason.message = "";
reason.DBusReason = "";
mCallChannel->setCallState(Tp::CallStateAccepted, 0, reason, stateDetails);
if (this->state() == "waiting") {
mConnection->voiceCallManager()->holdAndAnswer();
} else {
answer();
}
}
void oFonoCallChannel::init()
{
mIncoming = this->state() == "incoming" || this->state() == "waiting";
mMultiparty = this->multiparty();
mPreviousState = this->state();
mObjPath = mBaseChannel->objectPath();
Tp::CallMemberMap memberFlags;
Tp::HandleIdentifierMap identifiers;
QVariantMap stateDetails;
Tp::CallStateReason reason;
identifiers[mTargetHandle] = mPhoneNumber;
reason.actor = 0;
reason.reason = Tp::CallStateChangeReasonProgressMade;
reason.message = "";
reason.DBusReason = "";
if (mIncoming) {
memberFlags[mTargetHandle] = 0;
} else {
memberFlags[mTargetHandle] = Tp::CallMemberFlagRinging;
}
mCallChannel->setCallState(Tp::CallStateInitialising, 0, reason, stateDetails);
mCallContent = Tp::BaseCallContent::create(baseChannel()->dbusConnection(), baseChannel().data(), "audio", Tp::MediaStreamTypeAudio, Tp::MediaStreamDirectionNone);
mDTMFIface = Tp::BaseCallContentDTMFInterface::create();
mCallContent->plugInterface(Tp::AbstractCallContentInterfacePtr::dynamicCast(mDTMFIface));
mCallChannel->addContent(mCallContent);
mDTMFIface->setStartToneCallback(Tp::memFun(this,&oFonoCallChannel::onDTMFStartTone));
mDTMFIface->setStopToneCallback(Tp::memFun(this,&oFonoCallChannel::onDTMFStopTone));
mCallChannel->setMembersFlags(memberFlags, identifiers, Tp::UIntList(), reason);
mCallChannel->setCallState(Tp::CallStateInitialised, 0, reason, stateDetails);
QObject::connect(mBaseChannel.data(), SIGNAL(closed()), this, SLOT(deleteLater()));
QObject::connect(mConnection->callVolume(), SIGNAL(mutedChanged(bool)), SLOT(onOfonoMuteChanged(bool)));
QObject::connect(this, SIGNAL(stateChanged(QString)), SLOT(onOfonoCallStateChanged(QString)));
QObject::connect(mConnection, SIGNAL(activeAudioOutputChanged(QString)), mAudioOutputsIface.data(), SLOT(setActiveAudioOutput(QString)));
QObject::connect(mConnection, SIGNAL(audioOutputsChanged(AudioOutputList)), mAudioOutputsIface.data(), SLOT(setAudioOutputs(AudioOutputList)));
QObject::connect(mConnection->voiceCallManager(), SIGNAL(sendTonesComplete(bool)), SLOT(onDtmfComplete(bool)));
QObject::connect(this, SIGNAL(multipartyChanged(bool)), this, SLOT(onMultipartyChanged(bool)));
QObject::connect(this, SIGNAL(disconnectReason(const QString &)), this, SLOT(onDisconnectReason(const QString &)));
mAudioOutputsIface->setAudioOutputs(mConnection->audioOutputs());
mAudioOutputsIface->setActiveAudioOutput(mConnection->activeAudioOutput());
}
void oFonoCallChannel::onDisconnectReason(const QString &reason) {
mRequestedHangup = reason == "local";
}
void oFonoCallChannel::onMultipartyChanged(bool multiparty)
{
// if previous state was multparty then split
if (multiparty) {
Q_EMIT merged();
} else {
Q_EMIT splitted();
}
mMultiparty = multiparty;
}
void oFonoCallChannel::onOfonoMuteChanged(bool mute)
{
Tp::LocalMuteState state = mute ? Tp::LocalMuteStateMuted : Tp::LocalMuteStateUnmuted;
mMuteIface->setMuteState(state);
}
void oFonoCallChannel::onHoldStateChanged(const Tp::LocalHoldState &state, const Tp::LocalHoldStateReason &reason, Tp::DBusError *error)
{
if (state == Tp::LocalHoldStateHeld && this->state() == "active") {
QObject::connect(mConnection->voiceCallManager(), SIGNAL(swapCallsComplete(bool)), this, SLOT(onSwapCallsComplete(bool)));
mConnection->voiceCallManager()->swapCalls();
mHoldIface->setHoldState(Tp::LocalHoldStatePendingHold, Tp::LocalHoldStateReasonRequested);
} else if (state == Tp::LocalHoldStateUnheld && this->state() == "held") {
QObject::connect(mConnection->voiceCallManager(), SIGNAL(swapCallsComplete(bool)), this, SLOT(onSwapCallsComplete(bool)));
mConnection->voiceCallManager()->swapCalls();
mHoldIface->setHoldState(Tp::LocalHoldStatePendingUnhold, Tp::LocalHoldStateReasonRequested);
}
}
void oFonoCallChannel::onSwapCallsComplete(bool success)
{
if (!success && errorName() == "org.ofono.Error.InProgress") {
QTimer::singleShot(2000, mConnection->voiceCallManager(), SLOT(swapCalls()));
return;
}
Tp::LocalHoldState holdState = this->state() == "active" ? Tp::LocalHoldStateUnheld : Tp::LocalHoldStateHeld;
Tp::LocalHoldStateReason reason = success ? Tp::LocalHoldStateReasonRequested : Tp::LocalHoldStateReasonResourceNotAvailable;
QObject::disconnect(mConnection->voiceCallManager(), SIGNAL(swapCallsComplete(bool)), this, SLOT(onSwapCallsComplete(bool)));
mHoldIface->setHoldState(holdState, reason);
}
void oFonoCallChannel::onMuteStateChanged(const Tp::LocalMuteState &state, Tp::DBusError *error)
{
if (state == Tp::LocalMuteStateMuted) {
mConnection->callVolume()->setMuted(true);
#ifdef USE_PULSEAUDIO
if (mHasPulseAudio)
QPulseAudioEngine::instance()->setMicMute(true);
#endif
} else if (state == Tp::LocalMuteStateUnmuted) {
mConnection->callVolume()->setMuted(false);
#ifdef USE_PULSEAUDIO
if (mHasPulseAudio)
QPulseAudioEngine::instance()->setMicMute(false);
#endif
}
}
void oFonoCallChannel::sendNextDtmf()
{
if (mDtmfLock) {
return;
}
if (!mDtmfPendingStrings.isEmpty()) {
mDtmfLock = true;
mConnection->voiceCallManager()->sendTones(mDtmfPendingStrings.front());
}
}
void oFonoCallChannel::onDtmfComplete(bool success)
{
// this might be a response for another channel
if (mCallChannel->callState() != Tp::CallStateActive) {
return;
}
mDtmfLock = false;
if (success) {
if (mDtmfPendingStrings.count() > 0) {
mDtmfPendingStrings.removeFirst();
}
if (mDtmfPendingStrings.isEmpty()) {
return;
}
sendNextDtmf();
} else {
QTimer::singleShot(1000, this, SLOT(sendNextDtmf()));
}
}
void oFonoCallChannel::onDTMFStartTone(uchar event, Tp::DBusError *error)
{
QString finalString;
if (event == 10) {
finalString = "*";
} else if (event == 11) {
finalString = "#";
} else {
finalString = QString::number(event);
}
qDebug() << "start tone" << finalString;
// we can't append to the first item in the queue as it is being sent and
// we dont know yet if it will succeed or not.
if (mDtmfPendingStrings.count() > 1) {
mDtmfPendingStrings[1] += finalString;
} else {
mDtmfPendingStrings << finalString;
}
sendNextDtmf();
}
void oFonoCallChannel::onDTMFStopTone(Tp::DBusError *error)
{
}
oFonoCallChannel::~oFonoCallChannel()
{
qDebug() << "call channel closed";
// TODO - for some reason the object is not being removed
mConnection->dbusConnection().unregisterObject(mObjPath, QDBusConnection::UnregisterTree);
}
Tp::BaseChannelPtr oFonoCallChannel::baseChannel()
{
return mBaseChannel;
}
void oFonoCallChannel::onOfonoCallStateChanged(const QString &state)
{
Tp::CallStateReason reason;
QVariantMap stateDetails;
reason.actor = 0;
reason.reason = Tp::CallStateChangeReasonUserRequested;
reason.message = "";
reason.DBusReason = "";
// we invalidate the pending dtmf strings if the call status is changed
mDtmfPendingStrings.clear();
mDtmfLock = false;
if (state == "disconnected") {
qDebug() << "disconnected";
if (mIncoming && (mPreviousState == "incoming" || mPreviousState == "waiting") && !mRequestedHangup) {
reason.reason = Tp::CallStateChangeReasonNoAnswer;
}
mCallChannel->setCallState(Tp::CallStateEnded, 0, reason, stateDetails);
Q_EMIT closed();
mBaseChannel->close();
} else if (state == "active") {
qDebug() << "active";
mHoldIface->setHoldState(Tp::LocalHoldStateUnheld, Tp::LocalHoldStateReasonNone);
if (mMultiparty) {
Q_EMIT multipartyCallActive();
}
if (mPreviousState == "incoming") {
mConnection->updateAudioRouteToEarpiece();
}
if (mPreviousState == "dialing" || mPreviousState == "alerting" ||
mPreviousState == "incoming") {
mConnection->callVolume()->setMuted(false);
mCallChannel->setCallState(Tp::CallStateAccepted, 0, reason, stateDetails);
}
mCallChannel->setCallState(Tp::CallStateActive, 0, reason, stateDetails);
} else if (state == "held") {
mHoldIface->setHoldState(Tp::LocalHoldStateHeld, Tp::LocalHoldStateReasonNone);
if (mMultiparty) {
Q_EMIT multipartyCallHeld();
}
qDebug() << "held";
} else if (state == "dialing") {
qDebug() << "dialing";
} else if (state == "alerting") {
qDebug() << "alerting";
} else if (state == "incoming") {
qDebug() << "incoming";
} else if (state == "waiting") {
qDebug() << "waiting";
}
// always update the audio route when call state changes
mConnection->updateAudioRoute();
mPreviousState = state;
}
telepathy-ofono-0.2+16.04.20151120/ofonoconferencecallchannel.h 0000644 0000153 0000161 00000005620 12623675611 024537 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#ifndef OFONOCONFERENCECALLCHANNEL_H
#define OFONOCONFERENCECALLCHANNEL_H
#include
#include
#include
#include
#include
#include
#include "connection.h"
#include "audiooutputsiface.h"
class oFonoConnection;
class oFonoConferenceCallChannel : public QObject
{
Q_OBJECT
public:
oFonoConferenceCallChannel(oFonoConnection *conn, QObject *parent = 0);
~oFonoConferenceCallChannel();
void onHangup(uint reason, const QString &detailedReason, const QString &message, Tp::DBusError* error);
void onMuteStateChanged(const Tp::LocalMuteState &state, Tp::DBusError *error);
void onHoldStateChanged(const Tp::LocalHoldState &state, const Tp::LocalHoldStateReason &reason, Tp::DBusError *error);
void onDTMFStartTone(uchar event, Tp::DBusError *error);
void onDTMFStopTone(Tp::DBusError *error);
void onSetActiveAudioOutput(const QString &id, Tp::DBusError *error);
void onMerge(const QDBusObjectPath &channel, Tp::DBusError *error);
Tp::BaseChannelPtr baseChannel();
void setConferenceActive(bool active);
private Q_SLOTS:
void onDtmfComplete(bool success);
void sendNextDtmf();
void init();
void onOfonoMuteChanged(bool mute);
void onChannelMerged(const QDBusObjectPath &path);
void onChannelSplitted(const QDBusObjectPath &path);
void onSwapCallsComplete(bool success);
private:
QString mObjPath;
QString mPreviousState;
bool mIncoming;
bool mRequestedHangup;
oFonoConnection *mConnection;
QList mCallChannels;
Tp::BaseChannelPtr mBaseChannel;
Tp::BaseChannelHoldInterfacePtr mHoldIface;
Tp::BaseChannelConferenceInterfacePtr mConferenceIface;
Tp::BaseChannelMergeableConferenceInterfacePtr mMergeableIface;
Tp::BaseCallMuteInterfacePtr mMuteIface;
BaseChannelAudioOutputsInterfacePtr mAudioOutputsIface;
Tp::BaseChannelCallTypePtr mCallChannel;
Tp::BaseCallContentDTMFInterfacePtr mDTMFIface;
Tp::BaseCallContentPtr mCallContent;
bool mDtmfLock;
QStringList mDtmfPendingStrings;
};
#endif // OFONOCONFERENCECALLCHANNEL_H
telepathy-ofono-0.2+16.04.20151120/cmake/ 0000755 0000153 0000161 00000000000 12623676450 020110 5 ustar pbuser pbgroup 0000000 0000000 telepathy-ofono-0.2+16.04.20151120/cmake/modules/ 0000755 0000153 0000161 00000000000 12623676450 021560 5 ustar pbuser pbgroup 0000000 0000000 telepathy-ofono-0.2+16.04.20151120/cmake/modules/LibFindMacros.cmake 0000644 0000153 0000161 00000011060 12623675611 025232 0 ustar pbuser pbgroup 0000000 0000000 # Version 1.0 (2013-04-12)
# Public Domain, originally written by Lasse Kärkkäinen
# Published at http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
# If you improve the script, please modify the forementioned wiki page because
# I no longer maintain my scripts (hosted as static files at zi.fi). Feel free
# to remove this entire header if you use real version control instead.
# Changelog:
# 2013-04-12 Added version number (1.0) and this header, no other changes
# 2009-10-08 Originally published
# Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments
# used for the current package. For this to work, the first parameter must be the
# prefix of the current package, then the prefix of the new package etc, which are
# passed to find_package.
macro (libfind_package PREFIX)
set (LIBFIND_PACKAGE_ARGS ${ARGN})
if (${PREFIX}_FIND_QUIETLY)
set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET)
endif (${PREFIX}_FIND_QUIETLY)
if (${PREFIX}_FIND_REQUIRED)
set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED)
endif (${PREFIX}_FIND_REQUIRED)
find_package(${LIBFIND_PACKAGE_ARGS})
endmacro (libfind_package)
# CMake developers made the UsePkgConfig system deprecated in the same release (2.6)
# where they added pkg_check_modules. Consequently I need to support both in my scripts
# to avoid those deprecated warnings. Here's a helper that does just that.
# Works identically to pkg_check_modules, except that no checks are needed prior to use.
macro (libfind_pkg_check_modules PREFIX PKGNAME)
if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
include(UsePkgConfig)
pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS)
else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(${PREFIX} ${PKGNAME})
endif (PKG_CONFIG_FOUND)
endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
endmacro (libfind_pkg_check_modules)
# Do the final processing once the paths have been detected.
# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain
# all the variables, each of which contain one include directory.
# Ditto for ${PREFIX}_PROCESS_LIBS and library files.
# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
# Also handles errors in case library detection was required, etc.
macro (libfind_process PREFIX)
# Skip processing if already processed during this run
if (NOT ${PREFIX}_FOUND)
# Start with the assumption that the library was found
set (${PREFIX}_FOUND TRUE)
# Process all includes and set _FOUND to false if any are missing
foreach (i ${${PREFIX}_PROCESS_INCLUDES})
if (${i})
set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}})
mark_as_advanced(${i})
else (${i})
set (${PREFIX}_FOUND FALSE)
endif (${i})
endforeach (i)
# Process all libraries and set _FOUND to false if any are missing
foreach (i ${${PREFIX}_PROCESS_LIBS})
if (${i})
set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}})
mark_as_advanced(${i})
else (${i})
set (${PREFIX}_FOUND FALSE)
endif (${i})
endforeach (i)
# Print message and/or exit on fatal error
if (${PREFIX}_FOUND)
if (NOT ${PREFIX}_FIND_QUIETLY)
message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
endif (NOT ${PREFIX}_FIND_QUIETLY)
else (${PREFIX}_FOUND)
if (${PREFIX}_FIND_REQUIRED)
foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS})
message("${i}=${${i}}")
endforeach (i)
message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.")
endif (${PREFIX}_FIND_REQUIRED)
endif (${PREFIX}_FOUND)
endif (NOT ${PREFIX}_FOUND)
endmacro (libfind_process)
macro(libfind_library PREFIX basename)
set(TMP "")
if(MSVC80)
set(TMP -vc80)
endif(MSVC80)
if(MSVC90)
set(TMP -vc90)
endif(MSVC90)
set(${PREFIX}_LIBNAMES ${basename}${TMP})
if(${ARGC} GREATER 2)
set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2})
string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES})
set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP})
endif(${ARGC} GREATER 2)
find_library(${PREFIX}_LIBRARY
NAMES ${${PREFIX}_LIBNAMES}
PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}
)
endmacro(libfind_library)
telepathy-ofono-0.2+16.04.20151120/cmake/modules/FindLcov.cmake 0000644 0000153 0000161 00000001720 12623675611 024264 0 ustar pbuser pbgroup 0000000 0000000 # - Find lcov
# Will define:
#
# LCOV_EXECUTABLE - the lcov binary
# GENHTML_EXECUTABLE - the genhtml executable
#
# Copyright (C) 2010 by Johannes Wienke
#
# This program is free software; you can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation;
# either version 2, or (at your option)
# any later version.
#
# This program 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 General Public License for more details.
#
INCLUDE(FindPackageHandleStandardArgs)
FIND_PROGRAM(LCOV_EXECUTABLE lcov)
FIND_PROGRAM(GENHTML_EXECUTABLE genhtml)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lcov DEFAULT_MSG LCOV_EXECUTABLE GENHTML_EXECUTABLE)
# only visible in advanced view
MARK_AS_ADVANCED(LCOV_EXECUTABLE GENHTML_EXECUTABLE)
telepathy-ofono-0.2+16.04.20151120/cmake/modules/ParseArguments.cmake 0000644 0000153 0000161 00000003406 12623675611 025523 0 ustar pbuser pbgroup 0000000 0000000 # Parse arguments passed to a function into several lists separated by
# upper-case identifiers and options that do not have an associated list e.g.:
#
# SET(arguments
# hello OPTION3 world
# LIST3 foo bar
# OPTION2
# LIST1 fuz baz
# )
# PARSE_ARGUMENTS(ARG "LIST1;LIST2;LIST3" "OPTION1;OPTION2;OPTION3" ${arguments})
#
# results in 7 distinct variables:
# * ARG_DEFAULT_ARGS: hello;world
# * ARG_LIST1: fuz;baz
# * ARG_LIST2:
# * ARG_LIST3: foo;bar
# * ARG_OPTION1: FALSE
# * ARG_OPTION2: TRUE
# * ARG_OPTION3: TRUE
#
# taken from http://www.cmake.org/Wiki/CMakeMacroParseArguments
MACRO(PARSE_ARGUMENTS prefix arg_names option_names)
SET(DEFAULT_ARGS)
FOREACH(arg_name ${arg_names})
SET(${prefix}_${arg_name})
ENDFOREACH(arg_name)
FOREACH(option ${option_names})
SET(${prefix}_${option} FALSE)
ENDFOREACH(option)
SET(current_arg_name DEFAULT_ARGS)
SET(current_arg_list)
FOREACH(arg ${ARGN})
SET(larg_names ${arg_names})
LIST(FIND larg_names "${arg}" is_arg_name)
IF (is_arg_name GREATER -1)
SET(${prefix}_${current_arg_name} ${current_arg_list})
SET(current_arg_name ${arg})
SET(current_arg_list)
ELSE (is_arg_name GREATER -1)
SET(loption_names ${option_names})
LIST(FIND loption_names "${arg}" is_option)
IF (is_option GREATER -1)
SET(${prefix}_${arg} TRUE)
ELSE (is_option GREATER -1)
SET(current_arg_list ${current_arg_list} ${arg})
ENDIF (is_option GREATER -1)
ENDIF (is_arg_name GREATER -1)
ENDFOREACH(arg)
SET(${prefix}_${current_arg_name} ${current_arg_list})
ENDMACRO(PARSE_ARGUMENTS)
telepathy-ofono-0.2+16.04.20151120/cmake/modules/Findgcovr.cmake 0000644 0000153 0000161 00000001702 12623675611 024501 0 ustar pbuser pbgroup 0000000 0000000 # - Find gcovr scrip
# Will define:
#
# GCOVR_EXECUTABLE - the gcovr script
#
# Uses:
#
# GCOVR_ROOT - root to search for the script
#
# Copyright (C) 2011 by Johannes Wienke
#
# This program is free software; you can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation;
# either version 2, or (at your option)
# any later version.
#
# This program 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 General Public License for more details.
#
INCLUDE(FindPackageHandleStandardArgs)
FIND_PROGRAM(GCOVR_EXECUTABLE gcovr HINTS ${GCOVR_ROOT} "${GCOVR_ROOT}/bin")
FIND_PACKAGE_HANDLE_STANDARD_ARGS(gcovr DEFAULT_MSG GCOVR_EXECUTABLE)
# only visible in advanced view
MARK_AS_ADVANCED(GCOVR_EXECUTABLE)
telepathy-ofono-0.2+16.04.20151120/cmake/modules/FindLibPhoneNumber.cmake 0000644 0000153 0000161 00000001414 12623675611 026232 0 ustar pbuser pbgroup 0000000 0000000 set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
include(GNUInstallDirs)
include(LibFindMacros)
# Include dir
find_path(LibPhoneNumber_INCLUDE_DIR
NAMES phonenumberutil.h
PATHS "/usr/local/${CMAKE_INSTALL_INCLUDEDIR}" ${CMAKE_INSTALL_FULL_INCLUDEDIR}
PATH_SUFFIXES "phonenumbers"
)
# library itself
find_library(LibPhoneNumber_LIBRARY
NAMES phonenumber
PATHS "/usr/local/${CMAKE_INSTALL_LIBDIR}" ${CMAKE_INSTALL_FULL_LIBDIR}
)
# Set the include dir variables and the libraries and let libfind_process do the rest.
# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
set(LibPhoneNumber_PROCESS_INCLUDES LibPhoneNumber_INCLUDE_DIR)
set(LibPhoneNumber_PROCESS_LIBS LibPhoneNumber_LIBRARY)
libfind_process(LibPhoneNumber)
telepathy-ofono-0.2+16.04.20151120/cmake/modules/EnableCoverageReport.cmake 0000644 0000153 0000161 00000015311 12623675611 026617 0 ustar pbuser pbgroup 0000000 0000000 # - Creates a special coverage build type and target on GCC.
#
# Defines a function ENABLE_COVERAGE_REPORT which generates the coverage target
# for selected targets. Optional arguments to this function are used to filter
# unwanted results using globbing expressions. Moreover targets with tests for
# the source code can be specified to trigger regenerating the report if the
# test has changed
#
# ENABLE_COVERAGE_REPORT(TARGETS target... [FILTER filter...] [TESTS test targets...])
#
# To generate a coverage report first build the project with
# CMAKE_BUILD_TYPE=coverage, then call make test and afterwards make coverage.
#
# The coverage report is based on gcov. Depending on the availability of lcov
# a HTML report will be generated and/or an XML report of gcovr is found.
# The generated coverage target executes all found solutions. Special targets
# exist to create e.g. only the xml report: coverage-xml.
#
# Copyright (C) 2010 by Johannes Wienke
#
# This program is free software; you can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation;
# either version 2, or (at your option)
# any later version.
#
# This program 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 General Public License for more details.
#
INCLUDE(ParseArguments)
FIND_PACKAGE(Lcov)
FIND_PACKAGE(gcovr)
FUNCTION(ENABLE_COVERAGE_REPORT)
# argument parsing
PARSE_ARGUMENTS(ARG "FILTER;TARGETS;TESTS" "" ${ARGN})
SET(COVERAGE_RAW_FILE "${CMAKE_BINARY_DIR}/coverage.raw.info")
SET(COVERAGE_FILTERED_FILE "${CMAKE_BINARY_DIR}/coverage.info")
SET(COVERAGE_REPORT_DIR "${CMAKE_BINARY_DIR}/coveragereport")
SET(COVERAGE_XML_FILE "${CMAKE_BINARY_DIR}/coverage.xml")
SET(COVERAGE_XML_COMMAND_FILE "${CMAKE_BINARY_DIR}/coverage-xml.cmake")
# decide if there is any tool to create coverage data
SET(TOOL_FOUND FALSE)
IF(LCOV_FOUND OR GCOVR_FOUND)
SET(TOOL_FOUND TRUE)
ENDIF()
IF(NOT TOOL_FOUND)
MESSAGE(STATUS "Cannot enable coverage targets because neither lcov nor gcovr are found.")
ENDIF()
STRING(TOLOWER "${CMAKE_BUILD_TYPE}" COVERAGE_BUILD_TYPE)
IF(CMAKE_COMPILER_IS_GNUCXX AND TOOL_FOUND AND "${COVERAGE_BUILD_TYPE}" MATCHES "coverage")
MESSAGE(STATUS "Coverage support enabled for targets: ${ARG_TARGETS}")
# create coverage build type
SET(CMAKE_CXX_FLAGS_COVERAGE ${CMAKE_CXX_FLAGS_DEBUG} PARENT_SCOPE)
SET(CMAKE_C_FLAGS_COVERAGE ${CMAKE_C_FLAGS_DEBUG} PARENT_SCOPE)
SET(CMAKE_CONFIGURATION_TYPES ${CMAKE_CONFIGURATION_TYPES} coverage PARENT_SCOPE)
# instrument targets
SET_TARGET_PROPERTIES(${ARG_TARGETS} PROPERTIES COMPILE_FLAGS --coverage
LINK_FLAGS --coverage)
# html report
IF (LCOV_FOUND)
MESSAGE(STATUS "Enabling HTML coverage report")
# set up coverage target
ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_RAW_FILE}
COMMAND ${LCOV_EXECUTABLE} -c -d ${CMAKE_BINARY_DIR} -o ${COVERAGE_RAW_FILE}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Collecting coverage data"
DEPENDS ${ARG_TARGETS} ${ARG_TESTS}
VERBATIM)
# filter unwanted stuff
LIST(LENGTH ARG_FILTER FILTER_LENGTH)
IF(${FILTER_LENGTH} GREATER 0)
SET(FILTER COMMAND ${LCOV_EXECUTABLE})
FOREACH(F ${ARG_FILTER})
SET(FILTER ${FILTER} -r ${COVERAGE_FILTERED_FILE} ${F})
ENDFOREACH()
SET(FILTER ${FILTER} -o ${COVERAGE_FILTERED_FILE})
ELSE()
SET(FILTER "")
ENDIF()
ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_FILTERED_FILE}
COMMAND ${LCOV_EXECUTABLE} -e ${COVERAGE_RAW_FILE} "${CMAKE_SOURCE_DIR}*" -o ${COVERAGE_FILTERED_FILE}
${FILTER}
DEPENDS ${COVERAGE_RAW_FILE}
COMMENT "Filtering recorded coverage data for project-relevant entries"
VERBATIM)
ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_REPORT_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${COVERAGE_REPORT_DIR}
COMMAND ${GENHTML_EXECUTABLE} --legend --show-details -t "${PROJECT_NAME} test coverage" -o ${COVERAGE_REPORT_DIR} ${COVERAGE_FILTERED_FILE}
DEPENDS ${COVERAGE_FILTERED_FILE}
COMMENT "Generating HTML coverage report in ${COVERAGE_REPORT_DIR}"
VERBATIM)
ADD_CUSTOM_TARGET(coverage-html
DEPENDS ${COVERAGE_REPORT_DIR})
ENDIF()
# xml coverage report
IF(GCOVR_FOUND)
MESSAGE(STATUS "Enabling XML coverage report")
# gcovr cannot write directly to a file so the execution needs to
# be wrapped in a cmake file that generates the file output
FILE(WRITE ${COVERAGE_XML_COMMAND_FILE}
"SET(ENV{LANG} en)\n")
FILE(APPEND ${COVERAGE_XML_COMMAND_FILE}
"EXECUTE_PROCESS(COMMAND \"${GCOVR_EXECUTABLE}\" -x -r \"${CMAKE_SOURCE_DIR}\" OUTPUT_FILE \"${COVERAGE_XML_FILE}\" WORKING_DIRECTORY \"${CMAKE_BINARY_DIR}\")\n")
ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_XML_FILE}
COMMAND ${CMAKE_COMMAND} ARGS -P ${COVERAGE_XML_COMMAND_FILE}
COMMENT "Generating coverage XML report"
VERBATIM)
ADD_CUSTOM_TARGET(coverage-xml
DEPENDS ${COVERAGE_XML_FILE})
ENDIF()
# provide a global coverage target executing both steps if available
SET(GLOBAL_DEPENDS "")
IF(LCOV_FOUND)
LIST(APPEND GLOBAL_DEPENDS ${COVERAGE_REPORT_DIR})
ENDIF()
IF(GCOVR_FOUND)
LIST(APPEND GLOBAL_DEPENDS ${COVERAGE_XML_FILE})
ENDIF()
IF(LCOV_FOUND OR GCOVR_FOUND)
ADD_CUSTOM_TARGET(coverage
DEPENDS ${GLOBAL_DEPENDS})
ENDIF()
ENDIF()
ENDFUNCTION()
telepathy-ofono-0.2+16.04.20151120/powerddbus.cpp 0000644 0000153 0000161 00000002435 12623675611 021714 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2014 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Andreas Pokorny
*/
#include "powerddbus.h"
#include
#include
#include
PowerDDBus::PowerDDBus()
: mPowerDIface{
new QDBusInterface(
"com.canonical.powerd",
"/com/canonical/powerd",
"com.canonical.powerd",
QDBusConnection::systemBus())}
{
}
void PowerDDBus::enableProximityHandling()
{
mPowerDIface->call("enableProximityHandling", "telepathy-ofono");
}
void PowerDDBus::disableProximityHandling()
{
mPowerDIface->call("disableProximityHandling", "telepathy-ofono");
}
telepathy-ofono-0.2+16.04.20151120/ussdiface.h 0000644 0000153 0000161 00000022206 12623675611 021147 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#ifndef OFONOUSSDIFACE_H
#define OFONOUSSDIFACE_H
// telepathy-qt
#include
#include
#include
#include
#include
class BaseConnectionUSSDInterface;
typedef Tp::SharedPtr BaseConnectionUSSDInterfacePtr;
#define TP_QT_IFACE_CONNECTION_USSD "com.canonical.Telephony.USSD"
class TP_QT_EXPORT BaseConnectionUSSDInterface : public Tp::AbstractConnectionInterface
{
Q_OBJECT
Q_DISABLE_COPY(BaseConnectionUSSDInterface)
public:
static BaseConnectionUSSDInterfacePtr create() {
return BaseConnectionUSSDInterfacePtr(new BaseConnectionUSSDInterface());
}
template
static Tp::SharedPtr create() {
return Tp::SharedPtr(
new BaseConnectionUSSDInterfaceSubclass());
}
QVariantMap immutableProperties() const;
virtual ~BaseConnectionUSSDInterface();
typedef Tp::Callback2 InitiateCallback;
void setInitiateCallback(const InitiateCallback &cb);
typedef Tp::Callback2 RespondCallback;
void setRespondCallback(const RespondCallback &cb);
typedef Tp::Callback1 CancelCallback;
void setCancelCallback(const CancelCallback &cb);
QString state() const;
QString serial() const;
public Q_SLOTS:
void NotificationReceived(const QString &message);
void RequestReceived(const QString &message);
void InitiateUSSDComplete(const QString &ussdResp);
void RespondComplete(bool success, const QString &ussdResp);
void BarringComplete(const QString &ssOp, const QString &cbService, const QVariantMap &cbMap);
void ForwardingComplete(const QString &ssOp, const QString &cfService, const QVariantMap &cfMap);
void WaitingComplete(const QString &ssOp, const QVariantMap &cwMap);
void CallingLinePresentationComplete(const QString &ssOp, const QString &status);
void ConnectedLinePresentationComplete(const QString &ssOp, const QString &status);
void CallingLineRestrictionComplete(const QString &ssOp, const QString &status);
void ConnectedLineRestrictionComplete(const QString &ssOp, const QString &status);
void InitiateFailed();
void StateChanged(const QString &state);
void setSerial(const QString& serial) const;
protected:
BaseConnectionUSSDInterface();
private:
void createAdaptor();
class Adaptee;
friend class Adaptee;
struct Private;
friend struct Private;
Private *mPriv;
};
class TP_QT_EXPORT ConnectionInterfaceUSSDAdaptor : public Tp::AbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", TP_QT_IFACE_CONNECTION_USSD)
Q_CLASSINFO("D-Bus Introspection", ""
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
"")
Q_PROPERTY(QString State READ State)
Q_PROPERTY(QString Serial READ Serial)
public:
ConnectionInterfaceUSSDAdaptor(const QDBusConnection& dbusConnection, QObject* adaptee, QObject* parent);
virtual ~ConnectionInterfaceUSSDAdaptor();
typedef Tp::MethodInvocationContextPtr< > InitiateContextPtr;
typedef Tp::MethodInvocationContextPtr< > RespondContextPtr;
typedef Tp::MethodInvocationContextPtr< > CancelContextPtr;
public Q_SLOTS: // METHODS
void Initiate(const QString &command, const QDBusMessage& dbusMessage);
void Respond(const QString &reply, const QDBusMessage& dbusMessage);
void Cancel(const QDBusMessage& dbusMessage);
QString State() const;
QString Serial() const;
Q_SIGNALS: // SIGNALS
void NotificationReceived(const QString &message);
void RequestReceived(const QString &message);
void InitiateUSSDComplete(const QString &ussdResp);
void RespondComplete(bool success, const QString &ussdResp);
void BarringComplete(const QString &ssOp, const QString &cbService, const QVariantMap &cbMap);
void ForwardingComplete(const QString &ssOp, const QString &cfService, const QVariantMap &cfMap);
void WaitingComplete(const QString &ssOp, const QVariantMap &cwMap);
void CallingLinePresentationComplete(const QString &ssOp, const QString &status);
void ConnectedLinePresentationComplete(const QString &ssOp, const QString &status);
void CallingLineRestrictionComplete(const QString &ssOp, const QString &status);
void ConnectedLineRestrictionComplete(const QString &ssOp, const QString &status);
void InitiateFailed();
void StateChanged(const QString &state);
};
class TP_QT_NO_EXPORT BaseConnectionUSSDInterface::Adaptee : public QObject
{
Q_OBJECT
Q_PROPERTY(QString state READ state)
Q_PROPERTY(QString serial READ serial)
public:
Adaptee(BaseConnectionUSSDInterface *interface);
~Adaptee();
QString state() const
{
return mInterface->state();
}
QString serial() const
{
return mInterface->serial();
}
private Q_SLOTS:
void initiate(const QString &command, const ConnectionInterfaceUSSDAdaptor::InitiateContextPtr &context);
void respond(const QString &reply, const ConnectionInterfaceUSSDAdaptor::RespondContextPtr &context);
void cancel(const ConnectionInterfaceUSSDAdaptor::CancelContextPtr &context);
Q_SIGNALS:
void notificationReceived(const QString &message);
void requestReceived(const QString &message);
void initiateUSSDComplete(const QString &ussdResp);
void barringComplete(const QString &ssOp, const QString &cbService, const QVariantMap &cbMap);
void forwardingComplete(const QString &ssOp, const QString &cfService, const QVariantMap &cfMap);
void waitingComplete(const QString &ssOp, const QVariantMap &cwMap);
void callingLinePresentationComplete(const QString &ssOp, const QString &status);
void connectedLinePresentationComplete(const QString &ssOp, const QString &status);
void callingLineRestrictionComplete(const QString &ssOp, const QString &status);
void connectedLineRestrictionComplete(const QString &ssOp, const QString &status);
void initiateFailed();
void respondComplete(bool success, const QString &response);
void stateChanged(const QString &state);
public:
BaseConnectionUSSDInterface *mInterface;
};
#endif
telepathy-ofono-0.2+16.04.20151120/mmsdmessage.h 0000644 0000153 0000161 00000002663 12623675611 021513 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#ifndef MMSDMESSAGE_H
#define MMSDMESSAGE_H
#include
#include
#include
#include
class MMSDMessage : public QObject
{
Q_OBJECT
public:
MMSDMessage(QString objectPath, QVariantMap properties, QObject *parent=0);
~MMSDMessage();
QVariantMap properties() const;
QString path() const;
void markRead() const;
// it should be called delete, but it is a reserved keyword in c++
void remove() const;
Q_SIGNALS:
void propertyChanged(const QString&, const QVariant&);
private Q_SLOTS:
void onPropertyChanged(const QString&, const QDBusVariant&);
private:
QVariantMap m_properties;
QString m_messagePath;
};
#endif
telepathy-ofono-0.2+16.04.20151120/ofono.manager 0000644 0000153 0000161 00000001060 12623675611 021477 0 ustar pbuser pbgroup 0000000 0000000 [ConnectionManager]
Name = ofono
BusName = org.freedesktop.Telepathy.ConnectionManager.ofono
ObjectPath = /org/freedesktop/Telepathy/ConnectionManager/ofono
[Protocol ofono]
param-modem-objpath=s
param-fakeEmergencyNumber=s
AddressableVCardFields=tel
AddressableURISchemes=tel
EnglishName=ofono
Interfaces=org.freedesktop.Telepathy.Protocol.Interface.Addressing;
ConnectionInterfaces=org.freedesktop.Telepathy.Connection.Interface.Requests;org.freedesktop.Telepathy.Connection.Interface.Contacts;org.freedesktop.Telepathy.Connection.Interface.SimplePresence;
telepathy-ofono-0.2+16.04.20151120/ofonoconferencecallchannel.cpp 0000644 0000153 0000161 00000030014 12623675611 025065 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#include "ofonoconferencecallchannel.h"
#ifdef USE_PULSEAUDIO
#include "qpulseaudioengine.h"
#endif
#include "ofonocallchannel.h"
oFonoConferenceCallChannel::oFonoConferenceCallChannel(oFonoConnection *conn, QObject *parent):
mRequestedHangup(false),
mConnection(conn),
mDtmfLock(false)
{
Q_FOREACH(oFonoCallChannel *channel, mConnection->callChannels().values()) {
if (channel->callState() == Tp::CallStateActive) {
QDBusObjectPath path(channel->baseChannel()->objectPath());
mCallChannels << path;
}
}
Tp::BaseChannelPtr baseChannel = Tp::BaseChannel::create(mConnection, TP_QT_IFACE_CHANNEL_TYPE_CALL);
Tp::BaseChannelCallTypePtr callType = Tp::BaseChannelCallType::create(baseChannel.data(),
true,
Tp::StreamTransportTypeUnknown,
true,
false, "","");
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(callType));
mHoldIface = Tp::BaseChannelHoldInterface::create();
mHoldIface->setSetHoldStateCallback(Tp::memFun(this,&oFonoConferenceCallChannel::onHoldStateChanged));
mMuteIface = Tp::BaseCallMuteInterface::create();
mMuteIface->setSetMuteStateCallback(Tp::memFun(this,&oFonoConferenceCallChannel::onMuteStateChanged));
mAudioOutputsIface = BaseChannelAudioOutputsInterface::create();
mAudioOutputsIface->setSetActiveAudioOutputCallback(Tp::memFun(this,&oFonoConferenceCallChannel::onSetActiveAudioOutput));
mConferenceIface = Tp::BaseChannelConferenceInterface::create(mCallChannels);
mMergeableIface = Tp::BaseChannelMergeableConferenceInterface::create();
mMergeableIface->setMergeCallback(Tp::memFun(this,&oFonoConferenceCallChannel::onMerge));
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mHoldIface));
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mMuteIface));
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mAudioOutputsIface));
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mConferenceIface));
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mMergeableIface));
mBaseChannel = baseChannel;
mCallChannel = Tp::BaseChannelCallTypePtr::dynamicCast(mBaseChannel->interface(TP_QT_IFACE_CHANNEL_TYPE_CALL));
mCallChannel->setHangupCallback(Tp::memFun(this,&oFonoConferenceCallChannel::onHangup));
Tp::CallStateReason reason;
QVariantMap stateDetails;
reason.actor = 0;
reason.reason = Tp::CallStateChangeReasonUserRequested;
reason.message = "";
reason.DBusReason = "";
mCallChannel->setCallState(Tp::CallStateActive, 0, reason, stateDetails);
// init must be called after initialization, otherwise we will have no object path registered.
QTimer::singleShot(0, this, SLOT(init()));
}
Tp::BaseChannelPtr oFonoConferenceCallChannel::baseChannel()
{
return mBaseChannel;
}
void oFonoConferenceCallChannel::onMerge(const QDBusObjectPath &channel, Tp::DBusError *error)
{
// on gsm we always merge all the existing calls
mConnection->voiceCallManager()->createMultiparty();
}
void oFonoConferenceCallChannel::onChannelMerged(const QDBusObjectPath &path)
{
if (!mCallChannels.contains(path)) {
mCallChannels << path;
mConferenceIface->mergeChannel(path, 0, QVariantMap());
}
}
void oFonoConferenceCallChannel::onChannelSplitted(const QDBusObjectPath &path)
{
if (mCallChannels.contains(path)) {
mCallChannels.removeAll(path);
mConferenceIface->removeChannel(path, QVariantMap());
}
if (mCallChannels.size() == 1) {
// remove the call channel from the conference before closing it.
mConferenceIface->removeChannel(mCallChannels.takeFirst(), QVariantMap());
Tp::CallStateReason reason;
QVariantMap stateDetails;
reason.actor = 0;
reason.reason = Tp::CallStateChangeReasonUserRequested;
reason.message = "";
reason.DBusReason = "";
mCallChannel->setCallState(Tp::CallStateEnded, 0, reason, stateDetails);
mBaseChannel->close();
}
}
void oFonoConferenceCallChannel::onSetActiveAudioOutput(const QString &id, Tp::DBusError *error)
{
#ifdef USE_PULSEAUDIO
// fallback to earpiece/headset
AudioMode mode = AudioModeWiredOrEarpiece;
if (id == "bluetooth") {
mode = AudioModeBluetooth;
} else if (id == "speaker") {
mode = AudioModeSpeaker;
}
QPulseAudioEngine::instance()->setCallMode(CallActive, mode);
#endif
}
void oFonoConferenceCallChannel::onHangup(uint reason, const QString &detailedReason, const QString &message, Tp::DBusError *error)
{
// TODO: use the parameters sent by telepathy
//mRequestedHangup = true;
mConnection->voiceCallManager()->hangupMultiparty();
//hangup();
}
void oFonoConferenceCallChannel::init()
{
QVariantMap stateDetails;
Tp::CallStateReason reason;
mObjPath = mBaseChannel->objectPath();
reason.actor = 0;
reason.reason = Tp::CallStateChangeReasonProgressMade;
reason.message = "";
reason.DBusReason = "";
mCallChannel->setCallState(Tp::CallStateActive, 0, reason, stateDetails);
mDTMFIface = Tp::BaseCallContentDTMFInterface::create();
mCallContent = Tp::BaseCallContent::create(baseChannel()->dbusConnection(), baseChannel().data(), "audio", Tp::MediaStreamTypeAudio, Tp::MediaStreamDirectionNone);
mDTMFIface = Tp::BaseCallContentDTMFInterface::create();
mCallContent->plugInterface(Tp::AbstractCallContentInterfacePtr::dynamicCast(mDTMFIface));
mCallChannel->addContent(mCallContent);
mDTMFIface->setStartToneCallback(Tp::memFun(this,&oFonoConferenceCallChannel::onDTMFStartTone));
mDTMFIface->setStopToneCallback(Tp::memFun(this,&oFonoConferenceCallChannel::onDTMFStopTone));
QObject::connect(mBaseChannel.data(), SIGNAL(closed()), this, SLOT(deleteLater()));
QObject::connect(mConnection->callVolume(), SIGNAL(mutedChanged(bool)), SLOT(onOfonoMuteChanged(bool)));
QObject::connect(mConnection, SIGNAL(activeAudioOutputChanged(QString)), mAudioOutputsIface.data(), SLOT(setActiveAudioOutput(QString)));
QObject::connect(mConnection, SIGNAL(audioOutputsChanged(AudioOutputList)), mAudioOutputsIface.data(), SLOT(setAudioOutputs(AudioOutputList)));
QObject::connect(mConnection->voiceCallManager(), SIGNAL(sendTonesComplete(bool)), SLOT(onDtmfComplete(bool)));
mAudioOutputsIface->setAudioOutputs(mConnection->audioOutputs());
mAudioOutputsIface->setActiveAudioOutput(mConnection->activeAudioOutput());
QObject::connect(mConnection, SIGNAL(channelMerged(const QDBusObjectPath&)), this, SLOT(onChannelMerged(const QDBusObjectPath&)));
QObject::connect(mConnection, SIGNAL(channelSplitted(const QDBusObjectPath&)), this, SLOT(onChannelSplitted(const QDBusObjectPath&)));
QObject::connect(mConnection, SIGNAL(channelHangup(const QDBusObjectPath&)), this, SLOT(onChannelSplitted(const QDBusObjectPath&)));
}
void oFonoConferenceCallChannel::onOfonoMuteChanged(bool mute)
{
Tp::LocalMuteState state = mute ? Tp::LocalMuteStateMuted : Tp::LocalMuteStateUnmuted;
mMuteIface->setMuteState(state);
}
void oFonoConferenceCallChannel::setConferenceActive(bool active)
{
if (active) {
mHoldIface->setHoldState(Tp::LocalHoldStateUnheld, Tp::LocalHoldStateReasonRequested);
} else {
mHoldIface->setHoldState(Tp::LocalHoldStateHeld, Tp::LocalHoldStateReasonRequested);
}
}
void oFonoConferenceCallChannel::onHoldStateChanged(const Tp::LocalHoldState &state, const Tp::LocalHoldStateReason &reason, Tp::DBusError *error)
{
if (state == Tp::LocalHoldStateHeld && mHoldIface->getHoldState() == Tp::LocalHoldStateUnheld) {
QObject::connect(mConnection->voiceCallManager(), SIGNAL(swapCallsComplete(bool)), this, SLOT(onSwapCallsComplete(bool)));
mHoldIface->setHoldState(Tp::LocalHoldStatePendingHold, Tp::LocalHoldStateReasonRequested);
mConnection->voiceCallManager()->swapCalls();
} else if (state == Tp::LocalHoldStateUnheld && mHoldIface->getHoldState() == Tp::LocalHoldStateHeld) {
QObject::connect(mConnection->voiceCallManager(), SIGNAL(swapCallsComplete(bool)), this, SLOT(onSwapCallsComplete(bool)));
mHoldIface->setHoldState(Tp::LocalHoldStatePendingUnhold, Tp::LocalHoldStateReasonRequested);
mConnection->voiceCallManager()->swapCalls();
}
}
void oFonoConferenceCallChannel::onSwapCallsComplete(bool success)
{
QObject::disconnect(mConnection->voiceCallManager(), SIGNAL(swapCallsComplete(bool)), this, SLOT(onSwapCallsComplete(bool)));
if (!success) {
// only change hold state in case of failure. Successful action will happen through setConferenceActive()
Tp::LocalHoldState holdState = mHoldIface->getHoldState() == Tp::LocalHoldStatePendingHold ? Tp::LocalHoldStateUnheld : Tp::LocalHoldStateHeld;
mHoldIface->setHoldState(holdState, Tp::LocalHoldStateReasonResourceNotAvailable);
}
}
void oFonoConferenceCallChannel::onMuteStateChanged(const Tp::LocalMuteState &state, Tp::DBusError *error)
{
if (state == Tp::LocalMuteStateMuted) {
mConnection->callVolume()->setMuted(true);
#ifdef USE_PULSEAUDIO
QPulseAudioEngine::instance()->setMicMute(true);
#endif
} else if (state == Tp::LocalMuteStateUnmuted) {
mConnection->callVolume()->setMuted(false);
#ifdef USE_PULSEAUDIO
QPulseAudioEngine::instance()->setMicMute(false);
#endif
}
}
void oFonoConferenceCallChannel::sendNextDtmf()
{
if (mDtmfLock) {
return;
}
if (!mDtmfPendingStrings.isEmpty()) {
mDtmfLock = true;
mConnection->voiceCallManager()->sendTones(mDtmfPendingStrings.front());
}
}
void oFonoConferenceCallChannel::onDtmfComplete(bool success)
{
// this might be a response for another channel
if (mCallChannel->callState() != Tp::CallStateActive) {
return;
}
mDtmfLock = false;
if (success) {
if (mDtmfPendingStrings.count() > 0) {
mDtmfPendingStrings.removeFirst();
}
if (mDtmfPendingStrings.isEmpty()) {
return;
}
sendNextDtmf();
} else {
QTimer::singleShot(1000, this, SLOT(sendNextDtmf()));
}
}
void oFonoConferenceCallChannel::onDTMFStartTone(uchar event, Tp::DBusError *error)
{
QString finalString;
if (event == 10) {
finalString = "*";
} else if (event == 11) {
finalString = "#";
} else {
finalString = QString::number(event);
}
qDebug() << "start tone" << finalString;
// we can't append to the first item in the queue as it is being sent and
// we dont know yet if it will succeed or not.
if (mDtmfPendingStrings.count() > 1) {
mDtmfPendingStrings[1] += finalString;
} else {
mDtmfPendingStrings << finalString;
}
sendNextDtmf();
}
void oFonoConferenceCallChannel::onDTMFStopTone(Tp::DBusError *error)
{
}
oFonoConferenceCallChannel::~oFonoConferenceCallChannel()
{
qDebug() << "conference call channel closed";
// TODO - for some reason the object is not being removed
mConnection->dbusConnection().unregisterObject(mObjPath, QDBusConnection::UnregisterTree);
}
telepathy-ofono-0.2+16.04.20151120/powerdaudiomodemediator.h 0000644 0000153 0000161 00000002707 12623675611 024121 0 ustar pbuser pbgroup 0000000 0000000 /****************************************************************************
**
** Copyright (C) 2014 Canonical, Ltd.
**
** Authors:
** Andreas Pokorny
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
****************************************************************************/
#ifndef POWERDAUDIOMODEMEDIATOR_H
#define POWERDAUDIOMODEMEDIATOR_H
#include "powerd.h"
#include
#include
#include
class PowerD;
/*!
* \brief PowerDAudioModeMediator is responsible for configuring proximity
* handling of powerd during different call states and used audio outputs.
* In General that mean enabling sreen blanking on proximity events, when
* a call is active and neither a bluetooth headset nor the speakers are used.
*/
class PowerDAudioModeMediator
{
public:
PowerDAudioModeMediator(PowerD &powerd);
void audioModeChanged(const QString &mode);
void audioOutputClosed();
private:
void apply() const;
PowerD &powerd;
bool mProximityEnabled{false};
};
#endif
telepathy-ofono-0.2+16.04.20151120/ofonocallchannel.h 0000644 0000153 0000161 00000006240 12623675611 022506 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#ifndef OFONOCALLCHANNEL_H
#define OFONOCALLCHANNEL_H
#include
#include
#include
#include
#include
#include
#include "connection.h"
#include "audiooutputsiface.h"
class oFonoConnection;
class oFonoCallChannel : public OfonoVoiceCall
{
Q_OBJECT
public:
oFonoCallChannel(oFonoConnection *conn, QString phoneNumber, uint targetHandle, QString voiceObj, QObject *parent = 0);
~oFonoCallChannel();
Tp::BaseChannelPtr baseChannel();
void onHangup(uint reason, const QString &detailedReason, const QString &message, Tp::DBusError* error);
void onAccept(Tp::DBusError*);
void onMuteStateChanged(const Tp::LocalMuteState &state, Tp::DBusError *error);
void onHoldStateChanged(const Tp::LocalHoldState &state, const Tp::LocalHoldStateReason &reason, Tp::DBusError *error);
void onDTMFStartTone(uchar event, Tp::DBusError *error);
void onDTMFStopTone(Tp::DBusError *error);
void onSetActiveAudioOutput(const QString &id, Tp::DBusError *error);
void onSplit(Tp::DBusError *error);
Tp::CallState callState();
Q_SIGNALS:
void splitted();
void merged();
void closed();
void multipartyCallHeld();
void multipartyCallActive();
private Q_SLOTS:
void onOfonoCallStateChanged(const QString &state);
void onDtmfComplete(bool success);
void onSwapCallsComplete(bool success);
void sendNextDtmf();
void init();
void onAnswerComplete(bool success);
void onHangupComplete(bool success);
void onOfonoMuteChanged(bool mute);
void onMultipartyChanged(bool multiparty);
void onDisconnectReason(const QString &reason);
private:
QString mObjPath;
QString mPreviousState;
#ifdef USE_PULSEAUDIO
bool mHasPulseAudio;
#endif
bool mIncoming;
bool mRequestedHangup;
Tp::BaseChannelPtr mBaseChannel;
QString mPhoneNumber;
oFonoConnection *mConnection;
uint mTargetHandle;
Tp::BaseChannelHoldInterfacePtr mHoldIface;
Tp::BaseChannelSplittableInterfacePtr mSplittableIface;
Tp::BaseCallMuteInterfacePtr mMuteIface;
BaseChannelAudioOutputsInterfacePtr mAudioOutputsIface;
Tp::BaseChannelCallTypePtr mCallChannel;
Tp::BaseCallContentDTMFInterfacePtr mDTMFIface;
Tp::BaseCallContentPtr mCallContent;
bool mDtmfLock;
QStringList mDtmfPendingStrings;
bool mMultiparty;
};
#endif // OFONOCALLCHANNEL_H
telepathy-ofono-0.2+16.04.20151120/emergencymodeiface.h 0000644 0000153 0000161 00000011077 12623675611 023020 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
* Gustavo Pichorim Boiko
*/
#ifndef OFONOEMERGENCYMODEIFACE_H
#define OFONOEMERGENCYMODEIFACE_H
// telepathy-qt
#include
#include
#include
#include
#include
class BaseConnectionEmergencyModeInterface;
typedef Tp::SharedPtr BaseConnectionEmergencyModeInterfacePtr;
#define TP_QT_IFACE_CONNECTION_EMERGENCYMODE "com.canonical.Telephony.EmergencyMode"
class TP_QT_EXPORT BaseConnectionEmergencyModeInterface : public Tp::AbstractConnectionInterface
{
Q_OBJECT
Q_DISABLE_COPY(BaseConnectionEmergencyModeInterface)
public:
static BaseConnectionEmergencyModeInterfacePtr create() {
return BaseConnectionEmergencyModeInterfacePtr(new BaseConnectionEmergencyModeInterface());
}
template
static Tp::SharedPtr create() {
return Tp::SharedPtr(
new BaseConnectionEmergencyModeInterfaceSubclass());
}
QVariantMap immutableProperties() const;
virtual ~BaseConnectionEmergencyModeInterface();
typedef Tp::Callback1 EmergencyNumbersCallback;
void setEmergencyNumbersCallback(const EmergencyNumbersCallback &cb);
void setFakeEmergencyNumber(const QString &fakeEmergencyNumber);
public Q_SLOTS:
void setEmergencyNumbers(const QStringList &numbers);
void setCountryCode(const QString &countryCode);
protected:
BaseConnectionEmergencyModeInterface();
private:
void createAdaptor();
class Adaptee;
friend class Adaptee;
struct Private;
friend struct Private;
Private *mPriv;
};
class TP_QT_EXPORT ConnectionInterfaceEmergencyModeAdaptor : public Tp::AbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", TP_QT_IFACE_CONNECTION_EMERGENCYMODE)
Q_CLASSINFO("D-Bus Introspection", ""
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
"")
public:
ConnectionInterfaceEmergencyModeAdaptor(const QDBusConnection& dbusConnection, QObject* adaptee, QObject* parent);
virtual ~ConnectionInterfaceEmergencyModeAdaptor();
typedef Tp::MethodInvocationContextPtr< QStringList > EmergencyNumbersContextPtr;
typedef Tp::MethodInvocationContextPtr< QString > CountryCodeContextPtr;
public Q_SLOTS: // METHODS
QStringList EmergencyNumbers(const QDBusMessage& dbusMessage);
QString CountryCode(const QDBusMessage& dbusMessage);
Q_SIGNALS: // SIGNALS
void EmergencyNumbersChanged(const QStringList &numbers);
void CountryCodeChanged(const QString &countryCode);
};
class TP_QT_NO_EXPORT BaseConnectionEmergencyModeInterface::Adaptee : public QObject
{
Q_OBJECT
public:
Adaptee(BaseConnectionEmergencyModeInterface *interface);
~Adaptee();
private Q_SLOTS:
void emergencyNumbers(const ConnectionInterfaceEmergencyModeAdaptor::EmergencyNumbersContextPtr &context);
void countryCode(const ConnectionInterfaceEmergencyModeAdaptor::CountryCodeContextPtr &context);
Q_SIGNALS:
void emergencyNumbersChanged(const QStringList &numbers);
void countryCodeChanged(const QString &countryCode);
public:
BaseConnectionEmergencyModeInterface *mInterface;
};
#endif
telepathy-ofono-0.2+16.04.20151120/update_qrc.sh 0000755 0000153 0000161 00000000573 12623675611 021521 0 ustar pbuser pbgroup 0000000 0000000 #!/bin/sh
QRC_FILE=$1
FILES=`ls schema/*.sql schema/*.info`
# clear the file
if [ -e $QRC_FILE ]; then
rm -f $QRC_FILE
fi
# and print the contents
echo '' >> $QRC_FILE
echo ' ' >> $QRC_FILE
for file in $FILES; do
echo " $file" >> $QRC_FILE
done
echo ' ' >> $QRC_FILE
echo '' >> $QRC_FILE
telepathy-ofono-0.2+16.04.20151120/mmsdmanager.h 0000644 0000153 0000161 00000002514 12623675611 021474 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#ifndef MMSDMANAGER_H
#define MMSDMANAGER_H
#include
#include
#include
#include
class MMSDManager : public QObject
{
Q_OBJECT
public:
MMSDManager(QObject *parent=0);
~MMSDManager();
QStringList services() const;
Q_SIGNALS:
void serviceAdded(const QString &servicePath);
void serviceRemoved(const QString &servicePath);
private Q_SLOTS:
void onServiceAdded(const QDBusObjectPath &path, const QVariantMap &properties);
void onServiceRemoved(const QDBusObjectPath &path);
private:
QStringList m_services;
};
#endif
telepathy-ofono-0.2+16.04.20151120/COPYING.LGPL 0000644 0000153 0000161 00000016743 12623675611 020631 0 ustar pbuser pbgroup 0000000 0000000 GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
telepathy-ofono-0.2+16.04.20151120/ofonotextchannel.cpp 0000644 0000153 0000161 00000047760 12623675617 023134 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
// ofono-qt
#include
// telepathy-ofono
#include "ofonotextchannel.h"
#include "pendingmessagesmanager.h"
QDBusArgument &operator<<(QDBusArgument&argument, const IncomingAttachmentStruct &attachment)
{
argument.beginStructure();
argument << attachment.id << attachment.contentType << attachment.filePath << attachment.offset << attachment.length;
argument.endStructure();
return argument;
}
const QDBusArgument &operator>>(const QDBusArgument &argument, IncomingAttachmentStruct &attachment)
{
argument.beginStructure();
argument >> attachment.id >> attachment.contentType >> attachment.filePath >> attachment.offset >> attachment.length;
argument.endStructure();
return argument;
}
oFonoTextChannel::oFonoTextChannel(oFonoConnection *conn, QStringList phoneNumbers, bool flash, QObject *parent):
QObject(parent),
mConnection(conn),
mPhoneNumbers(phoneNumbers),
mFlash(flash),
mMessageCounter(1)
{
qDBusRegisterMetaType();
qDBusRegisterMetaType();
Tp::BaseChannelPtr baseChannel;
if (phoneNumbers.size() == 1) {
baseChannel = Tp::BaseChannel::create(mConnection,
TP_QT_IFACE_CHANNEL_TYPE_TEXT,
Tp::HandleTypeContact,
mConnection->ensureHandle(mPhoneNumbers[0]));
} else {
baseChannel = Tp::BaseChannel::create(mConnection,
TP_QT_IFACE_CHANNEL_TYPE_TEXT);
}
Tp::BaseChannelTextTypePtr textType = Tp::BaseChannelTextType::create(baseChannel.data());
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(textType));
QStringList supportedContentTypes = QStringList() << "text/plain";
Tp::UIntList messageTypes = Tp::UIntList() <<
Tp::ChannelTextMessageTypeNormal <<
Tp::ChannelTextMessageTypeDeliveryReport;
uint messagePartSupportFlags = 0;
uint deliveryReportingSupport = Tp::DeliveryReportingSupportFlagReceiveSuccesses;
mMessagesIface = Tp::BaseChannelMessagesInterface::create(textType.data(),
supportedContentTypes,
messageTypes,
messagePartSupportFlags,
deliveryReportingSupport);
mMessagesIface->setSendMessageCallback(Tp::memFun(this,&oFonoTextChannel::sendMessage));
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mMessagesIface));
mGroupIface = Tp::BaseChannelGroupInterface::create(Tp::ChannelGroupFlagCanAdd, conn->selfHandle());
mGroupIface->setAddMembersCallback(Tp::memFun(this,&oFonoTextChannel::onAddMembers));
mGroupIface->setRemoveMembersCallback(Tp::memFun(this,&oFonoTextChannel::onRemoveMembers));
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mGroupIface));
addMembers(phoneNumbers);
mSMSIface = Tp::BaseChannelSMSInterface::create(flash, true);
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mSMSIface));
mBaseChannel = baseChannel;
mTextChannel = Tp::BaseChannelTextTypePtr::dynamicCast(mBaseChannel->interface(TP_QT_IFACE_CHANNEL_TYPE_TEXT));
mTextChannel->setMessageAcknowledgedCallback(Tp::memFun(this,&oFonoTextChannel::messageAcknowledged));
QObject::connect(mBaseChannel.data(), SIGNAL(closed()), this, SLOT(deleteLater()));
}
void oFonoTextChannel::onAddMembers(const Tp::UIntList& handles, const QString& message, Tp::DBusError* error)
{
addMembers(mConnection->inspectHandles(Tp::HandleTypeContact, handles, error));
}
void oFonoTextChannel::onRemoveMembers(const Tp::UIntList& handles, const QString& message, Tp::DBusError* error)
{
Q_FOREACH(uint handle, handles) {
Q_FOREACH(const QString &phoneNumber, mConnection->inspectHandles(Tp::HandleTypeContact, Tp::UIntList() << handle, error)) {
mPhoneNumbers.removeAll(phoneNumber);
}
mMembers.removeAll(handle);
}
mGroupIface->removeMembers(handles);
}
void oFonoTextChannel::addMembers(QStringList phoneNumbers)
{
Tp::UIntList handles;
Q_FOREACH(const QString &phoneNumber, phoneNumbers) {
uint handle = mConnection->ensureHandle(phoneNumber);
handles << handle;
if (!mPhoneNumbers.contains(phoneNumber)) {
mPhoneNumbers << phoneNumber;
}
if (!mMembers.contains(handle)) {
mMembers << handle;
}
}
mGroupIface->addMembers(handles, phoneNumbers);
}
Tp::UIntList oFonoTextChannel::members()
{
return mMembers;
}
oFonoTextChannel::~oFonoTextChannel()
{
Q_FOREACH(const QStringList &fileList, mFilesToRemove) {
Q_FOREACH(const QString& file, fileList) {
QFile::remove(file);
}
}
}
Tp::BaseChannelPtr oFonoTextChannel::baseChannel()
{
return mBaseChannel;
}
void oFonoTextChannel::sendDeliveryReport(const QString &messageId, uint handle, Tp::DeliveryStatus status)
{
Tp::MessagePartList partList;
Tp::MessagePart header;
header["message-sender"] = QDBusVariant(handle);
header["message-sender-id"] = QDBusVariant(mPhoneNumbers[0]);
header["message-type"] = QDBusVariant(Tp::ChannelTextMessageTypeDeliveryReport);
header["delivery-status"] = QDBusVariant(status);
header["delivery-token"] = QDBusVariant(messageId);
partList << header;
mTextChannel->addReceivedMessage(partList);
}
void oFonoTextChannel::deliveryReportReceived(const QString &messageId, uint handle, bool success)
{
sendDeliveryReport(messageId, handle, success ? Tp::DeliveryStatusDelivered : Tp::DeliveryStatusPermanentlyFailed);
}
void oFonoTextChannel::messageAcknowledged(const QString &id)
{
Q_EMIT messageRead(id);
}
QString oFonoTextChannel::sendMessage(Tp::MessagePartList message, uint flags, Tp::DBusError* error)
{
bool success = true;
Tp::MessagePart header = message.at(0);
Tp::MessagePart body = message.at(1);
QString objpath;
bool mms = header["x-canonical-mms"].variant().toBool();
if (mms) {
// pop header out
message.removeFirst();
OutgoingAttachmentList attachments;
// FIXME group chat
QString phoneNumber = mPhoneNumbers[0];
uint handle = mConnection->ensureHandle(phoneNumber);
QStringList temporaryFiles;
Q_FOREACH(const Tp::MessagePart &part, message) {
OutgoingAttachmentStruct attachment;
attachment.id = part["identifier"].variant().toString();
attachment.contentType = part["content-type"].variant().toString();
QString attachmentsPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/telepathy-ofono/attachments";
if (!QDir().exists(attachmentsPath) && !QDir().mkpath(attachmentsPath)) {
qCritical() << "Failed to create attachments directory";
objpath = QDateTime::currentDateTimeUtc().toString(Qt::ISODate) + "-" + QString::number(mMessageCounter++);
error->set(TP_QT_ERROR_INVALID_ARGUMENT, "Failed to create attachments to disk");
mPendingDeliveryReportPermanentlyFailed[objpath] = handle;
QTimer::singleShot(0, this, SLOT(onProcessPendingDeliveryReport()));
return objpath;
}
QTemporaryFile file(attachmentsPath + "/attachmentXXXXXX");
file.setAutoRemove(false);
if (!file.open()) {
Q_FOREACH(const QString& file, temporaryFiles) {
QFile::remove(file);
}
objpath = QDateTime::currentDateTimeUtc().toString(Qt::ISODate) + "-" + QString::number(mMessageCounter++);
error->set(TP_QT_ERROR_INVALID_ARGUMENT, "Failed to create attachments to disk");
mPendingDeliveryReportPermanentlyFailed[objpath] = handle;
QTimer::singleShot(0, this, SLOT(onProcessPendingDeliveryReport()));
return objpath;
}
temporaryFiles << file.fileName();
file.write(part["content"].variant().toByteArray());
file.close();
attachment.filePath = file.fileName();
attachments << attachment;
}
objpath = mConnection->sendMMS(mPhoneNumbers, attachments).path();
if (objpath.isEmpty()) {
Q_FOREACH(const QString& file, temporaryFiles) {
QFile::remove(file);
}
// give a temporary id for this message
objpath = QDateTime::currentDateTimeUtc().toString(Qt::ISODate) + "-" + QString::number(mMessageCounter++);
// TODO: get error message from nuntium
error->set(TP_QT_ERROR_INVALID_ARGUMENT, "Failed to send MMS");
mPendingDeliveryReportPermanentlyFailed[objpath] = handle;
QTimer::singleShot(0, this, SLOT(onProcessPendingDeliveryReport()));
return objpath;
}
MMSDMessage *msg = new MMSDMessage(objpath, QVariantMap(), this);
QObject::connect(msg, SIGNAL(propertyChanged(QString,QVariant)), SLOT(onMMSPropertyChanged(QString,QVariant)));
mPendingDeliveryReportUnknown[objpath] = handle;
QTimer::singleShot(0, this, SLOT(onProcessPendingDeliveryReport()));
if (temporaryFiles.size() > 0) {
mFilesToRemove[objpath] = temporaryFiles;
}
return objpath;
}
if (mPhoneNumbers.size() == 1) {
QString phoneNumber = mPhoneNumbers[0];
uint handle = mConnection->ensureHandle(phoneNumber);
objpath = mConnection->messageManager()->sendMessage(phoneNumber, body["content"].variant().toString(), success).path();
if (objpath.isEmpty() || !success) {
if (!success) {
qWarning() << mConnection->messageManager()->errorName() << mConnection->messageManager()->errorMessage();
} else {
error->set(TP_QT_ERROR_INVALID_ARGUMENT, mConnection->messageManager()->errorMessage());
}
// create an unique id for this message that ofono failed to send
objpath = QDateTime::currentDateTimeUtc().toString(Qt::ISODate) + "-" + QString::number(mMessageCounter++);
mPendingDeliveryReportPermanentlyFailed[objpath] = handle;
QTimer::singleShot(0, this, SLOT(onProcessPendingDeliveryReport()));
return objpath;
}
OfonoMessage *msg = new OfonoMessage(objpath);
if (msg->state() == "") {
// message was already sent or failed too fast (this case is only reproducible with the emulator)
msg->deleteLater();
mPendingDeliveryReportUnknown[objpath] = handle;
QTimer::singleShot(0, this, SLOT(onProcessPendingDeliveryReport()));
return objpath;
}
// FIXME: track pending messages only if delivery reports are enabled. We need a system config option for it.
PendingMessagesManager::instance()->addPendingMessage(objpath, mPhoneNumbers[0]);
QObject::connect(msg, SIGNAL(stateChanged(QString)), SLOT(onOfonoMessageStateChanged(QString)));
return objpath;
} else {
bool someMessageSent = false;
QString lastPhoneNumber;
Q_FOREACH(const QString &phoneNumber, mPhoneNumbers) {
uint handle = mConnection->ensureHandle(mPhoneNumbers[0]);
objpath = mConnection->messageManager()->sendMessage(phoneNumber, body["content"].variant().toString(), success).path();
lastPhoneNumber = phoneNumber;
// dont fail if this is a group chat as we cannot track individual messages
if (objpath.isEmpty() || !success) {
if (!success) {
qWarning() << mConnection->messageManager()->errorName() << mConnection->messageManager()->errorMessage();
} else {
error->set(TP_QT_ERROR_INVALID_ARGUMENT, mConnection->messageManager()->errorMessage());
}
continue;
}
someMessageSent = true;
}
if (!someMessageSent) {
// for group chat we only fail if all the messages failed to send
objpath = QDateTime::currentDateTimeUtc().toString(Qt::ISODate) + "-" + QString::number(mMessageCounter++);
uint handle = mConnection->ensureHandle(lastPhoneNumber);
mPendingDeliveryReportPermanentlyFailed[objpath] = handle;
QTimer::singleShot(0, this, SLOT(onProcessPendingDeliveryReport()));
return objpath;
}
OfonoMessage *msg = new OfonoMessage(objpath);
if (msg->state() == "") {
// message was already sent or failed too fast (this case is only reproducible with the emulator)
msg->deleteLater();
uint handle = mConnection->ensureHandle(lastPhoneNumber);
mPendingDeliveryReportUnknown[objpath] = handle;
QTimer::singleShot(0, this, SLOT(onProcessPendingDeliveryReport()));
// return only the last one in case of group chat for history purposes
return objpath;
}
QObject::connect(msg, SIGNAL(stateChanged(QString)), SLOT(onOfonoMessageStateChanged(QString)));
return objpath;
}
}
void oFonoTextChannel::onMMSPropertyChanged(QString property, QVariant value)
{
qDebug() << "oFonoTextChannel::onMMSPropertyChanged" << property << value;
MMSDMessage *msg = qobject_cast(sender());
// FIXME - mms groupchat
uint handle = mConnection->ensureHandle(mPhoneNumbers[0]);
if (!msg) {
return;
}
if (property == "Status") {
Tp::DeliveryStatus status = Tp::DeliveryStatusUnknown;
if (value == "Sent") {
status = Tp::DeliveryStatusAccepted;
} else if (value == "TransientError" || value == "PermanentError") {
// transient error in telepathy means it is still trying, so we need to
// set a permanent error here so the user can retry
status = Tp::DeliveryStatusPermanentlyFailed;
} else if (value == "draft") {
// while it is draft we dont actually send a delivery report
return;
}
Q_FOREACH(const QString& file, mFilesToRemove[msg->path()]) {
QFile::remove(file);
}
mFilesToRemove.remove(msg->path());
sendDeliveryReport(msg->path(), handle, status);
}
}
void oFonoTextChannel::onProcessPendingDeliveryReport()
{
QMapIterator iterator(mPendingDeliveryReportPermanentlyFailed);
while(iterator.hasNext()) {
iterator.next();
sendDeliveryReport(iterator.key(), iterator.value(), Tp::DeliveryStatusPermanentlyFailed);
}
iterator = mPendingDeliveryReportDelivered;
while(iterator.hasNext()) {
iterator.next();
sendDeliveryReport(iterator.key(), iterator.value(), Tp::DeliveryStatusDelivered);
}
iterator = mPendingDeliveryReportAccepted;
while(iterator.hasNext()) {
iterator.next();
sendDeliveryReport(iterator.key(), iterator.value(), Tp::DeliveryStatusAccepted);
}
iterator = mPendingDeliveryReportTemporarilyFailed;
while(iterator.hasNext()) {
iterator.next();
sendDeliveryReport(iterator.key(), iterator.value(), Tp::DeliveryStatusTemporarilyFailed);
}
iterator = mPendingDeliveryReportUnknown;
while(iterator.hasNext()) {
iterator.next();
sendDeliveryReport(iterator.key(), iterator.value(), Tp::DeliveryStatusUnknown);
}
mPendingDeliveryReportTemporarilyFailed.clear();
mPendingDeliveryReportPermanentlyFailed.clear();
mPendingDeliveryReportDelivered.clear();
mPendingDeliveryReportAccepted.clear();
mPendingDeliveryReportUnknown.clear();
}
void oFonoTextChannel::onOfonoMessageStateChanged(QString status)
{
OfonoMessage *msg = static_cast(sender());
if(msg) {
Tp::DeliveryStatus delivery_status;
if (status == "sent") {
delivery_status = Tp::DeliveryStatusAccepted;
msg->deleteLater();
} else if(status == "failed") {
delivery_status = Tp::DeliveryStatusPermanentlyFailed;
PendingMessagesManager::instance()->removePendingMessage(msg->path());
msg->deleteLater();
} else if(status == "pending") {
delivery_status = Tp::DeliveryStatusTemporarilyFailed;
} else {
delivery_status = Tp::DeliveryStatusUnknown;
}
sendDeliveryReport(msg->path(), mConnection->ensureHandle(mPhoneNumbers[0]), delivery_status);
}
}
void oFonoTextChannel::messageReceived(const QString &message, uint handle, const QVariantMap &info)
{
Tp::MessagePartList partList;
Tp::MessagePart body;
body["content-type"] = QDBusVariant("text/plain");
body["content"] = QDBusVariant(message);
Tp::MessagePart header;
header["message-token"] = QDBusVariant(info["SentTime"].toString() +"-" + QString::number(mMessageCounter++));
header["message-received"] = QDBusVariant(QDateTime::currentDateTime().toTime_t());
header["message-sender"] = QDBusVariant(handle);
header["message-sender-id"] = QDBusVariant(mPhoneNumbers[0]);
header["message-type"] = QDBusVariant(Tp::ChannelTextMessageTypeNormal);
partList << header << body;
mTextChannel->addReceivedMessage(partList);
}
void oFonoTextChannel::mmsReceived(const QString &id, uint handle, const QVariantMap &properties)
{
Tp::MessagePartList message;
QString subject = properties["Subject"].toString();
QString smil = properties["Smil"].toString();
Tp::MessagePart header;
header["message-token"] = QDBusVariant(id);
header["message-sender"] = QDBusVariant(handle);
header["message-received"] = QDBusVariant(QDateTime::currentDateTimeUtc().toTime_t());
header["message-type"] = QDBusVariant(Tp::DeliveryStatusDelivered);
header["x-canonical-mms"] = QDBusVariant(true);
if (!subject.isEmpty())
{
header["subject"] = QDBusVariant(subject);
}
message << header;
IncomingAttachmentList mmsdAttachments = qdbus_cast(properties["Attachments"]);
Q_FOREACH(const IncomingAttachmentStruct &attachment, mmsdAttachments) {
QFile attachmentFile(attachment.filePath);
if (!attachmentFile.open(QIODevice::ReadOnly)) {
qWarning() << "fail to load attachment" << attachmentFile.errorString() << attachment.filePath;
continue;
}
// FIXME check if we managed to read the total attachment file
attachmentFile.seek(attachment.offset);
QByteArray fileData = attachmentFile.read(attachment.length);
Tp::MessagePart part;
part["content-type"] = QDBusVariant(attachment.contentType);
part["identifier"] = QDBusVariant(attachment.id);
part["content"] = QDBusVariant(fileData);
part["size"] = QDBusVariant(attachment.length);
message << part;
}
if (!smil.isEmpty()) {
Tp::MessagePart part;
part["content-type"] = QDBusVariant(QString("application/smil"));
part["identifier"] = QDBusVariant(QString("smil"));
part["content"] = QDBusVariant(smil);
part["size"] = QDBusVariant(smil.size());
message << part;
}
mTextChannel->addReceivedMessage(message);
}
telepathy-ofono-0.2+16.04.20151120/tools/ 0000755 0000153 0000161 00000000000 12623676450 020170 5 ustar pbuser pbgroup 0000000 0000000 telepathy-ofono-0.2+16.04.20151120/tools/generate_country_codes.py 0000644 0000153 0000161 00000001256 12623675611 025276 0 ustar pbuser pbgroup 0000000 0000000 # originally available at https://github.com/musalbas/mcc-mnc-table/blob/master/get-mcc-mnc-table-csv.py
import re
import urllib2
html = urllib2.urlopen('http://mcc-mnc.com/').read()
td_re = re.compile('
([^<]*)
'*6)
codes = {}
tbody_start = False
for line in html.split('\n'):
if '' in line:
tbody_start = True
elif '' in line:
break
elif tbody_start:
td_search = td_re.search(line)
mcc = int(td_search.group(1))
isoCountryCode = td_search.group(3).upper()
if (len(isoCountryCode) != 2):
continue
codes[mcc] = isoCountryCode
for mcc in codes:
print str(mcc) + ":" + codes[mcc]
telepathy-ofono-0.2+16.04.20151120/mmsdservice.h 0000644 0000153 0000161 00000003337 12623675611 021526 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#ifndef MMSDSERVICE_H
#define MMSDSERVICE_H
#include
#include
#include
#include
#include "dbustypes.h"
#include "connection.h"
#include "mmsdmessage.h"
class MMSDService : public QObject
{
Q_OBJECT
public:
MMSDService(QString objectPath, oFonoConnection *connection, QObject *parent=0);
~MMSDService();
QVariantMap properties() const;
MessageList messages() const;
QString path() const;
QString modemObjectPath() const;
QDBusObjectPath sendMessage(QStringList recipients, OutgoingAttachmentList attachments);
Q_SIGNALS:
void messageAdded(const QString &messagePath, const QVariantMap &properties);
void messageRemoved(const QString &messagePath);
private Q_SLOTS:
void onMessageAdded(const QDBusObjectPath &path, const QVariantMap &properties);
void onMessageRemoved(const QDBusObjectPath &path);
private:
QVariantMap m_properties;
QString m_servicePath;
MessageList m_messages;
};
#endif
telepathy-ofono-0.2+16.04.20151120/countrycodes.qrc 0000644 0000153 0000161 00000000137 12623675611 022257 0 ustar pbuser pbgroup 0000000 0000000 countrycodes.txt
telepathy-ofono-0.2+16.04.20151120/voicemailiface.h 0000644 0000153 0000161 00000012331 12623675611 022137 0 ustar pbuser pbgroup 0000000 0000000 /**
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, 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 program. If not, see .
*
* Authors: Tiago Salem Herrmann
*/
#ifndef OFONOVOICEMAILIFACE_H
#define OFONOVOICEMAILIFACE_H
// telepathy-qt
#include
#include
#include
#include
#include
class BaseConnectionVoicemailInterface;
typedef Tp::SharedPtr BaseConnectionVoicemailInterfacePtr;
#define TP_QT_IFACE_CONNECTION_VOICEMAIL "com.canonical.Telephony.Voicemail"
class TP_QT_EXPORT BaseConnectionVoicemailInterface : public Tp::AbstractConnectionInterface
{
Q_OBJECT
Q_DISABLE_COPY(BaseConnectionVoicemailInterface)
public:
static BaseConnectionVoicemailInterfacePtr create() {
return BaseConnectionVoicemailInterfacePtr(new BaseConnectionVoicemailInterface());
}
template