Index: pjproject/trunk/pjsip/src/pjsip-simple/presence.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip-simple/presence.c	(revision 2730)
+++ pjproject/trunk/pjsip/src/pjsip-simple/presence.c	(revision 2762)
@@ -74,5 +74,7 @@
     pjsip_dialog	*dlg;		/**< The dialog.		    */
     content_type_e	 content_type;	/**< Content-Type.		    */
+    pj_pool_t		*status_pool;	/**< Pool for pres_status	    */
     pjsip_pres_status	 status;	/**< Presence status.		    */
+    pj_pool_t		*tmp_pool;	/**< Pool for tmp_status	    */
     pjsip_pres_status	 tmp_status;	/**< Temp, before NOTIFY is answred.*/
     pjsip_evsub_user	 user_cb;	/**< The user callback.		    */
@@ -186,4 +188,5 @@
     pj_status_t status;
     pjsip_pres *pres;
+    char obj_name[PJ_MAX_OBJ_NAME];
     pjsip_evsub *sub;
 
@@ -205,4 +208,11 @@
 	pj_memcpy(&pres->user_cb, user_cb, sizeof(pjsip_evsub_user));
 
+    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "pres%p", dlg->pool);
+    pres->status_pool = pj_pool_create(dlg->pool->factory, obj_name, 
+				       512, 512, NULL);
+    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "tmpres%p", dlg->pool);
+    pres->tmp_pool = pj_pool_create(dlg->pool->factory, obj_name, 
+				    512, 512, NULL);
+
     /* Attach to evsub */
     pjsip_evsub_set_mod_data(sub, mod_presence.id, pres);
@@ -229,4 +239,5 @@
     pjsip_evsub *sub;
     pjsip_pres *pres;
+    char obj_name[PJ_MAX_OBJ_NAME];
     pj_status_t status;
 
@@ -298,4 +309,11 @@
 	pj_memcpy(&pres->user_cb, user_cb, sizeof(pjsip_evsub_user));
 
+    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "pres%p", dlg->pool);
+    pres->status_pool = pj_pool_create(dlg->pool->factory, obj_name, 
+				       512, 512, NULL);
+    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "tmpres%p", dlg->pool);
+    pres->tmp_pool = pj_pool_create(dlg->pool->factory, obj_name, 
+				    512, 512, NULL);
+
     /* Attach to evsub */
     pjsip_evsub_set_mod_data(sub, mod_presence.id, pres);
@@ -356,8 +374,11 @@
     PJ_ASSERT_RETURN(pres!=NULL, PJSIP_SIMPLE_ENOPRESENCE);
 
-    if (pres->tmp_status._is_valid)
+    if (pres->tmp_status._is_valid) {
+	PJ_ASSERT_RETURN(pres->tmp_pool!=NULL, PJSIP_SIMPLE_ENOPRESENCE);
 	pj_memcpy(status, &pres->tmp_status, sizeof(pjsip_pres_status));
-    else
+    } else {
+	PJ_ASSERT_RETURN(pres->status_pool!=NULL, PJSIP_SIMPLE_ENOPRESENCE);
 	pj_memcpy(status, &pres->status, sizeof(pjsip_pres_status));
+    }
 
     return PJ_SUCCESS;
@@ -372,4 +393,5 @@
 {
     unsigned i;
+    pj_pool_t *tmp;
     pjsip_pres *pres;
 
@@ -381,5 +403,7 @@
     for (i=0; i<status->info_cnt; ++i) {
 	pres->status.info[i].basic_open = status->info[i].basic_open;
-	if (status->info[i].id.slen == 0) {
+	if (pres->status.info[i].id.slen) {
+	    /* Id already set */
+	} else if (status->info[i].id.slen == 0) {
 	    pj_create_unique_string(pres->dlg->pool, 
 	    			    &pres->status.info[i].id);
@@ -389,5 +413,5 @@
 		      &status->info[i].id);
 	}
-	pj_strdup(pres->dlg->pool, 
+	pj_strdup(pres->tmp_pool, 
 		  &pres->status.info[i].contact,
 		  &status->info[i].contact);
@@ -396,8 +420,8 @@
 	pres->status.info[i].rpid.activity = 
 	    status->info[i].rpid.activity;
-	pj_strdup(pres->dlg->pool, 
+	pj_strdup(pres->tmp_pool, 
 		  &pres->status.info[i].rpid.id,
 		  &status->info[i].rpid.id);
-	pj_strdup(pres->dlg->pool,
+	pj_strdup(pres->tmp_pool,
 		  &pres->status.info[i].rpid.note,
 		  &status->info[i].rpid.note);
@@ -406,4 +430,10 @@
 
     pres->status.info_cnt = status->info_cnt;
+
+    /* Swap pools */
+    tmp = pres->tmp_pool;
+    pres->tmp_pool = pres->status_pool;
+    pres->status_pool = tmp;
+    pj_pool_reset(pres->tmp_pool);
 
     return PJ_SUCCESS;
@@ -573,4 +603,15 @@
     if (pres->user_cb.on_evsub_state)
 	(*pres->user_cb.on_evsub_state)(sub, event);
+
+    if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
+	if (pres->status_pool) {
+	    pj_pool_release(pres->status_pool);
+	    pres->status_pool = NULL;
+	}
+	if (pres->tmp_pool) {
+	    pj_pool_release(pres->tmp_pool);
+	    pres->tmp_pool = NULL;
+	}
+    }
 }
 
@@ -671,5 +712,5 @@
 	pj_stricmp(&ctype_hdr->media.subtype, &STR_PIDF_XML)==0)
     {
-	status = pjsip_pres_parse_pidf( rdata, pres->dlg->pool,
+	status = pjsip_pres_parse_pidf( rdata, pres->tmp_pool,
 					&pres->tmp_status);
     }
@@ -678,5 +719,5 @@
 	pj_stricmp(&ctype_hdr->media.subtype, &STR_XPIDF_XML)==0)
     {
-	status = pjsip_pres_parse_xpidf( rdata, pres->dlg->pool,
+	status = pjsip_pres_parse_xpidf( rdata, pres->tmp_pool,
 					 &pres->tmp_status);
     }
@@ -741,9 +782,21 @@
 
     } else {
+#if 1
+	/* This is the newest change, http://trac.pjsip.org/repos/ticket/873
+	 * Some app want to be notified about the empty NOTIFY, e.g. to 
+	 * decide whether it should consider the buddy as offline.
+	 * In this case, leave the buddy state unchanged, but set the
+	 * "tuple_node" in pjsip_pres_status to NULL.
+	 */
+	unsigned i;
+	for (i=0; i<pres->status.info_cnt; ++i) {
+	    pres->status.info[i].tuple_node = NULL;
+	}
+
+#elif 0
 	/* This has just been changed. Previously, we treat incoming NOTIFY
 	 * with no message body as having the presence subscription closed.
 	 * Now we treat it as no change in presence status (ref: EyeBeam).
 	 */
-#if 1
 	*p_st_code = 200;
 	return;
@@ -768,8 +821,16 @@
      */
     if ((*p_st_code)/100 == 2) {
+	pj_pool_t *tmp;
+
 	pj_memcpy(&pres->status, &pres->tmp_status, sizeof(pjsip_pres_status));
+
+	/* Swap the pool */
+	tmp = pres->tmp_pool;
+	pres->tmp_pool = pres->status_pool;
+	pres->status_pool = tmp;
     }
 
     pres->tmp_status._is_valid = PJ_FALSE;
+    pj_pool_reset(pres->tmp_pool);
 
     /* Done */
