Commit c44e5251 authored by Patrick Keroulas's avatar Patrick Keroulas
Browse files

* #28472: Adapt client/dbus interface, restore lock mechanism for IP2IP

* presence subscription
parent ec7f500c
......@@ -184,6 +184,7 @@ class CallManager
void subscribePresence(const std::string& accountID, const std::string& buddySipUri);
void unsubscribePresence(const std::string& accountID, const std::string& buddySipUri);
void sendPresence(const std::string& accountID, const std::string& status, const std::string& note);
void confirmPresenceSubscription(const bool& confirm);
private:
#if HAVE_ZRTP
......
......@@ -832,18 +832,26 @@
<arg type="s" name="buddySipUri" direction="in"/>
</method>
<method name="sendPresence" tp:name-for-bindings="sendPresence">
<method name="sendPresence" tp:name-for-bindings="sendPresence">
<tp:added version="0.9.7"/>
<arg type="s" name="accountID" direction="in"/>
<arg type="s" name="status" direction="in"/>
<arg type="s" name="note" direction="in"/>
</method>
<method name="confirmPresenceSubscription" tp:name-for-bindings="confirmPresenceSubscription">
<arg type="b" name="confirm"/>
</method>
<signal name="newPresenceNotification" tp:name-for-bindings="newPresenceNotification">
<arg type="s" name="buddyUri"/>
<arg type="s" name="status"/>
<arg type="s" name="lineStatus"/>
</signal>D
</signal>
<signal name="newPresenceSubscription" tp:name-for-bindings="newPresenceSubscription">
<arg type="s" name="buddyUri"/>
</signal>
</interface>
</node>
......@@ -426,14 +426,14 @@ CallManager::sendTextMessage(const std::string& callID, const std::string& messa
void
CallManager::subscribePresence(const std::string& accountID, const std::string& buddySipUri)
{
DEBUG("subscribePresence");
DEBUG("subscribePresence (acc:%s, buddy:%)",accountID.c_str(), buddySipUri.c_str());
Manager::instance().subscribePresence(accountID,buddySipUri);
}
void
CallManager::unsubscribePresence(const std::string& accountID, const std::string& buddySipUri)
{
DEBUG("unsubscribePresence");
DEBUG("unsubscribePresence (acc:%s, buddy:%)",accountID.c_str(), buddySipUri.c_str());
Manager::instance().unsubscribePresence(accountID,buddySipUri);
}
......@@ -441,6 +441,14 @@ void
CallManager::sendPresence(const std::string& accountID, const std::string& status, const std::string& note)
{
DEBUG("sendPresence");
DEBUG("sendPresence (acc:%s, status:%s).",accountID.c_str(),status.c_str());
Manager::instance().sendPresence(accountID,status,note);
}
void
CallManager::confirmPresenceSubscription(const bool& confirm)
{
DEBUG("confirmPresenceSubscription : %s",confirm);
Manager::instance().confirmPresenceSubscription(confirm);
}
......@@ -2950,7 +2950,13 @@ void ManagerImpl::sendPresence(const std::string& accountID, const std::string&
account->getPresence()->sendPresence(status,note);
}
void
void ManagerImpl::confirmPresenceSubscription(const bool& confirm)
{
SIPAccount *account = Manager::instance().getSipAccount("IP2IP");
account->getPresence()->confirmNewServerSubscription(confirm);
}
void
ManagerImpl::registerAccounts()
{
AccountMap allAccounts(getAllAccounts());
......
......@@ -1041,11 +1041,15 @@ class ManagerImpl {
void subscribePresence(const std::string& accountID, const std::string& buddySipUri);
void unsubscribePresence(const std::string& accountID, const std::string& buddySipUri);
/**
/**
* push a presence for a account
* Notify for IP2IP accounts and publish for PBX account
* Notify for IP2IP account and publish for PBX account
*/
void sendPresence(const std::string& accountID, const std::string& status, const std::string& note);
/**
* Accept or not a PresenceSubscription request for IP2IP account
*/
void confirmPresenceSubscription(const bool& confirm);
private:
NON_COPYABLE(ManagerImpl);
......
......@@ -42,14 +42,13 @@
void pres_evsub_on_srv_state(pjsip_evsub *sub, pjsip_event *event) {
pjsip_rx_data *rdata = event->body.rx_msg.rdata;
if(!rdata) {
DEBUG("no rdata in presence");
DEBUG("Presence server state has changed but no rdata.");
return;
}
/*std::string accountId = "IP2IP";
SIPAccount *acc = Manager::instance().getSipAccount(accountId);*/
PJ_UNUSED_ARG(event);
SIPPresence * pres = Manager::instance().getSipAccount("IP2IP")->getPresence();
pres->lock();
PresenceSubscription *presenceSub = (PresenceSubscription *) pjsip_evsub_get_mod_data(sub,pres->getModId());
WARN("Presence server subscription to %s is %s", presenceSub->remote, pjsip_evsub_get_state_name(sub));
......@@ -58,23 +57,13 @@ void pres_evsub_on_srv_state(pjsip_evsub *sub, pjsip_event *event) {
state = pjsip_evsub_get_state(sub);
/* ebail : FIXME check if ths code is usefull */
#if 0
if (false pjsua_var.ua_cfg.cb.on_srv_subscribe_state) {
pj_str_t from;
from = server->dlg->remote.info_str;
(*pjsua_var.ua_cfg.cb.on_srv_subscribe_state)(uapres->acc_id,
uapres, &from,
state, event);
}
#endif
if (state == PJSIP_EVSUB_STATE_TERMINATED) {
pjsip_evsub_set_mod_data(sub, pres->getModId(), NULL);
pres->removeServerSubscription(presenceSub);
}
/* TODO check if other cases should be handled*/
}
pres->unlock();
}
pj_bool_t pres_on_rx_subscribe_request(pjsip_rx_data *rdata) {
......@@ -82,7 +71,6 @@ pj_bool_t pres_on_rx_subscribe_request(pjsip_rx_data *rdata) {
pjsip_method *method = &rdata->msg_info.msg->line.req.method;
pj_str_t *str = &method->name;
std::string request(str->ptr, str->slen);
DEBUG("pres_on_rx_subscribe_request for %s.", request.c_str());
pj_str_t contact;
pj_status_t status;
pjsip_dialog *dlg;
......@@ -95,27 +83,32 @@ pj_bool_t pres_on_rx_subscribe_request(pjsip_rx_data *rdata) {
pres_msg_data msg_data;
pjsip_evsub_state ev_state;
/* ebail this code only hande incoming subscribe messages. Otherwise we return FALSE to let other modules handle it */
if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_subscribe_method()) != 0){
/* Only hande incoming subscribe messages should be processed here.
* Otherwise we return FALSE to let other modules handle it */
if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_subscribe_method()) != 0)
return PJ_FALSE;
}
std::string name(rdata->msg_info.to->name.ptr, rdata->msg_info.to->name.slen);
std::string server(rdata->msg_info.from->name.ptr, rdata->msg_info.from->name.slen);
DEBUG("Incomming pres_on_rx_subscribe_request for %s.", request.c_str());
//std::string name(rdata->msg_info.to->name.ptr, rdata->msg_info.to->name.slen);
//std::string server(rdata->msg_info.from->name.ptr, rdata->msg_info.from->name.slen);
std::string accountId = "IP2IP"; /* ebail : this code is only used for IP2IP accounts */
std::string accountId = "IP2IP"; /* this code is only used for IP2IP accounts */
SIPAccount *acc = (SIPAccount *) Manager::instance().getSipAccount(accountId);
pjsip_endpoint *endpt = ((SIPVoIPLink*) acc->getVoIPLink())->getEndpoint();
SIPPresence * pres = acc->getPresence();
pres->lock();
contact = pj_str(strdup(acc->getContactHeader().c_str()));
/* Create UAS dialog: */
contact = pj_str(strdup(acc->getContactHeader().c_str()));
status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, &contact, &dlg);
if (status != PJ_SUCCESS) {
char errmsg[PJ_ERR_MSG_SIZE];
pj_strerror(status, errmsg, sizeof(errmsg));
WARN("Unable to create UAS dialog for subscription: %s [status=%d]", errmsg, status);
pres->unlock();
pjsip_endpt_respond_stateless(endpt, rdata, 400, NULL, NULL, NULL);
return PJ_TRUE;
}
......@@ -141,6 +134,7 @@ pj_bool_t pres_on_rx_subscribe_request(pjsip_rx_data *rdata) {
status = pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);
}
pres->unlock();
return PJ_FALSE;
}
......@@ -157,8 +151,8 @@ pj_bool_t pres_on_rx_subscribe_request(pjsip_rx_data *rdata) {
pjsip_evsub_set_mod_data(sub, pres->getModId(), presenceSub);
/* Add server subscription to the list: */
pres->addServerSubscription(presenceSub);
/* Need client approvement.*/
pres->reportNewServerSubscription(presenceSub);
/* Capture the value of Expires header. */
expires_hdr = (pjsip_expires_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
......@@ -179,6 +173,7 @@ pj_bool_t pres_on_rx_subscribe_request(pjsip_rx_data *rdata) {
if (status != PJ_SUCCESS) {
WARN("Unable to accept presence subscription %d", status);
pjsip_pres_terminate(sub, PJ_FALSE);
pres->unlock();
return PJ_FALSE;
}
//TODO: handle rejection case pjsua_pers.c:956
......@@ -207,8 +202,10 @@ pj_bool_t pres_on_rx_subscribe_request(pjsip_rx_data *rdata) {
if (status != PJ_SUCCESS) {
WARN("Unable to create/send NOTIFY %d", status);
pjsip_pres_terminate(sub, PJ_FALSE);
pres->unlock();
return status;
}
pres->unlock();
return PJ_TRUE;
}
......
......@@ -45,7 +45,7 @@ extern pj_bool_t pres_on_rx_subscribe_request(pjsip_rx_data *rdata);
static pjsip_module mod_presence_server = {
NULL, NULL, /* prev, next. */
pj_str("mod-presence-server"), //{ "mod-lotes-presence", 18}, /* Name. */
pj_str("mod-presence-server"), /* Name. */
-1, /* Id */
PJSIP_MOD_PRIORITY_DIALOG_USAGE,
NULL, /* load() */
......
......@@ -113,6 +113,10 @@ class SIPBuddy {
pjsip_hdr *res_hdr,
pjsip_msg_body **p_body);
friend void buddy_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry);
/**
* TODO: explain this:
*/
void incLock() {
lock_count++;
}
......
......@@ -76,6 +76,7 @@ void pres_process_msg_data(pjsip_tx_data *tdata, const pres_msg_data *msg_data){
}
}
static pj_caching_pool cp;
SIPPresence::SIPPresence(SIPAccount *acc)
: acc_(acc)
......@@ -88,11 +89,24 @@ SIPPresence::SIPPresence(SIPAccount *acc)
, publish_sess()
, publish_state()
, publish_enabled(true)
, newPresenceSubscription_(NULL)
, serverSubscriptions_ ()
, buddies_ ()
, mutex_()
, mutex_nesting_level_()
, mutex_owner_()
, pool_()
, cp_()
{
// init default status
updateStatus("open","Available");
cp_ = &cp;
pj_caching_pool_init(cp_, NULL, 0);
pool_ = pj_pool_create(&(cp_->factory), "pres", 1000, 1000, NULL);
/* Create mutex */
if(pj_mutex_create_recursive(pool_, "pres",&mutex_) != PJ_SUCCESS)
ERROR("Unable to create mutex");
}
......@@ -186,6 +200,27 @@ void SIPPresence::removeBuddy(SIPBuddy *b){
buddies_.remove(b);
}
void SIPPresence::reportNewServerSubscription(PresenceSubscription *s){
newPresenceSubscription_ = s;
Manager::instance().getClient()->getCallManager()->newPresenceSubscription(s->remote);
}
void SIPPresence::confirmNewServerSubscription(const bool& confirm){
if(newPresenceSubscription_!=NULL)
return;
if(confirm){
DEBUG("-Confirm new PresenceSubscription for %s",newPresenceSubscription_->remote);
addServerSubscription(newPresenceSubscription_);
}
else{
DEBUG("-Refused new PresenceSubscription for %s",newPresenceSubscription_->remote);
newPresenceSubscription_ = NULL;
}
}
void SIPPresence::addServerSubscription(PresenceSubscription *s) {
DEBUG("-PresenceServer subscription added.");
serverSubscriptions_.push_back(s);
......@@ -202,3 +237,34 @@ void SIPPresence::notifyServerSubscription() {
for (serverIt = serverSubscriptions_.begin(); serverIt != serverSubscriptions_.end(); serverIt++)
(*serverIt)->notify();
}
void SIPPresence::lock()
{
pj_mutex_lock(mutex_);
mutex_owner_ = pj_thread_this();
++mutex_nesting_level_;
}
void SIPPresence::unlock()
{
if (--mutex_nesting_level_ == 0)
mutex_owner_ = NULL;
pj_mutex_unlock(mutex_);
}
bool SIPPresence::tryLock()
{
pj_status_t status;
status = pj_mutex_trylock(mutex_);
if (status == PJ_SUCCESS) {
mutex_owner_ = pj_thread_this();
++mutex_nesting_level_;
}
return status;
}
bool SIPPresence::isLocked()
{
return mutex_owner_ == pj_thread_this();
}
......@@ -87,12 +87,14 @@ struct pres_msg_data
extern void pres_process_msg_data(pjsip_tx_data *tdata, const pres_msg_data *msg_data);
class SIPAccount;
class SIPBuddy;
class PresenceSubscription;
/**
* TODO Clean this:
*/
struct pj_caching_pool;
/**
* @file sippresence.h
......@@ -163,6 +165,18 @@ public:
*/
void removeBuddy(SIPBuddy *b);
/**
* IP2IP context.
* Report new Subscription to the client, waiting for approval.
* @param s PresenceSubcription pointer.
*/
void reportNewServerSubscription(PresenceSubscription *s);
/**
* IP2IP context.
* Process new subscription based on client decision.
* @param s PresenceSubcription pointer.
*/
void confirmNewServerSubscription(const bool& confirm);
/**
* IP2IP context.
* Add a server associated to a subscriber in the list.
......@@ -181,6 +195,14 @@ public:
*/
void notifyServerSubscription();
/**
* Lock methods
*/
void lock();
void unlock();
bool tryLock();
bool isLocked();
pjsip_pres_status pres_status_data; /**< Presence Data.*/
pj_bool_t online_status; /**< Our online status. */
pjrpid_element rpid; /**< RPID element information.*/
......@@ -190,7 +212,15 @@ public:
private:
NON_COPYABLE(SIPPresence);
pj_mutex_t *mutex_; /**< Mutex protection for this data */
unsigned mutex_nesting_level_; /**< Mutex nesting level. */
pj_thread_t *mutex_owner_; /**< Mutex owner. */
pj_caching_pool *cp_; /**< Global pool factory. */
pj_pool_t *pool_; /**< pjsua's private pool. */
SIPAccount * acc_; /**< Associated SIP account. */
PresenceSubscription *newPresenceSubscription_; /**< Latest Subscribers waiting for approval */
std::list< PresenceSubscription *> serverSubscriptions_; /**< Subscribers list.*/
std::list< SIPBuddy *> buddies_; /**< Subcribed buddy list.*/
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment