diff options
author | Benny Prijono <bennylp@teluu.com> | 2006-09-25 13:40:12 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2006-09-25 13:40:12 +0000 |
commit | cf3c435e0093cf2f1fb8add2298ee468f8c6afc5 (patch) | |
tree | 93bbdb60b762ce015dc8f55147eed38bb034d1ca | |
parent | e3f862fca94af0cb4812796055b18d2ba107b613 (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.h | 15 | ||||
-rw-r--r-- | pjmedia/src/pjmedia-codec/ilbc.c | 2 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/errno.c | 3 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/sdp_neg.c | 49 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 2 | ||||
-rw-r--r-- | pjsip/src/pjsip-ua/sip_inv.c | 32 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_call.c | 64 |
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 */ |