summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-09-25 13:40:12 +0000
committerBenny Prijono <bennylp@teluu.com>2006-09-25 13:40:12 +0000
commitcf3c435e0093cf2f1fb8add2298ee468f8c6afc5 (patch)
tree93bbdb60b762ce015dc8f55147eed38bb034d1ca
parente3f862fca94af0cb4812796055b18d2ba107b613 (diff)
Tests with other user agents revealed some bugs which
have been fixed below: - some UAs sends "telephone-event/8000/1" instead of "telephone-event/8000", which caused SDP negotiation to fail. Fixed in sdp_neg.c. - codec name was (incorrectly) compared case-sensitively, causing negotiation to fail. Fixed in sdp_neg.c. - Also improved error reporting in SDP negotiation by introducing few more error codes. - Added Warning header in Not Acceptable response sent by pjsip_inv_session when SDP negotiation fails. - PJSUA-LIB will try to negotiate both SDPs before sending 100 response. - Fixed bug in iLBC codec when setting the mode to 30. Also: - Echo cancellation by default is disabled now since it doesn't seem to work. Further investigation needed. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@738 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/include/pjmedia/errno.h15
-rw-r--r--pjmedia/src/pjmedia-codec/ilbc.c2
-rw-r--r--pjmedia/src/pjmedia/errno.c3
-rw-r--r--pjmedia/src/pjmedia/sdp_neg.c49
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h2
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c32
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c64
7 files changed, 108 insertions, 59 deletions
diff --git a/pjmedia/include/pjmedia/errno.h b/pjmedia/include/pjmedia/errno.h
index 03608f9f..af3467ed 100644
--- a/pjmedia/include/pjmedia/errno.h
+++ b/pjmedia/include/pjmedia/errno.h
@@ -198,6 +198,21 @@ PJ_BEGIN_DECL
* No media is active after negotiation.
*/
#define PJMEDIA_SDPNEG_ENOMEDIA (PJMEDIA_ERRNO_START+48) /* 220048 */
+/**
+ * @hideinitializer
+ * No suitable codec for remote offer.
+ */
+#define PJMEDIA_SDPNEG_NOANSCODEC (PJMEDIA_ERRNO_START+49) /* 220049 */
+/**
+ * @hideinitializer
+ * No suitable telephone-event for remote offer.
+ */
+#define PJMEDIA_SDPNEG_NOANSTELEVENT (PJMEDIA_ERRNO_START+50) /* 220050 */
+/**
+ * @hideinitializer
+ * No suitable answer for unknown remote offer.
+ */
+#define PJMEDIA_SDPNEG_NOANSUNKNOWN (PJMEDIA_ERRNO_START+51) /* 220051 */
/************************************************************
diff --git a/pjmedia/src/pjmedia-codec/ilbc.c b/pjmedia/src/pjmedia-codec/ilbc.c
index c6ec700a..da4bcec0 100644
--- a/pjmedia/src/pjmedia-codec/ilbc.c
+++ b/pjmedia/src/pjmedia-codec/ilbc.c
@@ -395,7 +395,7 @@ static pj_status_t ilbc_codec_open(pjmedia_codec *codec,
attr->setting.penh);
if (attr->setting.dec_fmtp_mode == 20)
ilbc_codec->dec_frame_size = 38;
- else if (attr->setting.dec_fmtp_mode == 20)
+ else if (attr->setting.dec_fmtp_mode == 30)
ilbc_codec->dec_frame_size = 50;
else {
pj_assert(!"Invalid iLBC mode");
diff --git a/pjmedia/src/pjmedia/errno.c b/pjmedia/src/pjmedia/errno.c
index 9305cd65..35441b9b 100644
--- a/pjmedia/src/pjmedia/errno.c
+++ b/pjmedia/src/pjmedia/errno.c
@@ -67,6 +67,9 @@ static const struct
PJ_BUILD_ERR( PJMEDIA_SDPNEG_EINVANSTP, "SDP media transport type mismatch in offer/answer" ),
PJ_BUILD_ERR( PJMEDIA_SDPNEG_EANSNOMEDIA, "No common SDP media payload in answer" ),
PJ_BUILD_ERR( PJMEDIA_SDPNEG_ENOMEDIA, "No active media stream after negotiation" ),
+ PJ_BUILD_ERR( PJMEDIA_SDPNEG_NOANSCODEC, "No suitable codec for remote offer"),
+ PJ_BUILD_ERR( PJMEDIA_SDPNEG_NOANSTELEVENT, "No suitable telephone-event for remote offer"),
+ PJ_BUILD_ERR( PJMEDIA_SDPNEG_NOANSUNKNOWN, "No suitable answer for unknown remote offer"),
/* SDP comparison results */
PJ_BUILD_ERR( PJMEDIA_SDP_EMEDIANOTEQUAL, "SDP media descriptor not equal" ),
diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c
index 8b362ba9..8b65644d 100644
--- a/pjmedia/src/pjmedia/sdp_neg.c
+++ b/pjmedia/src/pjmedia/sdp_neg.c
@@ -533,9 +533,10 @@ static pj_status_t process_m_answer( pj_pool_t *pool,
/* See if encoding name, clock rate, and channel
* count match
*/
- if (!pj_strcmp(&or.enc_name, &ar.enc_name) &&
+ if (!pj_stricmp(&or.enc_name, &ar.enc_name) &&
or.clock_rate == ar.clock_rate &&
- pj_strcmp(&or.param, &ar.param)==0)
+ (pj_stricmp(&or.param, &ar.param)==0 ||
+ ar.param.slen==1 && *ar.param.ptr=='1'))
{
/* Match! */
break;
@@ -628,10 +629,10 @@ static pj_status_t process_answer(pj_pool_t *pool,
}
/* Try to match offer with answer. */
-static pj_bool_t match_offer(pj_pool_t *pool,
- const pjmedia_sdp_media *offer,
- const pjmedia_sdp_media *local,
- pjmedia_sdp_media **p_answer)
+static pj_status_t match_offer(pj_pool_t *pool,
+ const pjmedia_sdp_media *offer,
+ const pjmedia_sdp_media *local,
+ pjmedia_sdp_media **p_answer)
{
unsigned i;
pj_bool_t offer_has_codec = 0,
@@ -697,7 +698,7 @@ static pj_bool_t match_offer(pj_pool_t *pool,
&offer->desc.fmt[i]);
if (!a) {
pj_assert(!"Bug! Offer should have been validated");
- return PJ_FALSE;
+ return PJMEDIA_SDP_EMISSINGRTPMAP;
}
pjmedia_sdp_attr_get_rtpmap(a, &or);
@@ -726,9 +727,10 @@ static pj_bool_t match_offer(pj_pool_t *pool,
/* See if encoding name, clock rate, and
* channel count match
*/
- if (!pj_strcmp(&or.enc_name, &lr.enc_name) &&
+ if (!pj_stricmp(&or.enc_name, &lr.enc_name) &&
or.clock_rate == lr.clock_rate &&
- pj_strcmp(&or.param, &lr.param)==0)
+ (pj_strcmp(&or.param, &lr.param)==0 ||
+ or.param.slen==1 && *or.param.ptr=='1'))
{
/* Match! */
if (is_codec)
@@ -766,12 +768,16 @@ static pj_bool_t match_offer(pj_pool_t *pool,
/* See if all types of offer can be matched. */
#if 1
- if ((offer_has_codec && !found_matching_codec) ||
- (offer_has_telephone_event && !found_matching_telephone_event) ||
- (offer_has_other && !found_matching_other))
- {
- /* Some of the payload in the offer has no matching local sdp */
- return PJ_FALSE;
+ if (offer_has_codec && !found_matching_codec) {
+ return PJMEDIA_SDPNEG_NOANSCODEC;
+ }
+
+ if (offer_has_telephone_event && !found_matching_telephone_event) {
+ return PJMEDIA_SDPNEG_NOANSTELEVENT;
+ }
+
+ if (offer_has_other && !found_matching_other) {
+ return PJMEDIA_SDPNEG_NOANSUNKNOWN;
}
#else
PJ_TODO(FULL_MATCHING_WITH_TELEPHONE_EVENTS);
@@ -827,7 +833,7 @@ static pj_bool_t match_offer(pj_pool_t *pool,
update_media_direction(pool, offer, answer);
*p_answer = answer;
- return PJ_TRUE;
+ return PJ_SUCCESS;
}
/* Create complete answer for remote's offer. */
@@ -836,7 +842,7 @@ static pj_status_t create_answer( pj_pool_t *pool,
const pjmedia_sdp_session *offer,
pjmedia_sdp_session **p_answer)
{
- pj_status_t status;
+ pj_status_t status = PJMEDIA_SDPNEG_ENOMEDIA;
pj_bool_t has_active = PJ_FALSE;
pjmedia_sdp_session *answer;
char media_used[PJMEDIA_MAX_SDP_MEDIA];
@@ -879,10 +885,8 @@ static pj_status_t create_answer( pj_pool_t *pool,
media_used[j] == 0)
{
/* See if it has matching codec. */
- pj_bool_t match;
-
- match = match_offer(pool, om, im, &am);
- if (match) {
+ status = match_offer(pool, om, im, &am);
+ if (status == PJ_SUCCESS) {
/* Mark media as used. */
media_used[j] = 1;
break;
@@ -925,8 +929,7 @@ static pj_status_t create_answer( pj_pool_t *pool,
*p_answer = answer;
- return has_active ? PJ_SUCCESS : PJMEDIA_SDPNEG_ENOMEDIA;
- //return PJ_SUCCESS;
+ return has_active ? PJ_SUCCESS : status;
}
/* The best bit: SDP negotiation function! */
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index 82e22abe..47641c92 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -2102,7 +2102,7 @@ PJ_DECL(pj_status_t) pjsua_im_typing(pjsua_acc_id acc_id,
#define PJSUA_DEFAULT_CLOCK_RATE 16000
#define PJSUA_DEFAULT_CODEC_QUALITY 5
#define PJSUA_DEFAULT_ILBC_MODE 20
-#define PJSUA_DEFAULT_EC_TAIL_LEN 256
+#define PJSUA_DEFAULT_EC_TAIL_LEN 0
/**
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index e363eb90..97507458 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -614,7 +614,6 @@ PJ_DEF(pj_status_t) pjsip_inv_verify_request(pjsip_rx_data *rdata,
/* Incompatible media */
code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
- status = PJSIP_ERRNO_FROM_SIP_STATUS(code);
if (p_tdata) {
pjsip_accept_hdr *acc;
@@ -2414,9 +2413,38 @@ static void inv_on_state_confirmed( pjsip_inv_session *inv, pjsip_event *e)
/* Process SDP in the answer */
status = process_answer(inv, 200, tdata, NULL);
- if (status != PJ_SUCCESS)
+
+ if (status != PJ_SUCCESS) {
+ /*
+ * SDP negotiation has failed.
+ */
+ pj_status_t rc;
+ pj_str_t reason;
+
+ /* Delete the 2xx answer */
+ pjsip_tx_data_dec_ref(tdata);
+
+ /* Create 500 response */
+ reason = pj_str("SDP negotiation failed");
+ rc = pjsip_dlg_create_response(dlg, rdata, 500, &reason,
+ &tdata);
+ if (rc == PJ_SUCCESS) {
+ pjsip_warning_hdr *w;
+ const pj_str_t *endpt_name;
+
+ endpt_name = pjsip_endpt_name(dlg->endpt);
+ w = pjsip_warning_hdr_create_from_status(tdata->pool,
+ endpt_name,
+ status);
+ if (w)
+ pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)w);
+
+ pjsip_inv_send_msg(inv, tdata);
+ }
return;
+ }
+ /* Send 2xx regardless of the status of negotiation */
status = pjsip_inv_send_msg(inv, tdata);
}
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index bb2ccd18..d3b88a7b 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -394,38 +394,6 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
PJSUA_LOCK();
- /* Verify that we can handle the request. */
- status = pjsip_inv_verify_request(rdata, &options, NULL, NULL,
- pjsua_var.endpt, &response);
- if (status != PJ_SUCCESS) {
-
- /*
- * No we can't handle the incoming INVITE request.
- */
-
- if (response) {
- pjsip_response_addr res_addr;
-
- pjsip_get_response_addr(response->pool, rdata, &res_addr);
- pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response,
- NULL, NULL);
-
- } else {
-
- /* Respond with 500 (Internal Server Error) */
- pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
- NULL, NULL);
- }
-
- PJSUA_UNLOCK();
- return PJ_TRUE;
- }
-
-
- /*
- * Yes we can handle the incoming INVITE request.
- */
-
/* Find free call slot. */
for (call_id=0; call_id<(int)pjsua_var.ua_cfg.max_calls; ++call_id) {
if (pjsua_var.calls[call_id].inv == NULL)
@@ -461,6 +429,35 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
return PJ_TRUE;
}
+
+ /* Verify that we can handle the request. */
+ status = pjsip_inv_verify_request(rdata, &options, answer, NULL,
+ pjsua_var.endpt, &response);
+ if (status != PJ_SUCCESS) {
+
+ /*
+ * No we can't handle the incoming INVITE request.
+ */
+
+ if (response) {
+ pjsip_response_addr res_addr;
+
+ pjsip_get_response_addr(response->pool, rdata, &res_addr);
+ pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response,
+ NULL, NULL);
+
+ } else {
+
+ /* Respond with 500 (Internal Server Error) */
+ pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
+ NULL, NULL);
+ }
+
+ PJSUA_UNLOCK();
+ return PJ_TRUE;
+ }
+
+
/*
* Get which account is most likely to be associated with this incoming
* call. We need the account to find which contact URI to put for
@@ -1837,6 +1834,9 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv,
pjsua_perror(THIS_FILE, "SDP negotiation has failed", status);
+ /* Stop/destroy media, if any */
+ call_destroy_media(call->index);
+
/* Disconnect call if we're not in the middle of initializing an
* UAS dialog and if this is not a re-INVITE
*/