Skip to content
Snippets Groups Projects
Commit 8f3f26d4 authored by Guillaume Carmel-Archambault's avatar Guillaume Carmel-Archambault
Browse files

Presence and contacts in server

parent a03c4b20
Branches
Tags
No related merge requests found
......@@ -38,6 +38,7 @@ AC_CONFIG_FILES([src/Makefile \
src/audio/codecs/Makefile
src/audio/codecs/ilbc/Makefile \
src/config/Makefile \
src/contact/Makefile \
src/dbus/Makefile \
src/zeroconf/Makefile])
......
......@@ -28,7 +28,7 @@ IAXSOURCES =
IAXHEADERS =
endif
SUBDIRS = audio config dbus $(ZEROCONFDIR)
SUBDIRS = audio config contact dbus $(ZEROCONFDIR)
sflphoned_SOURCES = eventthread.cpp main.cpp voiplink.cpp \
managerimpl.cpp observer.cpp \
......@@ -51,6 +51,7 @@ libsflphone_la_LIBADD = \
./audio/libaudio.la \
./dbus/libdbus.la \
./config/libconfig.la \
./contact/libcontact.la \
$(IAX_LIBS)
libsflphone_la_SOURCES =
......
......@@ -21,25 +21,60 @@
#include "voiplink.h"
#include "manager.h"
#include <string>
Account::Account(const AccountID& accountID) : _accountID(accountID)
{
_link = NULL;
_enabled = false;
}
Account::~Account()
{
// _link should be destroyed WHERE IT'S CREATED
//delete _link;
//_link = NULL;
}
void
Account::loadConfig()
{
_enabled = Manager::instance().getConfigInt(_accountID, CONFIG_ACCOUNT_ENABLE) ? true : false;
}
// NOW
void
Account::loadContacts()
{
// TMP
Contact* contact1 = new Contact("1223345", "Guillaume140", "<sip:140@asterix.inside.savoirfairelinux.net>");
_contacts.push_back(contact1);
Contact* contact2 = new Contact("9876543", "SFLphone131", "<sip:131@asterix.inside.savoirfairelinux.net>");
_contacts.push_back(contact2);
Contact* contact3 = new Contact("6867823", "Guillaume201", "<sip:201@192.168.1.202:5066>");
_contacts.push_back(contact3);
Contact* contact4 = new Contact("3417928", "SFLphone203", "<sip:203@192.168.1.202:5066>");
_contacts.push_back(contact4);
// TODO Load contact file containing list of contacts
// or a configuration for LDAP contacts
}
void
Account::subscribeContactsPresence()
{
if(_link->isContactPresenceSupported())
{
// Subscribe to presence for each contact that presence is enabled
std::vector<Contact*>::iterator iter;
for(iter = _contacts.begin(); iter != _contacts.end(); iter++)
{
_link->subscribePresenceForContact(*iter);
}
}
}
void
Account::publishPresence(std::string presenceStatus)
{
if(_link->isContactPresenceSupported())
_link->publishPresenceStatus(presenceStatus);
}
......@@ -20,7 +20,9 @@
#define ACCOUNT_H
#include <string>
#include <vector>
#include "config/config.h"
#include "contact/contact.h"
#include "voiplink.h"
class VoIPLink;
......@@ -46,9 +48,6 @@ typedef std::string AccountID;
#define SIP_STUN_SERVER "STUN.STUNserver"
#define SIP_USE_STUN "STUN.useStun"
/**
* Class account is an interface to protocol account (SIPAccount, IAXAccount)
* It can be enable on loading or activate after.
......@@ -106,6 +105,21 @@ class Account{
*/
VoIPLink::RegistrationState getRegistrationState() { return _link->getRegistrationState(); }
/**
* Load all contacts
*/
void loadContacts();
/**
* Suscribe presence information for selected contacts if supported
*/
void subscribeContactsPresence();
/**
* Publish our presence information to the server
*/
void publishPresence(std::string presenceStatus);
private:
protected:
......@@ -128,6 +142,10 @@ protected:
*/
bool _enabled;
/**
* Contacts related to account that can have presence information
*/
std::vector<Contact*> _contacts;
};
#endif
SUBDIRS =
noinst_LTLIBRARIES = \
libcontact.la
libcontact_la_SOURCES = \
contact.h \
presence.h \
contact.cpp \
presence.cpp
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "contact.h"
#include <string>
Contact::Contact()
{
}
Contact::Contact(const std::string contactID, const std::string name, const std::string url)
{
_contactID = contactID;
_name = name;
_url = url;
_suscribeToPresence = true;
_presence = NULL;
}
Contact::~Contact()
{
}
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef CONTACT_H
#define CONTACT_H
#include "presence.h"
#include <string>
typedef std::string ContactID;
/**
* TOCOMMENT
* @author Guillaume Carmel-Archambault
*/
class Contact {
public:
Contact();
Contact(const std::string contactID, const std::string name, const std::string url);
virtual ~Contact();
std::string getUrl() { return _url; }
protected:
private:
ContactID _contactID;
std::string _name;
std::string _url;
bool _suscribeToPresence;
// Presence information, can be null
Presence* _presence;
};
#endif
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "presence.h"
Presence::Presence()
{
}
Presence::~Presence()
{
}
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef PRESENCE_H
#define PRESENCE_H
#include <string>
/**
* TOCOMMENT
* @author Guillaume Carmel-Archambault
*/
class Presence {
public:
Presence();
virtual ~Presence();
protected:
private:
std::string _state;
std::string _capabalities;
};
#endif
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef PRESENCE_STATUS_H
#define PRESENCE_STATUS_H
/* Definition of all presence status used by the deamon and the GUI
* The deamon knows how to identify tags coming from presence servers
* and cast them in a defined presence status presented here.
* The presence information is transmitted along DBus by those strings.
* The GUI can format and translate these strings for presentation.
*
* If a presence status identified by a string cannot be identified
* when sent from a presence server, we directly use the raw string
* without any formating or translation process possible
*/
// Same presence status as defined in Asterisk
#define PRESENCE_UNKNOWN "UNKNOWN"
#define PRESENCE_NOT_IN_USE "NOT_IN_USE"
#define PRESENCE_INUSE "INUSE"
#define PRESENCE_BUSY "BUSY"
#define PRESENCE_INVALID "INVALID"
#define PRESENCE_UNAVAILABLE "UNAVAILABLE"
#define PRESENCE_RINGING "RINGING"
#define PRESENCE_RING_IN_USE "RING_IN_USE"
#define PRESENCE_HOLD_IN_USE "HOLD_IN_USE"
#define PRESENCE_ON_HOLD "ON_HOLD"
// Presence status defined on some hardware phones
#define PRESENCE_ONLINE "ONLINE"
#define PRESENCE_BUSY "BUSY"
#define PRESENCE_BE_RIGHT_BACK "BE_RIGHT_BACK"
#define PRESENCE_AWAY "AWAY"
#define PRESENCE_OUT_TO_LUNCH "OUT_TO_LUNCH"
#define PRESENCE_OFFLINE "OFFLINE"
#define PRESENCE_DO_NOT_DISTURB "DO_NOT_DISTURB"
// Other presence status defined supported
#define PRESENCE_IN_REUNION "IN_REUNION"
#define PRESENCE_IN_CONFERENCE_CALL "IN_CONFERENCE_CALL"
#endif
......@@ -82,6 +82,7 @@ public:
bool refuse (const CallID& id);
bool carryingDTMFdigits(const CallID& id, char code);
bool sendMessage(const std::string& to, const std::string& body) { return false; }
bool isContactPresenceSupported() { return false; }
public: // iaxvoiplink only
void setHost(const std::string& host) { _host = host; }
......
......@@ -47,6 +47,8 @@
#include "user_cfg.h"
#include "contact/presencestatus.h"
#ifdef USE_ZEROCONF
#include "zeroconf/DNSService.h"
#include "zeroconf/DNSServiceTXTRecord.h"
......@@ -434,7 +436,11 @@ ManagerImpl::initRegisterAccounts()
if ( iter->second) {
iter->second->loadConfig();
if ( iter->second->isEnabled() ) {
// NOW
iter->second->registerVoIPLink();
iter->second->loadContacts();
iter->second->publishPresence(PRESENCE_ONLINE);
iter->second->subscribeContactsPresence();
}
}
iter++;
......@@ -460,7 +466,11 @@ ManagerImpl::registerAccount(const AccountID& accountId)
}
iter++;
}
// NOW
account->registerVoIPLink();
account->loadContacts();
account->publishPresence(PRESENCE_ONLINE);
account->subscribeContactsPresence();
}
return true;
}
......
......@@ -212,6 +212,7 @@ SIPVoIPLink::loadSIPLocalIP()
void
SIPVoIPLink::getEvent()
{
char* tmp2;
eXosip_event_t* event = eXosip_event_wait(0, 50);
eXosip_lock();
eXosip_automatic_action();
......@@ -223,16 +224,19 @@ SIPVoIPLink::getEvent()
_debug("> SIP Event: [cdt=%4d:%4d:%4d] type=#%03d %s \n", event->cid, event->did, event->tid, event->type, event->textinfo);
switch (event->type) {
/* REGISTER related events */
case EXOSIP_REGISTRATION_NEW: /** 00 < announce new registration. */
_debug(" !EXOSIP_REGISTRATION_NEW event is not implemented\n");
break;
case EXOSIP_REGISTRATION_SUCCESS: /** 01 < user is successfully registred. */
setRegistrationState(Registered);
_debug(" !EXOSIP_REGISTRATION_SUCCES\n");// TMP
//Manager::instance().registrationSucceed(getAccountID());
break;
case EXOSIP_REGISTRATION_FAILURE: /** 02 < user is not registred. */
setRegistrationState(Error, "SIP registration failure.");
_debug(" !EXOSIP_REGISTRATION_FAILURE\n");// TMP
//Manager::instance().registrationFailed(getAccountID());
break;
case EXOSIP_REGISTRATION_REFRESHED: /** 03 < registration has been refreshed. */
......@@ -251,6 +255,7 @@ SIPVoIPLink::getEvent()
SIPCallReinvite(event);
break;
/* CALL related events */
case EXOSIP_CALL_NOANSWER: /** 07 < announce no answer within the timeout */
_debug(" !EXOSIP_CALL_NOANSWER event is not implemented\n");
break;
......@@ -258,67 +263,96 @@ SIPVoIPLink::getEvent()
_debug(" !EXOSIP_CALL_PROCEEDING event is not implemented\n");
break;
case EXOSIP_CALL_RINGING: /** 09 < announce ringback */
_debug(" !EXOSIP_CALL_RINGING\n");// TMP
SIPCallRinging(event);
break;
case EXOSIP_CALL_ANSWERED: /** 10 < announce start of call */
_debug(" !EXOSIP_CALL_ANSWERED\n");// TMP
SIPCallAnswered(event);
break;
case EXOSIP_CALL_REDIRECTED: /** 11 < announce a redirection */
_debug(" !EXOSIP_CALL_REDIRECTED event is not implemented\n");
break;
case EXOSIP_CALL_REQUESTFAILURE: /** 12 < announce a request failure */
_debug(" !EXOSIP_CALL_REQUESTFAILURE");// TMP
SIPCallRequestFailure(event);
break;
case EXOSIP_CALL_SERVERFAILURE: /** 13 < announce a server failure */
_debug(" !EXOSIP_CALL_SERVERFAILURE");// TMP
SIPCallServerFailure(event);
break;
case EXOSIP_CALL_GLOBALFAILURE: /** 14 < announce a global failure */
_debug(" !EXOSIP_CALL_GLOBALFAILURE\n");// TMP
SIPCallServerFailure(event);
break;
case EXOSIP_CALL_ACK: /** 15 < ACK received for 200ok to INVITE */
_debug(" !EXOSIP_CALL_ACK\n");// TMP
SIPCallAck(event);
break;
case EXOSIP_CALL_CANCELLED: /** 16 < announce that call has been cancelled */
_debug(" !EXOSIP_CALL_CANCELLED\n");// TMP
break;
case EXOSIP_CALL_TIMEOUT: /** 17 < announce that call has failed */
_debug(" !EXOSIP_CALL_TIMEOUT\n");// TMP
Manager::instance().displayError(" !EXOSIP Call Error not implemented yet");
break;
/* request related events within calls (except INVITE) */
/* Request related events within calls (except INVITE) */
case EXOSIP_CALL_MESSAGE_NEW: /** 18 < announce new incoming MESSAGE. */
_debug(" !EXOSIP_CALL_MESSAGE_NEW\n");// TMP
SIPCallMessageNew(event);
break;
case EXOSIP_CALL_MESSAGE_PROCEEDING: /** 19 < announce a 1xx for MESSAGE. */
_debug(" !EXOSIP_CALL_MESSAGE_PROCEEDING\n");// TMP
break;
case EXOSIP_CALL_MESSAGE_ANSWERED: /** 20 < announce a 200ok */
// 200 OK
_debug(" !EXOSIP_CALL_MESSAGE_ANSWERED\n");// TMP
break;
case EXOSIP_CALL_MESSAGE_REDIRECTED: /** 21 < announce a failure. */
_debug(" !EXOSIP_CALL_MESSAGE_REDIRECTED\n");// TMP
break;
case EXOSIP_CALL_MESSAGE_REQUESTFAILURE: /** 22 < announce a failure. */
_debug(" !EXOSIP_CALL_MESSAGE_REQUESTFAILURE\n");// TMP
break;
case EXOSIP_CALL_MESSAGE_SERVERFAILURE: /** 23 < announce a failure. */
_debug(" !EXOSIP_CALL_MESSAGE_SERVERFAILURE\n");// TMP
break;
case EXOSIP_CALL_MESSAGE_GLOBALFAILURE: /** 24 < announce a failure. */
_debug(" !EXOSIP_CALL_MESSAGE_GLOBALFAILURE\n");// TMP
Manager::instance().displayError(" !EXOSIP Call Message not implemented yet");
break;
case EXOSIP_CALL_CLOSED: /** 25 < a BYE was received for this call */
_debug(" !EXOSIP_CALL_CLOSED\n");// TMP
SIPCallClosed(event);
break;
/* for both UAS & UAC events */
/* For both UAS & UAC events */
case EXOSIP_CALL_RELEASED: /** 26 < call context is cleared. */
_debug(" !EXOSIP_CALL_RELEASED\n");// TMP
SIPCallReleased(event);
break;
/* response received for request outside calls */
/* Response received for request outside calls */
case EXOSIP_MESSAGE_NEW: /** 27 < announce new incoming MESSAGE. */
_debug(" !EXOSIP_MESSAGE_NEW\n");// TMP
if (event->request == NULL) { break; }
SIPMessageNew(event);
break;
case EXOSIP_MESSAGE_PROCEEDING: /** 28 < announce a 1xx for MESSAGE. */
_debug(" !EXOSIP_MESSAGE_PROCEEDING\n");// TMP
break;
case EXOSIP_MESSAGE_ANSWERED: /** 29 < announce a 200ok */
_debug(" !EXOSIP_MESSAGE_ANSWERED\n");// TMP
break;
case EXOSIP_MESSAGE_REDIRECTED: /** 30 < announce a failure. */
_debug(" !EXOSIP_MESSAGE_REDIRECTED\n");// TMP
Manager::instance().displayError(" !EXOSIP Message not implemented yet");
break;
case EXOSIP_MESSAGE_REQUESTFAILURE: /** 31 < announce a failure. */
_debug(" !EXOSIP_MESSAGE_REQUESTFAILURE\n");// TMP
if (event->response !=0 && event->response->status_code == SIP_METHOD_NOT_ALLOWED) {
Manager::instance().incomingMessage(getAccountID(), "Message are not allowed");
} else {
......@@ -326,41 +360,78 @@ SIPVoIPLink::getEvent()
}
break;
case EXOSIP_MESSAGE_SERVERFAILURE: /** 32 < announce a failure. */
_debug(" !EXOSIP_MESSAGE_SERVERFAILURE\n");// TMP
break;
case EXOSIP_MESSAGE_GLOBALFAILURE: /** 33 < announce a failure. */
_debug(" !EXOSIP_MESSAGE_GLOBALFAILURE\n");// TMP
Manager::instance().displayError(" !EXOSIP Message not implemented yet");
break;
/* Presence and Instant Messaging */
case EXOSIP_SUBSCRIPTION_UPDATE: /** 34 < announce incoming SUBSCRIBE. */
_debug(" !EXOSIP_SUBSCRIPTION_UPDATE\n");
break;
case EXOSIP_SUBSCRIPTION_CLOSED: /** 35 < announce end of subscription. */
_debug(" !EXOSIP_SUBSCRIPTION_CLOSED\n");
Manager::instance().displayError(" !EXOSIP Subscription not implemented yet");
break;
case EXOSIP_SUBSCRIPTION_NOANSWER: /** 37 < announce no answer */
_debug(" !EXOSIP_SUBSCRIPTION_NOANSWER\n");
break;
case EXOSIP_SUBSCRIPTION_PROCEEDING: /** 38 < announce a 1xx */
Manager::instance().displayError(" !EXOSIP Subscription resposne not implemented yet");
_debug(" !EXOSIP_SUBSCRIPTION_PROCEEDING\n");
Manager::instance().displayError(" !EXOSIP Subscription response not implemented yet");
break;
case EXOSIP_SUBSCRIPTION_ANSWERED: /** 39 < announce a 200ok */
_debug(" !EXOSIP_SUBSCRIPTION_ANSWERED\n");
eXosip_lock();
eXosip_automatic_action();
eXosip_unlock();
break;
case EXOSIP_SUBSCRIPTION_REDIRECTED: /** 40 < announce a redirection */
_debug(" !EXOSIP_SUBSCRIPTION_REDIRECTED\n");// TMP
break;
case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /** 41 < announce a request failure */
_debug(" !EXOSIP_SUBSCRIPTION_REQUESTFAILURE\n");// TMP
break;
case EXOSIP_SUBSCRIPTION_SERVERFAILURE: /** 42 < announce a server failure */
_debug(" !EXOSIP_SUBSCRIPTION_REQUESTFAILURE\n");// TMP
break;
case EXOSIP_SUBSCRIPTION_GLOBALFAILURE: /** 43 < announce a global failure */
_debug(" !EXOSIP_SUBSCRIPTION_GLOBALFAILURE\n");// TMP
break;
case EXOSIP_SUBSCRIPTION_NOTIFY: /** 44 < announce new NOTIFY request */
_debug(" !EXOSIP_SUBSCRIPTION_NOTIFY\n");
osip_body_t* body;
osip_from_to_str(event->request->from, &tmp2);
osip_message_get_body(event->request, 0, &body);
if (body != NULL && body->body != NULL) {
printf("\n---------------------------------\n");
printf ("(%i) from: %s\n %s\n", event->tid, tmp2, body->body);
printf("---------------------------------\n");
osip_free(tmp2);
}
break;
case EXOSIP_SUBSCRIPTION_RELEASED: /** 45 < call context is cleared. */
_debug(" !EXOSIP_SUBSCRIPTION_RELEASED\n");
Manager::instance().displayError(" !EXOSIP Subscription response not implemented yet.");
break;
case EXOSIP_IN_SUBSCRIPTION_NEW: /** 46 < announce new incoming SUBSCRIBE.*/
_debug(" !EXOSIP_IN_SUBSCRIPTION_NEW\n");
break;
case EXOSIP_IN_SUBSCRIPTION_RELEASED: /** 47 < announce end of subscription. */
_debug(" !EXOSIP_IN_SUBSCRIPTION_RELEASED\n");
Manager::instance().displayError(" !EXOSIP Subscription not implemented yet");
break;
case EXOSIP_EVENT_COUNT: /** 48 < MAX number of events */
_debug(" !EXOSIP_EVENT_COUNT : SHOULD NEVER HAPPEN!!!!!\n"); // TMP
break;
default:
printf("received eXosip event (type, did, cid) = (%d, %d, %d)", event->type, event->did, event->cid);
break;
}
eXosip_event_free(event);
......@@ -895,6 +966,93 @@ SIPVoIPLink::sendMessage(const std::string& to, const std::string& body)
return returnValue;
}
// NOW
bool
SIPVoIPLink::isContactPresenceSupported()
{
return true;
}
void
SIPVoIPLink::subscribePresenceForContact(Contact* contact)
{
osip_message_t* subscription;
int i;
std::string to = contact->getUrl().data();
std::ostringstream from;
// Build URL of sender
from << "sip:" << _userpart.data() << "@" << getHostName().data();
// Subscribe for changes on server but also polls at every 5000 interval
i = eXosip_subscribe_build_initial_request(&subscription,
to.data(),
from.str().c_str(),
NULL,
"presence", 5000);
if(i!=0) return;
// We want to receive presence in the PIDF XML format in SIP messages
osip_message_set_accept(subscription, "application/pidf+xml");
// Send subscription
eXosip_lock();
i = eXosip_subscribe_send_initial_request(subscription);
if(i!=0) _debug("Sending of subscription tp %s failed\n", to.data());
eXosip_unlock();
}
void
SIPVoIPLink::publishPresenceStatus(std::string status)
{
_debug("PUBLISH PRESENCE\n");
char buf[4096];
int i;
osip_message_t* publication;
std::ostringstream url;
std::string basic;
std::string note;
// Build URL of sender
url << "sip:" << _userpart.data() << "@" << getHostName().data();
// TODO
// Call function to convert status in basic and note
// tags that are integrated in the publication
basic = "open";
note = "ready";
snprintf(buf, 4096,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status>\n\
<basic>%s</basic>\n\
<es:activities>\n\
<es:activity>in-transit</es:activity>\n\
</es:activities>\n\
</status>\n\
<contact priority=\"0.8\">%s</contact>\n\
<note>%s</note>\n\
</tuple>\n\
</presence>"
, url.str().c_str(), basic.data(), url.str().c_str(), note.data());
// TMP
printf("%s\n", buf);
i = eXosip_build_publish(&publication, url.str().c_str(), url.str().c_str(), NULL, "presence", "1800", "application/pidf+xml", buf);
eXosip_lock();
i = eXosip_publish(publication, url.str().c_str());
eXosip_unlock();
}
bool
SIPVoIPLink::SIPOutgoingInvite(SIPCall* call)
{
......
......@@ -60,8 +60,12 @@ public:
bool refuse (const CallID& id);
bool carryingDTMFdigits(const CallID& id, char code);
bool sendMessage(const std::string& to, const std::string& body);
bool isContactPresenceSupported();
void subscribePresenceForContact(Contact* contact);
void publishPresenceStatus(std::string status);
// TODO Not used yet
void sendMessageToContact(const CallID& id, const std::string& message);
// SIP Specific
......
......@@ -108,3 +108,20 @@ VoIPLink::setRegistrationState(const enum RegistrationState state)
{
setRegistrationState(state, "");
}
// NOW
void
VoIPLink::subscribePresenceForContact(Contact* contact)
{
// Nothing to do if presence is not supported
// or the function will be overidden
_debug("Presence subscription not supported for account\n");
}
void
VoIPLink::publishPresenceStatus(std::string status)
{
// Nothing to do if presence is not supported
// or the function will be overidden
_debug("Presence publication not supported for account\n");
}
......@@ -24,6 +24,7 @@
#include <string>
#include "call.h"
#include "contact/contact.h"
#include <map>
#include <cc++/thread.h> // for mutex
......@@ -94,6 +95,22 @@ public:
*/
virtual bool sendMessage(const std::string& to, const std::string& body) = 0;
// NOW
/**
* Determine if link supports presence information
*/
virtual bool isContactPresenceSupported() = 0;
/**
* Register contacts for presence information if supported
*/
virtual void subscribePresenceForContact(Contact* contact);
/**
* Publish presence status to server
*/
virtual void publishPresenceStatus(std::string status);
// these method are set only with 'Account init' and can be get by everyone
void setFullName (const std::string& fullname) { _fullname = fullname; }
std::string& getFullName (void) { return _fullname; }
......@@ -135,7 +152,6 @@ public:
*/
void setRegistrationState(const enum RegistrationState state);
private:
/**
* Full name used as outgoing Caller ID
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment