summaryrefslogtreecommitdiff
path: root/pjsip/src/pjsua-lib/pjsua_call.c
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2008-08-04 15:01:38 +0000
committerNanang Izzuddin <nanang@teluu.com>2008-08-04 15:01:38 +0000
commit1adb6e34e661bb7de2b27423b6e80f2510e38af0 (patch)
treecf932de4cebdef7e7d7e3827e3bf4dc8d255519e /pjsip/src/pjsua-lib/pjsua_call.c
parent98dc6db2fc17166e04ffebe294928620eb604c44 (diff)
Ticket #563: Updated SDP offer/answer related to call hold scenario to conform to RFC 3264 section 8.4 (before: 'a=inactive' and 'c=0.0.0.0', now: 'a=sendonly' and muted ports).
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2191 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src/pjsua-lib/pjsua_call.c')
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c155
1 files changed, 78 insertions, 77 deletions
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index bedc5fab..114da50d 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -66,10 +66,9 @@ static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
pjsip_event *e);
-
-/* Create inactive SDP for call hold. */
-static pj_status_t create_inactive_sdp(pjsua_call *call,
- pjmedia_sdp_session **p_answer);
+/* Create SDP for call hold. */
+static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
+ pjmedia_sdp_session **p_answer);
/* Update SDP version in the offer */
static void update_sdp_version(pjsua_call *call,
@@ -117,6 +116,7 @@ static void reset_call(pjsua_call_id id)
call->res_time.msec = 0;
call->rem_nat_type = PJ_STUN_NAT_TYPE_UNKNOWN;
call->rem_srtp_use = PJMEDIA_SRTP_DISABLED;
+ call->local_hold = PJ_FALSE;
}
@@ -1426,7 +1426,7 @@ PJ_DEF(pj_status_t) pjsua_call_set_hold(pjsua_call_id call_id,
return PJSIP_ESESSIONSTATE;
}
- status = create_inactive_sdp(call, &sdp);
+ status = create_sdp_of_call_hold(call, &sdp);
if (status != PJ_SUCCESS) {
pjsip_dlg_dec_lock(dlg);
return status;
@@ -1453,6 +1453,9 @@ PJ_DEF(pj_status_t) pjsua_call_set_hold(pjsua_call_id call_id,
return status;
}
+ /* Set flag that local put the call on hold */
+ call->local_hold = PJ_TRUE;
+
pjsip_dlg_dec_lock(dlg);
return PJ_SUCCESS;
@@ -1487,10 +1490,13 @@ PJ_DEF(pj_status_t) pjsua_call_reinvite( pjsua_call_id call_id,
}
/* Create SDP */
- PJ_UNUSED_ARG(unhold);
- PJ_TODO(create_active_inactive_sdp_based_on_unhold_arg);
- status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,
- NULL, &sdp, NULL);
+ if (call->local_hold && !unhold) {
+ status = create_sdp_of_call_hold(call, &sdp);
+ } else {
+ status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,
+ NULL, &sdp, NULL);
+ call->local_hold = PJ_FALSE;
+ }
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",
status);
@@ -1573,11 +1579,13 @@ PJ_DEF(pj_status_t) pjsua_call_update( pjsua_call_id call_id,
/* Send the request */
status = pjsip_inv_send_msg( call->inv, tdata);
if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Unable to send UPDAT Erequest", status);
+ pjsua_perror(THIS_FILE, "Unable to send UPDATE request", status);
pjsip_dlg_dec_lock(dlg);
return status;
}
+ call->local_hold = PJ_FALSE;
+
pjsip_dlg_dec_lock(dlg);
return PJ_SUCCESS;
@@ -3012,116 +3020,109 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv,
}
-/*
- * Create inactive SDP for call hold.
- */
-static pj_status_t create_inactive_sdp(pjsua_call *call,
- pjmedia_sdp_session **p_answer)
+/* 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_conn *conn;
- pjmedia_sdp_attr *attr;
- pjmedia_transport_info tp_info;
pjmedia_sdp_session *sdp;
/* Use call's pool */
pool = call->inv->pool;
- /* Get media socket info */
- pjmedia_transport_info_init(&tp_info);
- pjmedia_transport_get_info(call->med_tp, &tp_info);
-
/* Create new offer */
- status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, pool, 1,
- &tp_info.sock_info, &sdp);
+ 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;
}
- /* 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);
+ /* Call-hold is done by set the media direction to 'sendonly'
+ * (PJMEDIA_DIR_ENCODING), except when current media direction is
+ * 'inactive' (PJMEDIA_DIR_NONE).
+ * (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1)
+ */
+ if (call->media_dir != PJMEDIA_DIR_ENCODING) {
+ pjmedia_sdp_attr *attr;
+
+ /* 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");
+
+ if (call->media_dir == PJMEDIA_DIR_ENCODING_DECODING) {
+ /* Add sendonly attribute */
+ attr = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
+ pjmedia_sdp_media_add_attr(sdp->media[0], attr);
+ } else {
+ /* Add inactive attribute */
+ attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
+ pjmedia_sdp_media_add_attr(sdp->media[0], attr);
+ }
+ }
*p_answer = sdp;
return status;
}
-
/*
* Called when session received new offer.
*/
static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
const pjmedia_sdp_session *offer)
{
- const char *remote_state;
pjsua_call *call;
pjmedia_sdp_conn *conn;
pjmedia_sdp_session *answer;
- pj_bool_t is_remote_active;
pj_status_t status;
PJSUA_LOCK();
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
- /*
- * See if remote is offering active media (i.e. not on-hold)
- */
- is_remote_active = PJ_TRUE;
-
conn = offer->media[0]->conn;
if (!conn)
conn = offer->conn;
+ /* Supply candidate answer */
+ PJ_LOG(4,(THIS_FILE, "Call %d: received updated media offer",
+ call->index));
+
+ status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,
+ offer, &answer, NULL);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
+ PJSUA_UNLOCK();
+ return;
+ }
+
+ /* Check if offer's conn address is zero */
if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 ||
pj_strcmp2(&conn->addr, "0")==0)
{
- is_remote_active = PJ_FALSE;
-
- }
- else if (pjmedia_sdp_media_find_attr2(offer->media[0], "inactive", NULL) ||
- pjmedia_sdp_media_find_attr2(offer->media[0], "sendonly", NULL))
- {
- is_remote_active = PJ_FALSE;
+ /* Modify address */
+ answer->conn->addr = pj_str("0.0.0.0");
}
- remote_state = (is_remote_active ? "active" : "inactive");
+ /* Check if call is on-hold */
+ if (call->local_hold) {
+ pjmedia_sdp_attr *attr;
- /* Supply candidate answer */
- if (call->media_st == PJSUA_CALL_MEDIA_LOCAL_HOLD || !is_remote_active) {
- PJ_LOG(4,(THIS_FILE,
- "Call %d: RX new media offer, creating inactive SDP "
- "(media in offer is %s)", call->index, remote_state));
- status = create_inactive_sdp( call, &answer );
- } else {
- PJ_LOG(4,(THIS_FILE, "Call %d: received updated media offer",
- call->index));
+ /* 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");
- status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,
- offer, &answer, NULL);
- }
-
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
- PJSUA_UNLOCK();
- return;
+ /* 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, "sendonly", NULL);
+ pjmedia_sdp_media_add_attr(answer->media[0], attr);
}
status = pjsip_inv_set_sdp_answer(call->inv, answer);
@@ -3149,11 +3150,11 @@ static void pjsua_call_on_create_offer(pjsip_inv_session *inv,
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
/* See if we've put call on hold. */
- if (call->media_st == PJSUA_CALL_MEDIA_LOCAL_HOLD) {
+ if (call->local_hold) {
PJ_LOG(4,(THIS_FILE,
- "Call %d: call is on-hold locally, creating inactive SDP ",
+ "Call %d: call is on-hold locally, creating call-hold SDP ",
call->index));
- status = create_inactive_sdp( call, offer );
+ status = create_sdp_of_call_hold( call, offer );
} else {
PJ_LOG(4,(THIS_FILE, "Call %d: asked to send a new offer",
call->index));