Ticket #833:
 - Renamed pjsip_timer_default_setting() to pjsip_timer_setting_default().
 - Updated session timer settings in pjsua-lib as whole session timer setting struct (pyhton version remains using se & min_se).
 - Added output param SIP status code in pjsip_timer_process_resp() and pjsip_timer_process_req() to specify the corresponding SIP status code when function returning non-PJ_SUCCESS.
 - Fixed print header functions in sip_timer.c to have buffer check.
 - Added PJSIP_SESS_TIMER_DEF_SE setting to specify the default value of session timer interval.
 - Fixed role reference of the refresher, it is transaction role, not dialog role.




git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2859 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip/src/pjsip-ua/sip_timer.c b/pjsip/src/pjsip-ua/sip_timer.c
index 628e0e2..1200d13 100644
--- a/pjsip/src/pjsip-ua/sip_timer.c
+++ b/pjsip/src/pjsip-ua/sip_timer.c
@@ -27,9 +27,8 @@
 #define THIS_FILE		"sip_timer.c"
 
 
-/* Constant values of Session Timers */
+/* Constant of Session Timers */
 #define ABS_MIN_SE		90	/* Absolute Min-SE, in seconds	    */
-#define DEF_SE			1800	/* Default SE, in seconds	    */
 
 
 /* String definitions */
@@ -60,6 +59,8 @@
     pj_timer_entry		 timer;		/**< Timer entry	    */
     pj_bool_t			 use_update;	/**< Use UPDATE method to
 						     refresh the session    */
+    pjsip_role_e		 role;		/**< Role in last INVITE/
+						     UPDATE transaction.    */
 
 } pjsip_timer;
 
@@ -120,6 +121,10 @@
     const pjsip_parser_const_t *pc = pjsip_parser_const();
     const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;
 
+    /* Print header name and value */
+    if ((endbuf - p) < (hname->slen + 16))
+	return -1;
+
     copy_advance(p, (*hname));
     *p++ = ':';
     *p++ = ' ';
@@ -127,14 +132,19 @@
     printed = pj_utoa(hdr->sess_expires, p);
     p += printed;
 
-    if (hdr->refresher.slen && (endbuf-p) > (hdr->refresher.slen + 2))
+    /* Print 'refresher' param */
+    if (hdr->refresher.slen)
     {
+	if  ((endbuf - p) < (STR_REFRESHER.slen + 2 + hdr->refresher.slen))
+	    return -1;
+
 	*p++ = ';';
 	copy_advance(p, STR_REFRESHER);
 	*p++ = '=';
 	copy_advance(p, hdr->refresher);
     }
 
+    /* Print generic params */
     printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,
 				   &pc->pjsip_TOKEN_SPEC, 
 				   &pc->pjsip_TOKEN_SPEC, ';');
@@ -176,6 +186,10 @@
     int printed;
     const pjsip_parser_const_t *pc = pjsip_parser_const();
 
+    /* Print header name and value */
+    if ((endbuf - p) < (hdr->name.slen + 16))
+	return -1;
+
     copy_advance(p, hdr->name);
     *p++ = ':';
     *p++ = ' ';
@@ -183,6 +197,7 @@
     printed = pj_utoa(hdr->min_se, p);
     p += printed;
 
+    /* Print generic params */
     printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,
 				   &pc->pjsip_TOKEN_SPEC, 
 				   &pc->pjsip_TOKEN_SPEC, ';');
@@ -323,8 +338,8 @@
 
     /* Check our role */
     as_refresher = 
-	(inv->timer->refresher == TR_UAC && inv->role == PJSIP_ROLE_UAC) ||
-	(inv->timer->refresher == TR_UAS && inv->role == PJSIP_ROLE_UAS);
+	(inv->timer->refresher == TR_UAC && inv->timer->role == PJSIP_ROLE_UAC) ||
+	(inv->timer->refresher == TR_UAS && inv->timer->role == PJSIP_ROLE_UAS);
 
     /* Do action based on role, refresher or refreshee */
     if (as_refresher) {
@@ -417,8 +432,8 @@
 			timer_cb);	    /* callback */
     
     /* Set delay based on role, refresher or refreshee */
-    if ((timer->refresher == TR_UAC && inv->role == PJSIP_ROLE_UAC) ||
-	(timer->refresher == TR_UAS && inv->role == PJSIP_ROLE_UAS))
+    if ((timer->refresher == TR_UAC && inv->timer->role == PJSIP_ROLE_UAC) ||
+	(timer->refresher == TR_UAS && inv->timer->role == PJSIP_ROLE_UAS))
     {
 	/* Next refresh, the delay is half of session expire */
 	delay.sec = timer->setting.sess_expires / 2;
@@ -487,11 +502,11 @@
 /*
  * Initialize Session Timers setting with default values.
  */
-PJ_DEF(pj_status_t) pjsip_timer_default_setting(pjsip_timer_setting *setting)
+PJ_DEF(pj_status_t) pjsip_timer_setting_default(pjsip_timer_setting *setting)
 {
     pj_bzero(setting, sizeof(pjsip_timer_setting));
 
-    setting->sess_expires = DEF_SE;
+    setting->sess_expires = PJSIP_SESS_TIMER_DEF_SE;
     setting->min_se = ABS_MIN_SE;
 
     return PJ_SUCCESS;
@@ -526,7 +541,7 @@
 
 	pj_memcpy(s, setting, sizeof(*s));
     } else {
-	pjsip_timer_default_setting(s);
+	pjsip_timer_setting_default(s);
     }
 
     return PJ_SUCCESS;
@@ -604,11 +619,13 @@
  * - 2xx final response
  */
 PJ_DEF(pj_status_t) pjsip_timer_process_resp(pjsip_inv_session *inv,
-					     const pjsip_rx_data *rdata)
+					     const pjsip_rx_data *rdata,
+					     pjsip_status_code *st_code)
 {
     const pjsip_msg *msg;
 
-    PJ_ASSERT_RETURN(inv && rdata, PJ_EINVAL);
+    PJ_ASSERT_ON_FAIL(inv && rdata,
+	{if(st_code)*st_code=PJSIP_SC_INTERNAL_SERVER_ERROR;return PJ_EINVAL;});
 
     /* Check if Session Timers is supported */
     if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0)
@@ -704,6 +721,8 @@
 	     * require or force to use Session Timers.
 	     */
 	    if (inv->options & PJSIP_INV_REQUIRE_TIMER) {
+		if (st_code)
+		    *st_code = PJSIP_SC_EXTENSION_REQUIRED;
 		pjsip_timer_end_session(inv);
 		return PJSIP_ERRNO_FROM_SIP_STATUS(
 					    PJSIP_SC_EXTENSION_REQUIRED);
@@ -726,6 +745,8 @@
 	if (se_hdr && 
 	    se_hdr->sess_expires < inv->timer->setting.min_se)
 	{
+	    if (st_code)
+		*st_code = PJSIP_SC_SESSION_TIMER_TOO_SMALL;
 	    pjsip_timer_end_session(inv);
 	    return PJSIP_ERRNO_FROM_SIP_STATUS(
 					    PJSIP_SC_SESSION_TIMER_TOO_SMALL);
@@ -757,6 +778,9 @@
 
 	PJ_TODO(CHECK_IF_REMOTE_SUPPORT_UPDATE);
 
+	/* Remember our role in this transaction */
+	inv->timer->role = PJSIP_ROLE_UAC;
+
 	/* Finally, set active flag and start the Session Timers */
 	inv->timer->active = PJ_TRUE;
 	start_timer(inv);
@@ -769,14 +793,16 @@
  * Handle incoming INVITE or UPDATE request.
  */
 PJ_DEF(pj_status_t) pjsip_timer_process_req(pjsip_inv_session *inv,
-					    const pjsip_rx_data *rdata)
+					    const pjsip_rx_data *rdata,
+					    pjsip_status_code *st_code)
 {
     pjsip_min_se_hdr *min_se_hdr;
     pjsip_sess_expires_hdr *se_hdr;
     const pjsip_msg *msg;
     unsigned min_se;
 
-    PJ_ASSERT_RETURN(inv && rdata, PJ_EINVAL);
+    PJ_ASSERT_ON_FAIL(inv && rdata,
+	{if(st_code)*st_code=PJSIP_SC_INTERNAL_SERVER_ERROR;return PJ_EINVAL;});
 
     /* Check if Session Timers is supported */
     if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0)
@@ -827,8 +853,11 @@
     /* Validate SE. Session-Expires cannot be lower than Min-SE 
      * (or 90 seconds if Min-SE is not set).
      */
-    if (se_hdr && se_hdr->sess_expires < min_se)
+    if (se_hdr && se_hdr->sess_expires < min_se) {
+	if (st_code)
+	    *st_code = PJSIP_SC_SESSION_TIMER_TOO_SMALL;
 	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_SESSION_TIMER_TOO_SMALL);
+    }
 
     /* Update SE. Note that there is a case that SE is not available in the
      * request (which means remote doesn't want/support it), but local insists
@@ -881,8 +910,11 @@
 
     if (msg->line.status.code/100 == 2)
     {
-	/* Add Session-Expires header and start the timer */
 	if (inv->timer && inv->timer->active) {
+	    /* Remember our role in this transaction */
+	    inv->timer->role = PJSIP_ROLE_UAS;
+
+	    /* Add Session-Expires header and start the timer */
 	    add_timer_headers(inv, tdata, PJ_TRUE, PJ_FALSE);
 	    start_timer(inv);
 	}