Commit 6ad0780e authored by Emmanuel Lepage Vallee's avatar Emmanuel Lepage Vallee

Merge presence refactoring branch

parents c0e570cd c2f1bed0
../../../src/dbus/callmanager-introspec.xml
\ No newline at end of file
../../../src/client/dbus/callmanager-introspec.xml
\ No newline at end of file
../../../src/dbus/configurationmanager-introspec.xml
\ No newline at end of file
../../../src/client/dbus/configurationmanager-introspec.xml
\ No newline at end of file
../../../src/dbus/instance-introspec.xml
\ No newline at end of file
../../../src/client/dbus/instance-introspec.xml
\ No newline at end of file
../../../src/client/dbus/presencemanager-introspec.xml
\ No newline at end of file
......@@ -45,27 +45,28 @@
#include "client/configurationmanager.h"
const char * const Account::AUDIO_CODECS_KEY = "audioCodecs"; // 0/9/110/111/112/
const char * const Account::VIDEO_CODECS_KEY = "videoCodecs";
const char * const Account::VIDEO_CODEC_ENABLED = "enabled";
const char * const Account::VIDEO_CODEC_NAME = "name";
const char * const Account::VIDEO_CODEC_PARAMETERS ="parameters";
const char * const Account::VIDEO_CODEC_BITRATE = "bitrate";
const char * const Account::RINGTONE_PATH_KEY = "ringtonePath";
const char * const Account::RINGTONE_ENABLED_KEY = "ringtoneEnabled";
const char * const Account::DISPLAY_NAME_KEY = "displayName";
const char * const Account::ALIAS_KEY = "alias";
const char * const Account::TYPE_KEY = "type";
const char * const Account::ID_KEY = "id";
const char * const Account::USERNAME_KEY = "username";
const char * const Account::AUDIO_CODECS_KEY = "audioCodecs"; // 0/9/110/111/112/
const char * const Account::VIDEO_CODECS_KEY = "videoCodecs";
const char * const Account::VIDEO_CODEC_ENABLED = "enabled";
const char * const Account::VIDEO_CODEC_NAME = "name";
const char * const Account::VIDEO_CODEC_PARAMETERS = "parameters";
const char * const Account::VIDEO_CODEC_BITRATE = "bitrate";
const char * const Account::RINGTONE_PATH_KEY = "ringtonePath";
const char * const Account::RINGTONE_ENABLED_KEY = "ringtoneEnabled";
const char * const Account::DISPLAY_NAME_KEY = "displayName";
const char * const Account::ALIAS_KEY = "alias";
const char * const Account::TYPE_KEY = "type";
const char * const Account::ID_KEY = "id";
const char * const Account::USERNAME_KEY = "username";
const char * const Account::AUTHENTICATION_USERNAME_KEY = "authenticationUsername";
const char * const Account::PASSWORD_KEY = "password";
const char * const Account::HOSTNAME_KEY = "hostname";
const char * const Account::ACCOUNT_ENABLE_KEY = "enable";
const char * const Account::ACCOUNT_AUTOANSWER_KEY = "autoAnswer";
const char * const Account::MAILBOX_KEY = "mailbox";
const char * const Account::DEFAULT_USER_AGENT = "SFLphone/" PACKAGE_VERSION;
const char * const Account::USER_AGENT_KEY = "useragent";
const char * const Account::PASSWORD_KEY = "password";
const char * const Account::HOSTNAME_KEY = "hostname";
const char * const Account::ACCOUNT_ENABLE_KEY = "enable";
const char * const Account::ACCOUNT_AUTOANSWER_KEY = "autoAnswer";
const char * const Account::MAILBOX_KEY = "mailbox";
const char * const Account::DEFAULT_USER_AGENT = "SFLphone/" PACKAGE_VERSION;
const char * const Account::USER_AGENT_KEY = "useragent";
const char * const Account::PRESENCE_MODULE_ENABLED_KEY = "presenceModuleEnabled";
using std::map;
using std::string;
......
......@@ -224,6 +224,7 @@ class Account : public Serializable {
static const char * const MAILBOX_KEY;
static const char * const USER_AGENT_KEY;
static const char * const DEFAULT_USER_AGENT;
static const char * const PRESENCE_MODULE_ENABLED_KEY;
static std::string mapStateNumberToString(RegistrationState state);
......
......@@ -55,10 +55,12 @@ static const char *const CONFIG_ACCOUNT_DTMF_TYPE = "Account.dtmfT
static const char *const CONFIG_RINGTONE_PATH = "Account.ringtonePath";
static const char *const CONFIG_RINGTONE_ENABLED = "Account.ringtoneEnabled";
static const char *const CONFIG_KEEP_ALIVE_ENABLED = "Account.keepAliveEnabled";
static const char *const CONFIG_PRESENCE_ENABLED = "Account.presenceModuleEnabled";
static const char *const CONFIG_DEFAULT_REGISTRATION_EXPIRE = "60";
static const char *const CONFIG_DEFAULT_RINGTONE_ENABLED = "true";
static const char *const CONFIG_DEFAULT_PRESENCE_ENABLED = "true";
static const char *const CONFIG_ACCOUNT_HOSTNAME = "Account.hostname";
static const char *const CONFIG_ACCOUNT_USERNAME = "Account.username";
......
......@@ -179,16 +179,7 @@ class CallManager
void registrationStateChanged(const std::string&, const std::string&, const int32_t&);
void sipCallStateChanged(const std::string&, const std::string&, const int32_t&);
void newPresSubClientNotification(const std::string& uri, const std::string& basic, const std::string& note);
void newPresSubServerRequest(const std::string& remote);
#endif // __ANDROID__
/* Presence subscription/Notification. */
void enablePresence(const std::string& accountID, const bool& flag);
void sendPresence(const std::string& accountID, const bool& status, const std::string& note);
void approvePresSubServer(const std::string& uri, const bool& flag);
void subscribePresSubClient(const std::string& accountID, const std::string& uri, const bool& flag);
private:
#if HAVE_ZRTP
......
......@@ -38,6 +38,7 @@
class ConfigurationManager;
class CallManager;
class PresenceManager;
class NetworkManager;
class Instance;
class VideoControls;
......@@ -57,6 +58,10 @@ class Client {
ConfigurationManager * getConfigurationManager() {
return configurationManager_;
}
PresenceManager * getPresenceManager() {
return presenceManager_;
}
#ifdef SFL_VIDEO
VideoControls* getVideoControls() {
return videoControls_;
......@@ -70,6 +75,7 @@ class Client {
NON_COPYABLE(Client);
CallManager* callManager_;
ConfigurationManager* configurationManager_;
PresenceManager* presenceManager_;
Instance* instanceManager_;
DBus::BusDispatcher* dispatcher_;
#ifdef SFL_VIDEO
......
......@@ -5,6 +5,7 @@ noinst_LTLIBRARIES = libclient.la
BUILT_SOURCES= \
callmanager-glue.h \
configurationmanager-glue.h \
presencemanager-glue.h \
instance-glue.h
if SFL_VIDEO
......@@ -21,6 +22,10 @@ callmanager-glue.h: callmanager-introspec.xml Makefile.am
configurationmanager-glue.h: configurationmanager-introspec.xml Makefile.am
dbusxx-xml2cpp $< --adaptor=$@
# Rule to generate the binding headers
presencemanager-glue.h: presencemanager-introspec.xml Makefile.am
dbusxx-xml2cpp $< --adaptor=$@
# Rule to generate the binding headers
instance-glue.h: instance-introspec.xml Makefile.am
dbusxx-xml2cpp $< --adaptor=$@
......@@ -29,7 +34,8 @@ libclient_la_SOURCES = \
callmanager.cpp \
configurationmanager.cpp \
instance.cpp \
client.cpp
client.cpp \
presencemanager.cpp
if SFL_VIDEO
libclient_la_SOURCES+=video_controls.cpp
......@@ -51,6 +57,7 @@ libclient_la_CXXFLAGS = -I../ \
noinst_HEADERS = \
../callmanager.h \
../configurationmanager.h \
../presencemanager.h \
instance.h \
../client.h \
networkmanager_proxy.h \
......@@ -75,7 +82,8 @@ EXTRA_DIST = README $(service_in_files) \
callmanager-introspec.xml \
configurationmanager-introspec.xml \
instance-introspec.xml \
org.freedesktop.NetworkManager.xml
org.freedesktop.NetworkManager.xml \
presencemanager-introspec.xml
if SFL_VIDEO
EXTRA_DIST += video_controls-introspec.xml
......
......@@ -819,43 +819,5 @@
<arg type="s" name="callID" direction="in"/>
<arg type="b" name="accepted" direction="in"/>
</method>
<method name="subscribePresSubClient" tp:name-for-bindings="subscribePresSubClient">
<tp:added version="0.9.7"/>
<arg type="s" name="accountID" direction="in"/>
<arg type="s" name="uri" direction="in"/>
<arg type="b" name="flag" direction="in"/>
</method>
<method name="enablePresence" tp:name-for-bindings="enablePresence">
<tp:added version="0.9.7"/>
<arg type="s" name="accountID" direction="in"/>
<arg type="b" name="flag" direction="in"/>
</method>
<method name="sendPresence" tp:name-for-bindings="sendPresence">
<tp:added version="0.9.7"/>
<arg type="s" name="accountID" direction="in"/>
<arg type="b" name="status" direction="in"/>
<arg type="s" name="note" direction="in"/>
</method>
<method name="approvePresSubServer" tp:name-for-bindings="approvePresSubServer">
<tp:added version="0.9.7"/>
<arg type="s" name="uri" direction="in"/>
<arg type="b" name="flag" direction="in"/>
</method>
<signal name="newPresSubClientNotification" tp:name-for-bindings="newPresSubClientNotification">
<tp:added version="0.9.7"/>
<arg type="s" name="buddyUri"/>
<arg type="s" name="status"/>
<arg type="s" name="lineStatus"/>
</signal>
<signal name="newPresSubServerRequest" tp:name-for-bindings="newPresSubServerRequest">
<arg type="s" name="buddyUri"/>
</signal>
</interface>
</node>
......@@ -424,65 +424,3 @@ CallManager::sendTextMessage(const std::string& callID, const std::string& messa
ERROR("Could not send \"%s\" text message to %s since SFLphone daemon does not support it, please recompile with instant messaging support", message.c_str(), callID.c_str());
#endif
}
/**
* Un/subscribe to buddySipUri for an accountID
*/
void
CallManager::subscribePresSubClient(const std::string& accountID, const std::string& uri, const bool& flag)
{
SIPAccount *sipaccount = Manager::instance().getSipAccount(accountID);
if (!sipaccount)
ERROR("Could not find account %s",accountID.c_str());
else{
DEBUG("%subscribePresence (acc:%s, buddy:%s)",flag? "S":"Uns", accountID.c_str(), uri.c_str());
sipaccount->getPresence()->subscribePresSubClient(uri,flag);
}
}
/**
* Enable the presence module (PUBLISH/SUBSCRIBE)
*/
void
CallManager::enablePresence(const std::string& accountID, const bool& flag){
SIPAccount *sipaccount = Manager::instance().getSipAccount(accountID);
if (!sipaccount)
ERROR("Could not find account %s",accountID.c_str());
else{
DEBUG("Enable Presence (acc:%s : %s)",accountID.c_str(), flag? "yes":"no");
sipaccount->getPresence()->enable(flag);
}
}
/**
* push a presence for a account
* Notify for IP2IP account and publish for PBX account
*/
void
CallManager::sendPresence(const std::string& accountID, const bool& status, const std::string& note)
{
SIPAccount *sipaccount = Manager::instance().getSipAccount(accountID);
if (!sipaccount)
ERROR("Could not find account %s.",accountID.c_str());
else{
DEBUG("Send Presence (acc:%s, status %s).",accountID.c_str(),status? "online":"offline");
sipaccount->getPresence()->sendPresence(status, note);
}
}
/**
* Accept or not a PresSubServer request for IP2IP account
*/
void
CallManager::approvePresSubServer(const std::string& uri, const bool& flag)
{
SIPAccount *sipaccount = Manager::instance().getIP2IPAccount();
if (!sipaccount)
ERROR("Could not find account IP2IP");
else{
DEBUG("Approve presence (acc:IP2IP, serv:%s, flag:%s)", uri.c_str(), flag? "true":"false");
sipaccount->getPresence()->approvePresSubServer(uri, flag);
}
}
......@@ -43,6 +43,7 @@
#include "callmanager.h"
#include "configurationmanager.h"
#include "presencemanager.h"
#include "networkmanager.h"
#ifdef SFL_VIDEO
......@@ -51,6 +52,7 @@
Client::Client() : callManager_(0)
, configurationManager_(0)
, presenceManager_(0)
, instanceManager_(0)
, dispatcher_(new DBus::BusDispatcher)
#ifdef SFL_VIDEO
......@@ -75,6 +77,8 @@ Client::Client() : callManager_(0)
callManager_ = new CallManager(sessionConnection);
DEBUG("DBUS create configuration manager from session connection");
configurationManager_ = new ConfigurationManager(sessionConnection);
DEBUG("DBUS create presence manager from session connection");
presenceManager_ = new PresenceManager(sessionConnection);
DEBUG("DBUS create instance manager from session connection");
instanceManager_ = new Instance(sessionConnection);
......
......@@ -46,6 +46,7 @@
<li>ACCOUNT_REGISTRATION_STATUS: The account registration status. Should be Registered to make calls.</li>
<li>ACCOUNT_REGISTRATION_STATE_CODE</li>
<li>ACCOUNT_REGISTRATION_STATE_DESC</li>
<li>CONFIG_DEFAULT_PRESENCE_ENABLED: enable/disable presence support - true or false</li>
<li>SRTP_KEY_EXCHANGE</li>
<li>SRTP_ENABLE: Whether or not voice communication are encrypted - True or False (Default: False)</li>
<li>SRTP_RTP_FALLBACK</li>
......
......@@ -147,12 +147,13 @@ void ConfigurationManager::registerAllAccounts()
std::map<std::string, std::string> ConfigurationManager::getAccountTemplate()
{
std::map<std::string, std::string> accTemplate;
accTemplate[ CONFIG_LOCAL_PORT ] = CONFIG_DEFAULT_LOCAL_PORT;
accTemplate[ CONFIG_PUBLISHED_PORT ] = CONFIG_DEFAULT_PUBLISHED_PORT;
accTemplate[ CONFIG_LOCAL_PORT ] = CONFIG_DEFAULT_LOCAL_PORT ;
accTemplate[ CONFIG_PUBLISHED_PORT ] = CONFIG_DEFAULT_PUBLISHED_PORT ;
accTemplate[ CONFIG_PUBLISHED_SAMEAS_LOCAL ] = CONFIG_DEFAULT_PUBLISHED_SAMEAS_LOCAL;
accTemplate[ CONFIG_INTERFACE ] = CONFIG_DEFAULT_INTERFACE;
accTemplate[ CONFIG_ACCOUNT_REGISTRATION_EXPIRE ] = CONFIG_DEFAULT_REGISTRATION_EXPIRE;
accTemplate[ CONFIG_RINGTONE_ENABLED ] = CONFIG_DEFAULT_RINGTONE_ENABLED;
accTemplate[ CONFIG_INTERFACE ] = CONFIG_DEFAULT_INTERFACE ;
accTemplate[ CONFIG_ACCOUNT_REGISTRATION_EXPIRE ] = CONFIG_DEFAULT_REGISTRATION_EXPIRE ;
accTemplate[ CONFIG_RINGTONE_ENABLED ] = CONFIG_DEFAULT_RINGTONE_ENABLED ;
accTemplate[ CONFIG_PRESENCE_ENABLED ] = CONFIG_DEFAULT_PRESENCE_ENABLED ;
return accTemplate;
}
......
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/presencemanager-introspec" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.sflphone.SFLphone.PresenceManager">
<!-- METHODS !-->
<method name="publish" tp:name-for-bindings="publish">
<tp:added version="1.3.0"/>
<arg type="s" name="accountID" direction="in">
<tp:docstring>
The account from which the presence will be emitted
</tp:docstring>
</arg>
<arg type="b" name="status" direction="in">
<tp:docstring>
Is this account present or not
</tp:docstring>
</arg>
<arg type="s" name="note" direction="in">
<tp:docstring>
A message transmitted by the server to other users
</tp:docstring>
</arg>
</method>
<method name="answerServerRequest" tp:name-for-bindings="answerServerRequest">
<tp:docstring>
Answer a presence request from the server
</tp:docstring>
<tp:added version="1.3.0"/>
<arg type="s" name="uri" direction="in">
<tp:docstring>
</tp:docstring>
</arg>
<arg type="b" name="flag" direction="in">
<tp:docstring>
Is the request granted or denied
</tp:docstring>
</arg>
</method>
<method name="subscribeBuddy" tp:name-for-bindings="subscribeBuddy">
<tp:docstring>
Ask be be notified when 'uri' presence change
</tp:docstring>
<tp:added version="1.3.0"/>
<arg type="s" name="accountID" direction="in">
<tp:docstring>
An account from which get request presence informations
</tp:docstring>
</arg>
<arg type="s" name="uri" direction="in">
<tp:docstring>
A SIP uri to watch
</tp:docstring>
</arg>
<arg type="b" name="flag" direction="in">
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method name="getSubscriptions" tp:name-for-bindings="getSubscriptions">
<tp:added version="1.3.0"/>
<tp:rationale>
New clients connecting to existing daemon need to be aware of active
subscriptions.
</tp:rationale>
<annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="VectorMapStringString"/>
<annotation>
While there is more status than "Online" or "Offline", only those
</annotation>
<arg type="s" name="accountID" direction="in">
</arg>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
<arg type="aa{ss}" name="credentialInformation" direction="out" tp:type="String_String_Map">
<tp:docstring>
List of hashes map with the following key-value pairs:
* Status: "Online" or "Offline"
* LineStatus: String
</tp:docstring>
</arg>
</method>
<method name="setSubscriptions" tp:name-for-bindings="setSubscriptions">
<tp:added version="1.3.0"/>
<tp:rationale>Calling "subscribeClient" in a loop is too slow</tp:rationale>
<arg type="s" name="accountID" direction="in">
</arg>
<annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="VectorString"/>
<arg type="as" name="uriList" direction="in">
<tp:docstring>
A list of SIP URIs
</tp:docstring>
</arg>
<!--TODO<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
<arg type="as" name="invalidUris" direction="out">
<tp:docstring>
List of invalid URIs. An URI must be a valid SIP URI. Clients should purge
the list from all invalid URIs
</tp:docstring>
</arg>-->
</method>
<!-- SIGNALS !-->
<signal name="newBuddySubscription" tp:name-for-bindings="newBuddySubscription">
<tp:added version="1.3.0"/>
<tp:docstring>
Notify when a registered presence uri presence informations changes
</tp:docstring>
<arg type="s" name="buddyUri">
<tp:docstring>
The registered URI
</tp:docstring>
</arg>
<arg type="b" name="status">
<tp:docstring>
Is the URI present or not
</tp:docstring>
</arg>
<arg type="s" name="lineStatus">
<tp:docstring>
A string containing informations from the user (human readable)
</tp:docstring>
</arg>
</signal>
<signal name="newServerSubscriptionRequest" tp:name-for-bindings="newServerSubscriptionRequest">
<tp:added version="1.3.0"/>
<arg type="s" name="buddyUri">
<tp:docstring>
Notify when an other user (or the server) request your presence informations
</tp:docstring>
</arg>
</signal>
</interface>
</node>
/*
* Copyright (C) 2013 Savoir-Faire Linux Inc.
* Author: Patrick Keroulas <patrick.keroulas@savoirfairelinux.com>
*
* 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 3 of the License, 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "presencemanager.h"
#include <cerrno>
#include <sstream>
#include "logger.h"
#include "sip/sipaccount.h"
#include "manager.h"
#include "sip/sippresence.h"
#include "sip/pres_sub_client.h"
namespace {
constexpr static const char* SERVER_PATH = "/org/sflphone/SFLphone/PresenceManager";
constexpr static const char* STATUS_KEY = "Status";
constexpr static const char* LINESTATUS_KEY = "LineStatus";
constexpr static const char* ONLINE_KEY = "Online";
constexpr static const char* OFFLINE_KEY = "Offline";
}
PresenceManager::PresenceManager(DBus::Connection& connection) :
DBus::ObjectAdaptor(connection, SERVER_PATH)
{}
/**
* Un/subscribe to buddySipUri for an accountID
*/
void
PresenceManager::subscribeBuddy(const std::string& accountID, const std::string& uri, const bool& flag)
{
SIPAccount *sipaccount = Manager::instance().getSipAccount(accountID);
if (!sipaccount)
ERROR("Could not find account %s",accountID.c_str());
else{
DEBUG("%subscribePresence (acc:%s, buddy:%s)",flag? "S":"Uns", accountID.c_str(), uri.c_str());
sipaccount->getPresence()->subscribeClient(uri,flag);
}
}
/**
* push a presence for a account
* Notify for IP2IP account and publish for PBX account
*/
void
PresenceManager::publish(const std::string& accountID, const bool& status, const std::string& note)
{
SIPAccount *sipaccount = Manager::instance().getSipAccount(accountID);
if (!sipaccount)
ERROR("Could not find account %s.",accountID.c_str());
else{
DEBUG("Send Presence (acc:%s, status %s).",accountID.c_str(),status? "online":"offline");
sipaccount->getPresence()->sendPresence(status, note);
}
}
/**
* Accept or not a PresSubServer request for IP2IP account
*/
void
PresenceManager::answerServerRequest(const std::string& uri, const bool& flag)
{
SIPAccount *sipaccount = Manager::instance().getIP2IPAccount();
if (!sipaccount)
ERROR("Could not find account IP2IP");
else{
DEBUG("Approve presence (acc:IP2IP, serv:%s, flag:%s)", uri.c_str(), flag? "true":"false");
sipaccount->getPresence()->approvePresSubServer(uri, flag);
}
}
/**
* Get all active subscriptions for "accountID"
*/
std::vector<std::map<std::string, std::string> >
PresenceManager::getSubscriptions(const std::string& accountID)
{
std::vector<std::map<std::string, std::string> > ret;
SIPAccount *sipaccount = Manager::instance().getSipAccount(accountID);
if (sipaccount) {
for (auto s : sipaccount->getPresence()->getClientSubscriptions()) {
std::map<std::string, std::string> sub;