diff --git a/daemon/src/client/callmanager.h b/daemon/src/client/callmanager.h
index c2189a6dfe69b98afba904e2926d931d65bee2a3..57eea4c93804fbdec8d6fa2fdb803de643a11353 100644
--- a/daemon/src/client/callmanager.h
+++ b/daemon/src/client/callmanager.h
@@ -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
diff --git a/daemon/src/client/dbus/callmanager-introspec.xml b/daemon/src/client/dbus/callmanager-introspec.xml
index b0e9954dc0cadd00d811ebe09f9b07e5bdcffefd..47a22e47f7ffb43b1b8525c4c02d708f2fd7231a 100644
--- a/daemon/src/client/dbus/callmanager-introspec.xml
+++ b/daemon/src/client/dbus/callmanager-introspec.xml
@@ -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>
diff --git a/daemon/src/client/dbus/callmanager.cpp b/daemon/src/client/dbus/callmanager.cpp
index 3dc6e0757caef877bbf87049228ecb8237231852..4178ada940d5b033e48e38424732044c19d9bf9c 100644
--- a/daemon/src/client/dbus/callmanager.cpp
+++ b/daemon/src/client/dbus/callmanager.cpp
@@ -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);
+}
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index 0570709039d7d68da815ffcc004ff9c4eea97fe4..87bfd451c5d0418c94f57d85d6f38cd3aaa26813 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -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());
diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h
index db78baec8ca6aa8ada62b2fd081406cbae5c2055..246754405180c38b077391f7b5fc84f090a6fb36 100644
--- a/daemon/src/managerimpl.h
+++ b/daemon/src/managerimpl.h
@@ -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);
diff --git a/daemon/src/sip/presence_subscription.cpp b/daemon/src/sip/presence_subscription.cpp
index fbdd96ab24f135f7fab39cf3c9500cbb49914461..d568de280479f138be8e29f4b178ab3d8b81367a 100644
--- a/daemon/src/sip/presence_subscription.cpp
+++ b/daemon/src/sip/presence_subscription.cpp
@@ -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;
 }
 
diff --git a/daemon/src/sip/presence_subscription.h b/daemon/src/sip/presence_subscription.h
index c70d41a00da3c5af6f1a4edb5e7b74b816fef63f..f9860e48f3bf5807a646c62274217099b37df224 100644
--- a/daemon/src/sip/presence_subscription.h
+++ b/daemon/src/sip/presence_subscription.h
@@ -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()		*/
diff --git a/daemon/src/sip/sipbuddy.h b/daemon/src/sip/sipbuddy.h
index d0dda6c93ac5684fdf15df1fdf4d6b995656460e..ace2903028c80a192507431dcdbbb91c57515209 100644
--- a/daemon/src/sip/sipbuddy.h
+++ b/daemon/src/sip/sipbuddy.h
@@ -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++;
         }
diff --git a/daemon/src/sip/sippresence.cpp b/daemon/src/sip/sippresence.cpp
index a44cf11e10ea44fc4f75d20d1be496177a6c947f..ee3ddca8599c1b8bd4f0c5dea6c98cccc1ede379 100644
--- a/daemon/src/sip/sippresence.cpp
+++ b/daemon/src/sip/sippresence.cpp
@@ -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();
+}
diff --git a/daemon/src/sip/sippresence.h b/daemon/src/sip/sippresence.h
index e05e49076c0d894f2fab5eea328026669c6b1b8a..98b8978da13b643000c595c902e86a8d24498590 100644
--- a/daemon/src/sip/sippresence.h
+++ b/daemon/src/sip/sippresence.h
@@ -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.*/
 };