Index: pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 3329)
+++ pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 3330)
@@ -2042,4 +2042,43 @@
 
 /**
+ * This enumeration specifies how we should offer call hold request to
+ * remote peer. The default value is set by compile time constant
+ * PJSUA_CALL_HOLD_TYPE_DEFAULT, and application may control the setting
+ * on per-account basis by manipulating \a call_hold_type field in
+ * #pjsua_acc_config.
+ */
+typedef enum pjsua_call_hold_type
+{
+    /**
+     * This will follow RFC 3264 recommendation to use a=sendonly,
+     * a=recvonly, and a=inactive attribute as means to signal call
+     * hold status. This is the correct value to use.
+     */
+    PJSUA_CALL_HOLD_TYPE_RFC3264,
+
+    /**
+     * This will use the old and deprecated method as specified in RFC 2543,
+     * and will offer c=0.0.0.0 in the SDP instead. Using this has many
+     * drawbacks such as inability to keep the media transport alive while
+     * the call is being put on hold, and should only be used if remote
+     * does not understand RFC 3264 style call hold offer.
+     */
+    PJSUA_CALL_HOLD_TYPE_RFC2543
+
+} pjsua_call_hold_type;
+
+
+/**
+ * Specify the default call hold type to be used in #pjsua_acc_config.
+ *
+ * Default is PJSUA_CALL_HOLD_TYPE_RFC3264, and there's no reason to change
+ * this except if you're communicating with an old/non-standard peer.
+ */
+#ifndef PJSUA_CALL_HOLD_TYPE_DEFAULT
+#   define PJSUA_CALL_HOLD_TYPE_DEFAULT		PJSUA_CALL_HOLD_TYPE_RFC3264
+#endif
+
+
+/**
  * This structure describes account configuration to be specified when
  * adding a new account with #pjsua_acc_add(). Application MUST initialize
@@ -2370,4 +2409,12 @@
     pj_bool_t	     use_stream_ka;
 #endif
+
+    /**
+     * Specify how to offer call hold to remote peer. Please see the
+     * documentation on #pjsua_call_hold_type for more info.
+     *
+     * Default: PJSUA_CALL_HOLD_TYPE_DEFAULT
+     */
+    pjsua_call_hold_type call_hold_type;
 
 } pjsua_acc_config;
Index: pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 3329)
+++ pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 3330)
@@ -62,4 +62,5 @@
     pjsua_acc_id	 acc_id;    /**< Account index being used.	    */
     int			 secure_level;/**< Signaling security level.	    */
+    pjsua_call_hold_type call_hold_type; /**< How to do call hold.	    */
     pj_bool_t		 local_hold;/**< Flag for call-hold by local.	    */
     pjsua_call_media_status media_st;/**< Media state.			    */
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 3329)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 3330)
@@ -83,5 +83,5 @@
 /* Create SDP for call hold. */
 static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
-					   pjmedia_sdp_session **p_answer);
+					   pjmedia_sdp_session **p_sdp);
 
 /*
@@ -405,4 +405,5 @@
     /* Associate session with account */
     call->acc_id = acc_id;
+    call->call_hold_type = acc->cfg.call_hold_type;
 
     /* Create temporary pool */
@@ -759,4 +760,5 @@
      */
     acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata);
+    call->call_hold_type = pjsua_var.acc[acc_id].cfg.call_hold_type;
 
     /* Get call's secure level */
@@ -3574,23 +3576,9 @@
 
 
-/* Create SDP for call hold. */
-static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
-					   pjmedia_sdp_session **p_answer)
-{
-    pj_status_t status;
-    pj_pool_t *pool;
-    pjmedia_sdp_session *sdp;
-
-    /* Use call's provisional pool */
-    pool = call->inv->pool_prov;
-
-    /* Create new offer */
-    status = pjsua_media_channel_create_sdp(call->index, pool, NULL, &sdp, 
-					    NULL);
-    if (status != PJ_SUCCESS) {
-	pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
-	return status;
-    }
-
+/* Modify SDP for call hold. */
+static pj_status_t modify_sdp_of_call_hold(pjsua_call *call,
+					   pj_pool_t *pool,
+					   pjmedia_sdp_session *sdp)
+{
     /* Call-hold is done by set the media direction to 'sendonly' 
      * (PJMEDIA_DIR_ENCODING), except when current media direction is 
@@ -3601,5 +3589,31 @@
        if (call->media_dir != PJMEDIA_DIR_ENCODING) {
      */
-    if (1) {
+    /* https://trac.pjsip.org/repos/ticket/1142:
+     *  configuration to use c=0.0.0.0 for call hold.
+     */
+    if (call->call_hold_type == PJSUA_CALL_HOLD_TYPE_RFC2543) {
+	pjmedia_sdp_conn *conn;
+	pjmedia_sdp_attr *attr;
+
+	/* Get SDP media connection line */
+	conn = sdp->media[0]->conn;
+	if (!conn)
+	    conn = sdp->conn;
+
+	/* Modify address */
+	conn->addr = pj_str("0.0.0.0");
+
+	/* Remove existing directions attributes */
+	pjmedia_sdp_media_remove_all_attr(sdp->media[0], "sendrecv");
+	pjmedia_sdp_media_remove_all_attr(sdp->media[0], "sendonly");
+	pjmedia_sdp_media_remove_all_attr(sdp->media[0], "recvonly");
+	pjmedia_sdp_media_remove_all_attr(sdp->media[0], "inactive");
+
+	/* Add inactive attribute */
+	attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
+	pjmedia_sdp_media_add_attr(sdp->media[0], attr);
+
+
+    } else {
 	pjmedia_sdp_attr *attr;
 
@@ -3621,7 +3635,33 @@
     }
 
-    *p_answer = sdp;
-
-    return status;
+    return PJ_SUCCESS;
+}
+
+/* Create SDP for call hold. */
+static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
+					   pjmedia_sdp_session **p_sdp)
+{
+    pj_status_t status;
+    pj_pool_t *pool;
+    pjmedia_sdp_session *sdp;
+
+    /* Use call's provisional pool */
+    pool = call->inv->pool_prov;
+
+    /* Create new offer */
+    status = pjsua_media_channel_create_sdp(call->index, pool, NULL, &sdp,
+					    NULL);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
+	return status;
+    }
+
+    status = modify_sdp_of_call_hold(call, pool, sdp);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    *p_sdp = sdp;
+
+    return PJ_SUCCESS;
 }
 
@@ -3668,17 +3708,5 @@
     /* Check if call is on-hold */
     if (call->local_hold) {
-        pjmedia_sdp_attr *attr;
-
-	/* Remove existing directions attributes */
-	pjmedia_sdp_media_remove_all_attr(answer->media[0], "sendrecv");
-	pjmedia_sdp_media_remove_all_attr(answer->media[0], "sendonly");
-	pjmedia_sdp_media_remove_all_attr(answer->media[0], "recvonly");
-	pjmedia_sdp_media_remove_all_attr(answer->media[0], "inactive");
-
-	/* Keep call on-hold by setting 'sendonly' attribute.
-	 * (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1)
-	 */
-	attr = pjmedia_sdp_attr_create(call->inv->pool_prov, "sendonly", NULL);
-	pjmedia_sdp_media_add_attr(answer->media[0], attr);
+	modify_sdp_of_call_hold(call, call->inv->pool_prov, answer);
     }
 
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 3329)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 3330)
@@ -190,4 +190,5 @@
 #endif
     pj_list_init(&cfg->reg_hdr_list);
+    cfg->call_hold_type = PJSUA_CALL_HOLD_TYPE_DEFAULT;
 }
 
