Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 3796)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 3841)
@@ -972,5 +972,5 @@
     options |= PJSIP_INV_SUPPORT_100REL;
     options |= PJSIP_INV_SUPPORT_TIMER;
-    if (pjsua_var.acc[acc_id].cfg.require_100rel)
+    if (pjsua_var.acc[acc_id].cfg.require_100rel == PJSUA_100REL_MANDATORY)
 	options |= PJSIP_INV_REQUIRE_100REL;
     if (pjsua_var.media_cfg.enable_ice)
@@ -1046,4 +1046,17 @@
     {
 	options &= ~(PJSIP_INV_SUPPORT_TIMER);
+    }
+
+    /* If 100rel is optional and UAC supports it, use it. */
+    if ((options & PJSIP_INV_REQUIRE_100REL)==0 &&
+	pjsua_var.acc[acc_id].cfg.require_100rel == PJSUA_100REL_OPTIONAL)
+    {
+	const pj_str_t token = { "100rel", 6};
+	pjsip_dialog_cap_status cap_status;
+
+	cap_status = pjsip_dlg_remote_has_cap(dlg, PJSIP_H_SUPPORTED, NULL,
+	                                      &token);
+	if (cap_status == PJSIP_DIALOG_CAP_SUPPORTED)
+	    options |= PJSIP_INV_REQUIRE_100REL;
     }
 
@@ -1289,4 +1302,5 @@
 
     pj_gettimeofday(&time_start);
+    timeout.sec = 0;
     timeout.msec = PJSUA_ACQUIRE_CALL_TIMEOUT;
     pj_time_val_normalize(&timeout);
@@ -1357,18 +1371,22 @@
 {
     pjsua_call *call;
-    pjsua_conf_port_id port_id;
-    pjsip_dialog *dlg;
-    pj_status_t status;
+    pjsua_conf_port_id port_id = PJSUA_INVALID_ID;
 
     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls, 
 		     PJ_EINVAL);
 
-    status = acquire_call("pjsua_call_get_conf_port()", call_id, &call, &dlg);
-    if (status != PJ_SUCCESS)
-	return PJSUA_INVALID_ID;
-
+    /* Use PJSUA_LOCK() instead of acquire_call():
+     *  https://trac.pjsip.org/repos/ticket/1371
+     */
+    PJSUA_LOCK();
+
+    if (!pjsua_call_is_active(call_id))
+	goto on_return;
+
+    call = &pjsua_var.calls[call_id];
     port_id = call->media[call->audio_idx].strm.a.conf_slot;
 
-    pjsip_dlg_dec_lock(dlg);
+on_return:
+    PJSUA_UNLOCK();
 
     return port_id;
@@ -1384,7 +1402,5 @@
 {
     pjsua_call *call;
-    pjsip_dialog *dlg;
     unsigned mi;
-    pj_status_t status;
 
     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
@@ -1393,7 +1409,14 @@
     pj_bzero(info, sizeof(*info));
 
-    status = acquire_call("pjsua_call_get_info()", call_id, &call, &dlg);
-    if (status != PJ_SUCCESS) {
-	return status;
+    /* Use PJSUA_LOCK() instead of acquire_call():
+     *  https://trac.pjsip.org/repos/ticket/1371
+     */
+    PJSUA_LOCK();
+
+    call = &pjsua_var.calls[call_id];
+
+    if (!call->inv) {
+	PJSUA_UNLOCK();
+	return PJSIP_ESESSIONTERMINATED;
     }
 
@@ -1521,5 +1544,5 @@
     }
 
-    pjsip_dlg_dec_lock(dlg);
+    PJSUA_UNLOCK();
 
     return PJ_SUCCESS;
@@ -1962,8 +1985,12 @@
     pjsua_process_msg_data( tdata, msg_data);
 
+    /* Record the tx_data to keep track the operation */
+    call->hold_msg = (void*) tdata;
+
     /* Send the request */
     status = pjsip_inv_send_msg( call->inv, tdata);
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
+	call->hold_msg = NULL;
 	goto on_return;
     }
@@ -2532,5 +2559,6 @@
     pj_log_push_indent();
 
-    PJSUA_LOCK();
+    // This may deadlock, see https://trac.pjsip.org/repos/ticket/1305
+    //PJSUA_LOCK();
 
     for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
@@ -2539,5 +2567,5 @@
     }
 
-    PJSUA_UNLOCK();
+    //PJSUA_UNLOCK();
     pj_log_pop_indent();
 }
@@ -3972,7 +4000,20 @@
 	    }
 	}
+    } else if (tsx->role == PJSIP_ROLE_UAC &&
+	       tsx->last_tx == (pjsip_tx_data*)call->hold_msg &&
+	       tsx->state >= PJSIP_TSX_STATE_COMPLETED)
+    {
+	/* Monitor the status of call hold request */
+	call->hold_msg = NULL;
+	if (tsx->status_code/100 != 2) {
+	    /* Outgoing call hold failed */
+	    call->local_hold = PJ_FALSE;
+	    PJ_LOG(3,(THIS_FILE, "Error putting call %d on hold (reason=%d)",
+		      call->index, tsx->status_code));
+	}
     }
 
 on_return:
+
     PJSUA_UNLOCK();
     pj_log_pop_indent();
