Closed #1144: New presence callback to report subscription state (thanks Johan Lantz for the suggestion):
 - added on_buddy_evsub_state() callback
 - added sample implementation in pjsua_app.c


git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@3339 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c
index ead8594..d6150ff 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -2797,6 +2797,37 @@
 }
 
 
+/*
+ * Subscription state has changed.
+ */
+static void on_buddy_evsub_state(pjsua_buddy_id buddy_id,
+				 pjsip_evsub *sub,
+				 pjsip_event *event)
+{
+    char event_info[80];
+
+    PJ_UNUSED_ARG(sub);
+
+    event_info[0] = '\0';
+
+    if (event->type == PJSIP_EVENT_TSX_STATE &&
+	    event->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
+    {
+	pjsip_rx_data *rdata = event->body.tsx_state.src.rdata;
+	snprintf(event_info, sizeof(event_info),
+		 " (RX %s)",
+		 pjsip_rx_data_get_info(rdata));
+    }
+
+    PJ_LOG(4,(THIS_FILE,
+	      "Buddy %d: subscription state: %s (event: %s%s)",
+	      buddy_id, pjsip_evsub_get_state_name(sub),
+	      pjsip_event_str(event->type),
+	      event_info));
+
+}
+
+
 /**
  * Incoming IM message (i.e. MESSAGE request)!
  */
@@ -4602,6 +4633,7 @@
     app_config.cfg.cb.on_reg_state = &on_reg_state;
     app_config.cfg.cb.on_incoming_subscribe = &on_incoming_subscribe;
     app_config.cfg.cb.on_buddy_state = &on_buddy_state;
+    app_config.cfg.cb.on_buddy_evsub_state = &on_buddy_evsub_state;
     app_config.cfg.cb.on_pager = &on_pager;
     app_config.cfg.cb.on_typing = &on_typing;
     app_config.cfg.cb.on_call_transfer_status = &on_call_transfer_status;
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index d178a86..0661bb2 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -687,6 +687,21 @@
      */
     void (*on_buddy_state)(pjsua_buddy_id buddy_id);
 
+
+    /**
+     * Notify application when the state of client subscription session
+     * associated with a buddy has changed. Application may use this
+     * callback to retrieve more detailed information about the state
+     * changed event.
+     *
+     * @param buddy_id	    The buddy id.
+     * @param sub	    Event subscription session.
+     * @param event	    The event which triggers state change event.
+     */
+    void (*on_buddy_evsub_state)(pjsua_buddy_id buddy_id,
+				 pjsip_evsub *sub,
+				 pjsip_event *event);
+
     /**
      * Notify application on incoming pager (i.e. MESSAGE request).
      * Argument call_id will be -1 if MESSAGE request is not related to an
diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c
index 651dad1..a4909b0 100644
--- a/pjsip/src/pjsua-lib/pjsua_pres.c
+++ b/pjsip/src/pjsua-lib/pjsua_pres.c
@@ -1557,7 +1557,11 @@
 	    buddy->term_reason.slen = 0;
 	}
 
-	/* Call callback */
+	/* Call callbacks */
+	if (pjsua_var.ua_cfg.cb.on_buddy_evsub_state)
+	    (*pjsua_var.ua_cfg.cb.on_buddy_evsub_state)(buddy->index, sub,
+							event);
+
 	if (pjsua_var.ua_cfg.cb.on_buddy_state)
 	    (*pjsua_var.ua_cfg.cb.on_buddy_state)(buddy->index);
 
@@ -1656,30 +1660,10 @@
 }
 
 
-/* Event subscription callback. */
-static pjsip_evsub_user pres_callback = 
-{
-    &pjsua_evsub_on_state,  
-    &pjsua_evsub_on_tsx_state,
-
-    NULL,   /* on_rx_refresh: don't care about SUBSCRIBE refresh, unless 
-	     * we want to authenticate 
-	     */
-
-    &pjsua_evsub_on_rx_notify,
-
-    NULL,   /* on_client_refresh: Use default behaviour, which is to 
-	     * refresh client subscription. */
-
-    NULL,   /* on_server_timeout: Use default behaviour, which is to send 
-	     * NOTIFY to terminate. 
-	     */
-};
-
-
 /* It does what it says.. */
 static void subscribe_buddy_presence(pjsua_buddy_id buddy_id)
 {
+    pjsip_evsub_user pres_callback;
     pj_pool_t *tmp_pool = NULL;
     pjsua_buddy *buddy;
     int acc_id;
@@ -1688,6 +1672,12 @@
     pjsip_tx_data *tdata;
     pj_status_t status;
 
+    /* Event subscription callback. */
+    pj_bzero(&pres_callback, sizeof(pres_callback));
+    pres_callback.on_evsub_state = &pjsua_evsub_on_state;
+    pres_callback.on_tsx_state = &pjsua_evsub_on_tsx_state;
+    pres_callback.on_rx_notify = &pjsua_evsub_on_rx_notify;
+
     buddy = &pjsua_var.buddy[buddy_id];
     acc_id = pjsua_acc_find_for_outgoing(&buddy->uri);