Implement ticket #336: custom presence status in NOTIFY/PUBLISH, supporting subset of RPID elements

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1424 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c
index b92e3e5..854f8cb 100644
--- a/pjsip/src/pjsua-lib/pjsua_acc.c
+++ b/pjsip/src/pjsua-lib/pjsua_acc.c
@@ -430,7 +430,26 @@
     PJ_ASSERT_RETURN(pjsua_var.acc[acc_id].valid, PJ_EINVALIDOP);
 
     pjsua_var.acc[acc_id].online_status = is_online;
-    pjsua_pres_refresh();
+    pj_bzero(&pjsua_var.acc[acc_id].rpid, sizeof(pjrpid_element));
+    pjsua_pres_update_acc(acc_id, PJ_FALSE);
+    return PJ_SUCCESS;
+}
+
+
+/* 
+ * Set online status with extended information 
+ */
+PJ_DEF(pj_status_t) pjsua_acc_set_online_status2( pjsua_acc_id acc_id,
+						  pj_bool_t is_online,
+						  const pjrpid_element *pr)
+{
+    PJ_ASSERT_RETURN(acc_id>=0 && acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc),
+		     PJ_EINVAL);
+    PJ_ASSERT_RETURN(pjsua_var.acc[acc_id].valid, PJ_EINVALIDOP);
+
+    pjsua_var.acc[acc_id].online_status = is_online;
+    pjrpid_element_dup(pjsua_var.pool, &pjsua_var.acc[acc_id].rpid, pr);
+    pjsua_pres_update_acc(acc_id, PJ_TRUE);
     return PJ_SUCCESS;
 }
 
@@ -689,7 +708,14 @@
     info->acc_uri = acc_cfg->id;
     info->has_registration = (acc->cfg.reg_uri.slen > 0);
     info->online_status = acc->online_status;
-    
+    pj_memcpy(&info->rpid, &acc->rpid, sizeof(pjrpid_element));
+    if (info->rpid.note.slen)
+	info->online_status_text = info->rpid.note;
+    else if (info->online_status)
+	info->online_status_text = pj_str("Online");
+    else
+	info->online_status_text = pj_str("Offline");
+
     if (acc->reg_last_err) {
 	info->status = (pjsip_status_code) acc->reg_last_err;
 	pj_strerror(acc->reg_last_err, info->buf_, sizeof(info->buf_));
diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c
index d531695..b544af6 100644
--- a/pjsip/src/pjsua-lib/pjsua_pres.c
+++ b/pjsip/src/pjsua-lib/pjsua_pres.c
@@ -113,7 +113,15 @@
 	info->status_text = pj_str("?");
     } else if (pjsua_var.buddy[buddy_id].status.info[0].basic_open) {
 	info->status = PJSUA_BUDDY_STATUS_ONLINE;
-	info->status_text = pj_str("Online");
+
+	/* copy RPID information */
+	info->rpid = buddy->status.info[0].rpid;
+
+	if (info->rpid.note.slen)
+	    info->status_text = info->rpid.note;
+	else
+	    info->status_text = pj_str("Online");
+
     } else {
 	info->status = PJSUA_BUDDY_STATUS_OFFLINE;
 	info->status_text = pj_str("Offline");
@@ -652,6 +660,9 @@
 	pres_status.info_cnt = 1;
 	pres_status.info[0].basic_open = acc->online_status;
 	pres_status.info[0].id = acc->cfg.pidf_tuple_id;
+	/* .. including RPID information */
+	pj_memcpy(&pres_status.info[0].rpid, &acc->rpid, 
+		  sizeof(pjrpid_element));
 
 	/* Be careful not to send PIDF with presence entity ID containing
 	 * "<" character.
@@ -821,8 +832,8 @@
 }
 
 
-/* Refresh subscription (e.g. when our online status has changed) */
-static void refresh_server_subscription(int acc_id)
+/* Update server subscription (e.g. when our online status has changed) */
+void pjsua_pres_update_acc(int acc_id, pj_bool_t force)
 {
     pjsua_acc *acc = &pjsua_var.acc[acc_id];
     pjsua_acc_config *acc_cfg = &pjsua_var.acc[acc_id].cfg;
@@ -836,8 +847,12 @@
 	pjsip_tx_data *tdata;
 
 	pjsip_pres_get_status(uapres->sub, &pres_status);
-	if (pres_status.info[0].basic_open != acc->online_status) {
+	if (force || pres_status.info[0].basic_open != acc->online_status) {
+
 	    pres_status.info[0].basic_open = acc->online_status;
+	    pj_memcpy(&pres_status.info[0].rpid, &acc->rpid, 
+		      sizeof(pjrpid_element));
+
 	    pjsip_pres_set_status(uapres->sub, &pres_status);
 
 	    if (pjsip_pres_current_notify(uapres->sub, &tdata)==PJ_SUCCESS) {
@@ -855,7 +870,7 @@
      * send the first PUBLISH. 
      */
     if (acc_cfg->publish_enabled && acc->publish_sess) {
-	if (acc->publish_state != acc->online_status) {
+	if (force || acc->publish_state != acc->online_status) {
 	    send_publish(acc_id, PJ_TRUE);
 	}
     }
@@ -1251,7 +1266,7 @@
 
     for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) {
 	if (pjsua_var.acc[i].valid)
-	    refresh_server_subscription(i);
+	    pjsua_pres_update_acc(i, PJ_FALSE);
     }
 }