Ticket #760: Enhancements to PUBLISH management (thanks Johan Lantz for the suggestion)
 - Changes in PJSUA-LIB
    - retry with fresh request on 412/Conditional Request Failed response
    - changed default Expires in PUBLISH request to none (we will not put Expires), to avoid getting 423/Interval Too Brief response
    - if the PUBLISH fails for any reason, it will be retried on every PJSUA_PRES_TIMER (default 300 seconds), similar to how failed SUBSCRIBE will be retried
 - Changes to publish.h:
    - added API to add headers in every PUBLISH request
 - Added test scenario in Python unit tests



git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2661 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip/src/pjsip-simple/publishc.c b/pjsip/src/pjsip-simple/publishc.c
index 6840d02..2f5b415 100644
--- a/pjsip/src/pjsip-simple/publishc.c
+++ b/pjsip/src/pjsip-simple/publishc.c
@@ -81,6 +81,7 @@
     pjsip_expires_hdr		*expires_hdr;
     pj_uint32_t			 expires;
     pjsip_route_hdr		 route_set;
+    pjsip_hdr			 usr_hdr;
 
     /* Authorization sessions. */
     pjsip_auth_clt_sess		 auth_sess;
@@ -157,6 +158,7 @@
 	return status;
 
     pj_list_init(&pubc->route_set);
+    pj_list_init(&pubc->usr_hdr);
 
     /* Done */
     *p_pubc = pubc;
@@ -186,7 +188,9 @@
 
 static void set_expires( pjsip_publishc *pubc, pj_uint32_t expires)
 {
-    if (expires != pubc->expires) {
+    if (expires != pubc->expires && 
+	expires != PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED) 
+    {
 	pubc->expires_hdr = pjsip_expires_hdr_create(pubc->pool, expires);
     } else {
 	pubc->expires_hdr = NULL;
@@ -281,6 +285,23 @@
     return PJ_SUCCESS;
 }
 
+PJ_DEF(pj_status_t) pjsip_publishc_set_headers( pjsip_publishc *pubc,
+						const pjsip_hdr *hdr_list)
+{
+    const pjsip_hdr *h;
+
+    PJ_ASSERT_RETURN(pubc && hdr_list, PJ_EINVAL);
+
+    pj_list_init(&pubc->usr_hdr);
+    h = hdr_list->next;
+    while (h != hdr_list) {
+	pj_list_push_back(&pubc->usr_hdr, pjsip_hdr_clone(pubc->pool, h));
+	h = h->next;
+    }
+
+    return PJ_SUCCESS;
+}
+
 static pj_status_t create_request(pjsip_publishc *pubc, 
 				  pjsip_tx_data **p_tdata)
 {
@@ -345,6 +366,19 @@
 	    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);
     }
 
+    /* Add user headers */
+    if (!pj_list_empty(&pubc->usr_hdr)) {
+	const pjsip_hdr *hdr;
+
+	hdr = pubc->usr_hdr.next;
+	while (hdr != &pubc->usr_hdr) {
+	    pjsip_hdr *new_hdr = (pjsip_hdr*)
+	    			 pjsip_hdr_shallow_clone(tdata->pool, hdr);
+	    pjsip_msg_add_hdr(tdata->msg, new_hdr);
+	    hdr = hdr->next;
+	}
+    }
+
 
     /* Done. */
     *p_tdata = tdata;
@@ -530,7 +564,7 @@
 	    expires = (pjsip_expires_hdr*)
 	    	      pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL);
 
-	    if (expires)
+	    if (pubc->auto_refresh && expires)
 		expiration = expires->ivalue;
 	    
 	    if (pubc->auto_refresh && expiration!=0 && expiration!=0xFFFF) {