Index: pjproject/trunk/pjsip/src/pjsip-simple/presence.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip-simple/presence.c	(revision 230)
+++ pjproject/trunk/pjsip/src/pjsip-simple/presence.c	(revision 268)
@@ -787,4 +787,91 @@
 
 /*
+ * Process the content of incoming NOTIFY request and update temporary
+ * status.
+ *
+ * return PJ_SUCCESS if incoming request is acceptable. If return value
+ *	  is not PJ_SUCCESS, res_hdr may be added with Warning header.
+ */
+static pj_status_t pres_process_rx_notify( pjsip_pres *pres,
+					   pjsip_rx_data *rdata, 
+					   int *p_st_code,
+					   pj_str_t **p_st_text,
+					   pjsip_hdr *res_hdr)
+{
+    pjsip_ctype_hdr *ctype_hdr;
+    pj_status_t status;
+
+    *p_st_text = NULL;
+
+    /* Check Content-Type and msg body are present. */
+    ctype_hdr = rdata->msg_info.ctype;
+
+    if (ctype_hdr==NULL || rdata->msg_info.msg->body==NULL) {
+	
+	pjsip_warning_hdr *warn_hdr;
+	pj_str_t warn_text;
+
+	*p_st_code = PJSIP_SC_BAD_REQUEST;
+
+	warn_text = pj_str("Message body is not present");
+	warn_hdr = pjsip_warning_hdr_create(rdata->tp_info.pool, 399,
+					    pjsip_endpt_name(pres->dlg->endpt),
+					    &warn_text);
+	pj_list_push_back(res_hdr, warn_hdr);
+
+	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);
+    }
+
+    /* Parse content. */
+
+    if (pj_stricmp(&ctype_hdr->media.type, &STR_APPLICATION)==0 &&
+	pj_stricmp(&ctype_hdr->media.subtype, &STR_PIDF_XML)==0)
+    {
+	status = pres_parse_pidf( pres, rdata, &pres->tmp_status);
+    }
+    else 
+    if (pj_stricmp(&ctype_hdr->media.type, &STR_APPLICATION)==0 &&
+	pj_stricmp(&ctype_hdr->media.subtype, &STR_XPIDF_XML)==0)
+    {
+	status = pres_parse_xpidf( pres, rdata, &pres->tmp_status);
+    }
+    else
+    {
+	status = PJSIP_SIMPLE_EBADCONTENT;
+    }
+
+    if (status != PJ_SUCCESS) {
+	/* Unsupported or bad Content-Type */
+	pjsip_accept_hdr *accept_hdr;
+	pjsip_warning_hdr *warn_hdr;
+
+	*p_st_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
+
+	/* Add Accept header */
+	accept_hdr = pjsip_accept_hdr_create(rdata->tp_info.pool);
+	accept_hdr->values[accept_hdr->count++] = STR_APP_PIDF_XML;
+	accept_hdr->values[accept_hdr->count++] = STR_APP_XPIDF_XML;
+	pj_list_push_back(res_hdr, accept_hdr);
+
+	/* Add Warning header */
+	warn_hdr = pjsip_warning_hdr_create_from_status(
+				    rdata->tp_info.pool,
+				    pjsip_endpt_name(pres->dlg->endpt),
+				    status);
+	pj_list_push_back(res_hdr, warn_hdr);
+
+	return status;
+    }
+
+    /* If application calls pres_get_status(), redirect the call to
+     * retrieve the temporary status.
+     */
+    pres->tmp_status._is_valid = PJ_TRUE;
+
+    return PJ_SUCCESS;
+}
+
+
+/*
  * Called when NOTIFY is received.
  */
@@ -796,5 +883,4 @@
 				     pjsip_msg_body **p_body)
 {
-    pjsip_ctype_hdr *ctype_hdr;
     pjsip_pres *pres;
     pj_status_t status;
@@ -803,68 +889,21 @@
     PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});
 
-    /* Check Content-Type and msg body are present. */
-    ctype_hdr = rdata->msg_info.ctype;
-
-    if (ctype_hdr==NULL || rdata->msg_info.msg->body==NULL) {
-	
-	pjsip_warning_hdr *warn_hdr;
-	pj_str_t warn_text;
-
-	*p_st_code = PJSIP_SC_BAD_REQUEST;
-
-	warn_text = pj_str("Message body is not present");
-	warn_hdr = pjsip_warning_hdr_create(rdata->tp_info.pool, 399,
-					    pjsip_endpt_name(pres->dlg->endpt),
-					    &warn_text);
-	pj_list_push_back(res_hdr, warn_hdr);
-
-	return;
-    }
-
-    /* Parse content. */
-
-    if (pj_stricmp(&ctype_hdr->media.type, &STR_APPLICATION)==0 &&
-	pj_stricmp(&ctype_hdr->media.subtype, &STR_PIDF_XML)==0)
-    {
-	status = pres_parse_pidf( pres, rdata, &pres->tmp_status);
-    }
-    else 
-    if (pj_stricmp(&ctype_hdr->media.type, &STR_APPLICATION)==0 &&
-	pj_stricmp(&ctype_hdr->media.subtype, &STR_XPIDF_XML)==0)
-    {
-	status = pres_parse_xpidf( pres, rdata, &pres->tmp_status);
-    }
-    else
-    {
-	status = PJSIP_SIMPLE_EBADCONTENT;
-    }
-
-    if (status != PJ_SUCCESS) {
-	/* Unsupported or bad Content-Type */
-	pjsip_accept_hdr *accept_hdr;
-	pjsip_warning_hdr *warn_hdr;
-
-	*p_st_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
-
-	/* Add Accept header */
-	accept_hdr = pjsip_accept_hdr_create(rdata->tp_info.pool);
-	accept_hdr->values[accept_hdr->count++] = STR_APP_PIDF_XML;
-	accept_hdr->values[accept_hdr->count++] = STR_APP_XPIDF_XML;
-	pj_list_push_back(res_hdr, accept_hdr);
-
-	/* Add Warning header */
-	warn_hdr = pjsip_warning_hdr_create_from_status(
-				    rdata->tp_info.pool,
-				    pjsip_endpt_name(pres->dlg->endpt),
-				    status);
-	pj_list_push_back(res_hdr, warn_hdr);
-
-	return;
-    }
-
-    /* If application calls pres_get_status(), redirect the call to
-     * retrieve the temporary status.
+    /* Only process the message body if it exists, otherwise treat as
+     * presence status is closed. 
      */
-    pres->tmp_status._is_valid = PJ_TRUE;
+    if (rdata->msg_info.msg->body) {
+	status = pres_process_rx_notify( pres, rdata, p_st_code, p_st_text,
+					 res_hdr );
+	if (status != PJ_SUCCESS)
+	    return;
+
+    } else {
+	unsigned i;
+
+	/* Subscription is terminated. Consider contact is offline */
+	pres->tmp_status._is_valid = PJ_TRUE;
+	for (i=0; i<pres->tmp_status.info_cnt; ++i)
+	    pres->tmp_status.info[i].basic_open = PJ_FALSE;
+    }
 
     /* Notify application. */
