summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorLiong Sauw Ming <ming@teluu.com>2014-10-17 00:47:31 +0000
committerLiong Sauw Ming <ming@teluu.com>2014-10-17 00:47:31 +0000
commit2fbb30b3d3afb464b97a61369a71aa90ec3fcc47 (patch)
treec7b0be49ad1e962a86e6c128016c9823dfd3028a /pjsip
parent3e7d2fbe0b45b43a30e5c107208550cb20ebd736 (diff)
Fixed #1797: Clean up provisional media after re-invite/update
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4948 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsua-lib/pjsua_internal.h2
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c70
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c8
3 files changed, 61 insertions, 19 deletions
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h
index 2c60f597..bffe07f6 100644
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -142,6 +142,8 @@ struct pjsua_call
unsigned med_prov_cnt;/**< Number of provisional media. */
pjsua_call_media media_prov[PJSUA_MAX_CALL_MEDIA];
/**< Array of provisional media. */
+ pj_bool_t med_update_success;
+ /**< Is media update successful? */
int audio_idx; /**< First active audio media. */
pj_mutex_t *med_ch_mutex;/**< Media channel callback's mutex. */
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index f9cae68f..cf72d6e5 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -48,6 +48,12 @@ const pjsip_method pjsip_info_method =
{ "INFO", 4 }
};
+/* UPDATE method */
+static const pjsip_method pjsip_update_method =
+{
+ PJSIP_OTHER_METHOD,
+ { "UPDATE", 6 }
+};
/* This callback receives notification from invite session when the
* session state has changed.
@@ -2508,6 +2514,7 @@ PJ_DEF(pj_status_t) pjsua_call_reinvite2(pjsua_call_id call_id,
pjsua_process_msg_data( tdata, msg_data);
/* Send the request */
+ call->med_update_success = PJ_FALSE;
status = pjsip_inv_send_msg( call->inv, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
@@ -2616,6 +2623,7 @@ PJ_DEF(pj_status_t) pjsua_call_update2(pjsua_call_id call_id,
pjsua_process_msg_data( tdata, msg_data);
/* Send the request */
+ call->med_update_success = PJ_FALSE;
status = pjsip_inv_send_msg( call->inv, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send UPDATE request", status);
@@ -3814,6 +3822,8 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv,
goto on_return;
}
+ call->med_update_success = (status == PJ_SUCCESS);
+
/* Update remote's NAT type */
if (pjsua_var.ua_cfg.nat_type_in_sdp) {
update_remote_nat_type(call, remote_sdp);
@@ -4681,29 +4691,51 @@ static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
}
}
} else if (tsx->role == PJSIP_ROLE_UAC &&
- tsx->last_tx == (pjsip_tx_data*)call->hold_msg &&
- tsx->state >= PJSIP_TSX_STATE_COMPLETED)
+ pjsip_method_cmp(&tsx->method, &pjsip_invite_method)==0 &&
+ tsx->state >= PJSIP_TSX_STATE_COMPLETED &&
+ (tsx->status_code!=401 && tsx->status_code!=407))
{
- /* 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));
- }
+ if (tsx->status_code/100 != 2) {
+ /* Monitor the status of call hold/unhold request */
+ if (tsx->last_tx == (pjsip_tx_data*)call->hold_msg) {
+ /* 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));
+ } else if (call->opt.flag & PJSUA_CALL_UNHOLD) {
+ /* Call unhold failed */
+ call->local_hold = PJ_TRUE;
+ PJ_LOG(3,(THIS_FILE, "Error releasing hold on call %d "
+ "(reason=%d)", call->index, tsx->status_code));
+ }
+ }
+
+ if (tsx->last_tx == (pjsip_tx_data*)call->hold_msg) {
+ call->hold_msg = NULL;
+ }
+
+ if (tsx->status_code/100 != 2 ||
+ ((call->opt.flag & PJSUA_CALL_NO_SDP_OFFER) == 0 &&
+ !call->med_update_success))
+ {
+ /* Either we get non-2xx or media update failed,
+ * clean up provisional media.
+ */
+ pjsua_media_prov_clean_up(call->index);
+ }
} else if (tsx->role == PJSIP_ROLE_UAC &&
- (call->opt.flag & PJSUA_CALL_UNHOLD) &&
- tsx->state >= PJSIP_TSX_STATE_COMPLETED)
+ pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0 &&
+ tsx->state >= PJSIP_TSX_STATE_COMPLETED &&
+ (tsx->status_code!=401 && tsx->status_code!=407))
{
- /* Monitor the status of call unhold request */
- if (tsx->status_code/100 != 2 &&
- (tsx->status_code!=401 && tsx->status_code!=407))
+ if (tsx->status_code/100 != 2 ||
+ ((call->opt.flag & PJSUA_CALL_NO_SDP_OFFER) == 0 &&
+ !call->med_update_success))
{
- /* Call unhold failed */
- call->local_hold = PJ_TRUE;
- PJ_LOG(3,(THIS_FILE, "Error releasing hold on call %d (reason=%d)",
- call->index, tsx->status_code));
+ /* Either we get non-2xx or media update failed,
+ * clean up provisional media.
+ */
+ pjsua_media_prov_clean_up(call->index);
}
} else if (tsx->role==PJSIP_ROLE_UAS &&
tsx->state==PJSIP_TSX_STATE_TRYING &&
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index af0799aa..61f76dee 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -1529,6 +1529,12 @@ static void media_prov_clean_up(pjsua_call_id call_id, int idx)
pjsua_call *call = &pjsua_var.calls[call_id];
unsigned i;
+ if (call->med_prov_cnt > call->med_cnt) {
+ PJ_LOG(4,(THIS_FILE, "Call %d: cleaning up provisional media, "
+ "prov_med_cnt=%d, med_cnt=%d",
+ call_id, call->med_prov_cnt, call->med_cnt));
+ }
+
for (i = idx; i < call->med_prov_cnt; ++i) {
pjsua_call_media *call_med = &call->media_prov[i];
unsigned j;
@@ -1554,6 +1560,8 @@ static void media_prov_clean_up(pjsua_call_id call_id, int idx)
call_med->tp = call_med->tp_orig = NULL;
}
}
+
+ call->med_prov_cnt = 0;
}
void pjsua_media_prov_clean_up(pjsua_call_id call_id)