diff options
Diffstat (limited to 'pjsip/src')
-rw-r--r-- | pjsip/src/pjsip-ua/sip_inv.c | 38 | ||||
-rw-r--r-- | pjsip/src/pjsip-ua/sip_replaces.c | 7 | ||||
-rw-r--r-- | pjsip/src/pjsip-ua/sip_timer.c | 6 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_auth_aka.c | 37 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_auth_client.c | 6 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_config.c | 4 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_endpoint.c | 40 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transaction.c | 50 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport_tls.c | 5 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_util.c | 5 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_aud.c | 68 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_call.c | 37 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_dump.c | 1 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_media.c | 4 |
14 files changed, 233 insertions, 75 deletions
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c index 8c2c92d0..a36cfed4 100644 --- a/pjsip/src/pjsip-ua/sip_inv.c +++ b/pjsip/src/pjsip-ua/sip_inv.c @@ -212,7 +212,16 @@ void inv_set_state(pjsip_inv_session *inv, pjsip_inv_state state, * otherwise disconnect the session. */ if (state == PJSIP_INV_STATE_CONFIRMED) { - if (pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE) { + struct tsx_inv_data *tsx_inv_data = NULL; + + if (inv->invite_tsx) { + tsx_inv_data = (struct tsx_inv_data*) + inv->invite_tsx->mod_data[mod_inv.mod.id]; + } + + if (pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE && + (tsx_inv_data && !tsx_inv_data->sdp_done) ) + { pjsip_tx_data *bye; PJ_LOG(4,(inv->obj_name, "SDP offer/answer incomplete, ending the " @@ -3954,6 +3963,32 @@ static void inv_on_state_connecting( pjsip_inv_session *inv, pjsip_event *e) } else if (tsx->role == PJSIP_ROLE_UAS && tsx->state == PJSIP_TSX_STATE_TRYING && + pjsip_method_cmp(&tsx->method, &pjsip_invite_method)==0) + { + pjsip_rx_data *rdata = e->body.tsx_state.src.rdata; + pjsip_tx_data *tdata; + pj_status_t status; + + /* See https://trac.pjsip.org/repos/ticket/1455 + * Handle incoming re-INVITE before current INVITE is confirmed. + * According to RFC 5407: + * - answer with 200 if we don't have pending offer-answer + * - answer with 491 if we *have* pending offer-answer + * + * But unfortunately accepting the re-INVITE would mean we have + * two outstanding INVITEs, and we don't support that because + * we will get confused when we handle the ACK. + */ + status = pjsip_dlg_create_response(inv->dlg, rdata, + PJSIP_SC_REQUEST_PENDING, + NULL, &tdata); + if (status != PJ_SUCCESS) + return; + pjsip_timer_update_resp(inv, tdata); + status = pjsip_dlg_send_response(dlg, tsx, tdata); + + } else if (tsx->role == PJSIP_ROLE_UAS && + tsx->state == PJSIP_TSX_STATE_TRYING && pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0) { /* @@ -3986,6 +4021,7 @@ static void inv_on_state_connecting( pjsip_inv_session *inv, pjsip_event *e) /* Generic handling for UAC tsx completion */ handle_uac_tsx_response(inv, e); + } } diff --git a/pjsip/src/pjsip-ua/sip_replaces.c b/pjsip/src/pjsip-ua/sip_replaces.c index 4707a510..70329f97 100644 --- a/pjsip/src/pjsip-ua/sip_replaces.c +++ b/pjsip/src/pjsip-ua/sip_replaces.c @@ -162,8 +162,10 @@ static pjsip_hdr *parse_hdr_replaces(pjsip_parse_ctx *ctx) /* Deinitialize Replaces */ -static void pjsip_replaces_deinit_module(void) +static void pjsip_replaces_deinit_module(pjsip_endpoint *endpt) { + PJ_TODO(provide_initialized_flag_for_each_endpoint); + PJ_UNUSED_ARG(endpt); is_initialized = PJ_FALSE; } @@ -191,7 +193,8 @@ PJ_DEF(pj_status_t) pjsip_replaces_init_module(pjsip_endpoint *endpt) 1, &STR_REPLACES); /* Register deinit module to be executed when PJLIB shutdown */ - if (pj_atexit(&pjsip_replaces_deinit_module) != PJ_SUCCESS) { + if (pjsip_endpt_atexit(endpt, &pjsip_replaces_deinit_module) != PJ_SUCCESS) + { /* Failure to register this function may cause this module won't * work properly when the stack is restarted (without quitting * application). diff --git a/pjsip/src/pjsip-ua/sip_timer.c b/pjsip/src/pjsip-ua/sip_timer.c index d907794f..17c83c24 100644 --- a/pjsip/src/pjsip-ua/sip_timer.c +++ b/pjsip/src/pjsip-ua/sip_timer.c @@ -495,8 +495,10 @@ static void stop_timer(pjsip_inv_session *inv) } /* Deinitialize Session Timers */ -static void pjsip_timer_deinit_module(void) +static void pjsip_timer_deinit_module(pjsip_endpoint *endpt) { + PJ_TODO(provide_initialized_flag_for_each_endpoint); + PJ_UNUSED_ARG(endpt); is_initialized = PJ_FALSE; } @@ -531,7 +533,7 @@ PJ_DEF(pj_status_t) pjsip_timer_init_module(pjsip_endpoint *endpt) return status; /* Register deinit module to be executed when PJLIB shutdown */ - if (pj_atexit(&pjsip_timer_deinit_module) != PJ_SUCCESS) { + if (pjsip_endpt_atexit(endpt, &pjsip_timer_deinit_module) != PJ_SUCCESS) { /* Failure to register this function may cause this module won't * work properly when the stack is restarted (without quitting * application). diff --git a/pjsip/src/pjsip/sip_auth_aka.c b/pjsip/src/pjsip/sip_auth_aka.c index 29deab7f..82efbaf9 100644 --- a/pjsip/src/pjsip/sip_auth_aka.c +++ b/pjsip/src/pjsip/sip_auth_aka.c @@ -152,22 +152,39 @@ PJ_DEF(pj_status_t) pjsip_auth_create_aka_response( &auth->uri, &chal->realm, &aka_cred, method); } else if (aka_version == 2) { + /* * For AKAv2, password is base64 encoded [1] parameters: * PRF(RES||IK||CK,"http-digest-akav2-password") * * The pseudo-random function (PRF) is HMAC-MD5 in this case. - * - * Hmmm.. but those above doesn't seem to work, and this below does! */ - aka_cred.data.slen = PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN + - PJSIP_AKA_CKLEN; - aka_cred.data.ptr = pj_pool_alloc(pool, aka_cred.data.slen); - - pj_memcpy(aka_cred.data.ptr + 0, res, PJSIP_AKA_RESLEN); - pj_memcpy(aka_cred.data.ptr + PJSIP_AKA_RESLEN, ik, PJSIP_AKA_IKLEN); - pj_memcpy(aka_cred.data.ptr + PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN, - ck, PJSIP_AKA_CKLEN); + + pj_str_t resikck; + const pj_str_t AKAv2_Passwd = { "http-digest-akav2-password", 26 }; + pj_uint8_t hmac_digest[16]; + char tmp_buf[48]; + int hmac64_len; + + resikck.slen = PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN + PJSIP_AKA_CKLEN; + pj_assert(resikck.slen <= PJ_ARRAY_SIZE(tmp_buf)); + resikck.ptr = tmp_buf; + pj_memcpy(resikck.ptr + 0, res, PJSIP_AKA_RESLEN); + pj_memcpy(resikck.ptr + PJSIP_AKA_RESLEN, ik, PJSIP_AKA_IKLEN); + pj_memcpy(resikck.ptr + PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN, + ck, PJSIP_AKA_CKLEN); + + pj_hmac_md5((const pj_uint8_t*)AKAv2_Passwd.ptr, AKAv2_Passwd.slen, + (const pj_uint8_t*)resikck.ptr, resikck.slen, + hmac_digest); + + aka_cred.data.slen = hmac64_len = + PJ_BASE256_TO_BASE64_LEN(PJ_ARRAY_SIZE(hmac_digest)); + pj_assert(aka_cred.data.slen+1 <= PJ_ARRAY_SIZE(tmp_buf)); + aka_cred.data.ptr = tmp_buf; + pj_base64_encode(hmac_digest, PJ_ARRAY_SIZE(hmac_digest), + aka_cred.data.ptr, &len); + aka_cred.data.slen = hmac64_len; pjsip_auth_create_digest(&auth->response, &chal->nonce, &auth->nc, &auth->cnonce, &auth->qop, diff --git a/pjsip/src/pjsip/sip_auth_client.c b/pjsip/src/pjsip/sip_auth_client.c index 8684cc9b..4bde8539 100644 --- a/pjsip/src/pjsip/sip_auth_client.c +++ b/pjsip/src/pjsip/sip_auth_client.c @@ -1103,7 +1103,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess, PJSIP_EINVALIDSTATUS); tdata = old_request; - + tdata->auth_retry = PJ_FALSE; + /* * Respond to each authentication challenge. */ @@ -1174,6 +1175,9 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess, /* Must invalidate the message! */ pjsip_tx_data_invalidate_msg(tdata); + /* Retrying.. */ + tdata->auth_retry = PJ_TRUE; + /* Increment reference counter. */ pjsip_tx_data_add_ref(tdata); diff --git a/pjsip/src/pjsip/sip_config.c b/pjsip/src/pjsip/sip_config.c index 37a66a67..ce970e8a 100644 --- a/pjsip/src/pjsip/sip_config.c +++ b/pjsip/src/pjsip/sip_config.c @@ -25,7 +25,9 @@ pjsip_cfg_t pjsip_sip_cfg_var = { /* Global settings */ { - PJSIP_ALLOW_PORT_IN_FROMTO_HDR + PJSIP_ALLOW_PORT_IN_FROMTO_HDR, + 0, + PJSIP_DONT_SWITCH_TO_TCP }, /* Transaction settings */ diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c index d39b9355..3eb865b1 100644 --- a/pjsip/src/pjsip/sip_endpoint.c +++ b/pjsip/src/pjsip/sip_endpoint.c @@ -40,6 +40,15 @@ #define MAX_METHODS 32 + +/* List of SIP endpoint exit callback. */ +typedef struct exit_cb +{ + PJ_DECL_LIST_MEMBER (struct exit_cb); + pjsip_endpt_exit_callback func; +} exit_cb; + + /** * The SIP endpoint. */ @@ -86,6 +95,9 @@ struct pjsip_endpoint /** Additional request headers. */ pjsip_hdr req_hdr; + + /** List of exit callback. */ + exit_cb exit_cb_list; }; @@ -445,6 +457,9 @@ PJ_DEF(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf, /* Init modules list. */ pj_list_init(&endpt->module_list); + /* Initialize exit callback list. */ + pj_list_init(&endpt->exit_cb_list); + /* Create R/W mutex for module manipulation. */ status = pj_rwmutex_create(endpt->pool, "ept%p", &endpt->mod_mutex); if (status != PJ_SUCCESS) @@ -559,6 +574,7 @@ on_error: PJ_DEF(void) pjsip_endpt_destroy(pjsip_endpoint *endpt) { pjsip_module *mod; + exit_cb *ecb; PJ_LOG(5, (THIS_FILE, "Destroying endpoing instance..")); @@ -592,6 +608,13 @@ PJ_DEF(void) pjsip_endpt_destroy(pjsip_endpoint *endpt) /* Destroy timer heap */ pj_timer_heap_destroy(endpt->timer_heap); + /* Call all registered exit callbacks */ + ecb = endpt->exit_cb_list.next; + while (ecb != &endpt->exit_cb_list) { + (*ecb->func)(endpt); + ecb = ecb->next; + } + /* Delete endpoint mutex. */ pj_mutex_destroy(endpt->mutex); @@ -1182,3 +1205,20 @@ PJ_DEF(void) pjsip_endpt_dump( pjsip_endpoint *endpt, pj_bool_t detail ) #endif } + +PJ_DEF(pj_status_t) pjsip_endpt_atexit( pjsip_endpoint *endpt, + pjsip_endpt_exit_callback func) +{ + exit_cb *new_cb; + + PJ_ASSERT_RETURN(endpt && func, PJ_EINVAL); + + new_cb = PJ_POOL_ZALLOC_T(endpt->pool, exit_cb); + new_cb->func = func; + + pj_mutex_lock(endpt->mutex); + pj_list_push_back(&endpt->exit_cb_list, new_cb); + pj_mutex_unlock(endpt->mutex); + + return PJ_SUCCESS; +} diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c index c127162b..3acef980 100644 --- a/pjsip/src/pjsip/sip_transaction.c +++ b/pjsip/src/pjsip/sip_transaction.c @@ -714,23 +714,17 @@ static pj_status_t mod_tsx_layer_stop(void) } pj_mutex_unlock(mod_tsx_layer.mutex); + + PJ_LOG(4,(THIS_FILE, "Stopped transaction layer module")); + return PJ_SUCCESS; } -/* This module callback is called when module is being unloaded by - * endpoint. - */ -static pj_status_t mod_tsx_layer_unload(void) +/* Destroy this module */ +static void tsx_layer_destroy(pjsip_endpoint *endpt) { - /* Only self destroy when there's no transaction in the table. - * Transaction may refuse to destroy when it has pending - * transmission. If we destroy the module now, application will - * crash when the pending transaction finally got error response - * from transport and when it tries to unregister itself. - */ - if (pj_hash_count(mod_tsx_layer.htable) != 0) - return PJ_EBUSY; + PJ_UNUSED_ARG(endpt); /* Destroy mutex. */ pj_mutex_destroy(mod_tsx_layer.mutex); @@ -745,6 +739,31 @@ static pj_status_t mod_tsx_layer_unload(void) mod_tsx_layer.endpt = NULL; PJ_LOG(4,(THIS_FILE, "Transaction layer module destroyed")); +} + + +/* This module callback is called when module is being unloaded by + * endpoint. + */ +static pj_status_t mod_tsx_layer_unload(void) +{ + /* Only self destroy when there's no transaction in the table. + * Transaction may refuse to destroy when it has pending + * transmission. If we destroy the module now, application will + * crash when the pending transaction finally got error response + * from transport and when it tries to unregister itself. + */ + if (pj_hash_count(mod_tsx_layer.htable) != 0) { + if (pjsip_endpt_atexit(mod_tsx_layer.endpt, &tsx_layer_destroy) != + PJ_SUCCESS) + { + PJ_LOG(3,(THIS_FILE, "Failed to register transaction layer " + "module destroy.")); + } + return PJ_EBUSY; + } + + tsx_layer_destroy(mod_tsx_layer.endpt); return PJ_SUCCESS; } @@ -3239,7 +3258,10 @@ static pj_status_t tsx_on_state_destroyed(pjsip_transaction *tsx, { PJ_UNUSED_ARG(tsx); PJ_UNUSED_ARG(event); - pj_assert(!"Not expecting any events!!"); - return PJ_EBUG; + + // See https://trac.pjsip.org/repos/ticket/1432 + //pj_assert(!"Not expecting any events!!"); + + return PJ_EIGNORED; } diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c index face6b88..bae3ffd1 100644 --- a/pjsip/src/pjsip/sip_transport_tls.c +++ b/pjsip/src/pjsip/sip_transport_tls.c @@ -293,6 +293,8 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start (pjsip_endpoint *endpt, ssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN; if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN) ssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN; + ssock_param.ciphers_num = listener->tls_setting.ciphers_num; + ssock_param.ciphers = listener->tls_setting.ciphers; ssock_param.qos_type = listener->tls_setting.qos_type; ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error; pj_memcpy(&ssock_param.qos_params, &listener->tls_setting.qos_params, @@ -862,7 +864,6 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory, ssock_param.cb.on_data_sent = &on_data_sent; ssock_param.async_cnt = 1; ssock_param.ioqueue = pjsip_endpt_get_ioqueue(listener->endpt); - PJ_TODO(synchronize_tls_cipher_type_with_ssl_sock_cipher_type); ssock_param.server_name = remote_name; ssock_param.timeout = listener->tls_setting.timeout; ssock_param.user_data = NULL; /* pending, must be set later */ @@ -872,6 +873,8 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory, ssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN; if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN) ssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN; + ssock_param.ciphers_num = listener->tls_setting.ciphers_num; + ssock_param.ciphers = listener->tls_setting.ciphers; ssock_param.qos_type = listener->tls_setting.qos_type; ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error; pj_memcpy(&ssock_param.qos_params, &listener->tls_setting.qos_params, diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c index 4f82a1a6..f238f524 100644 --- a/pjsip/src/pjsip/sip_util.c +++ b/pjsip/src/pjsip/sip_util.c @@ -1248,14 +1248,14 @@ stateless_send_resolver_callback( pj_status_t status, } pj_assert(tdata->dest_info.addr.count != 0); -#if !defined(PJSIP_DONT_SWITCH_TO_TCP) || PJSIP_DONT_SWITCH_TO_TCP==0 /* RFC 3261 section 18.1.1: * If a request is within 200 bytes of the path MTU, or if it is larger * than 1300 bytes and the path MTU is unknown, the request MUST be sent * using an RFC 2914 [43] congestion controlled transport protocol, such * as TCP. */ - if (tdata->msg->type == PJSIP_REQUEST_MSG && + if (pjsip_cfg()->endpt.disable_tcp_switch==0 && + tdata->msg->type == PJSIP_REQUEST_MSG && tdata->dest_info.addr.count > 0 && tdata->dest_info.addr.entry[0].type == PJSIP_TRANSPORT_UDP) { @@ -1297,7 +1297,6 @@ stateless_send_resolver_callback( pj_status_t status, tdata->dest_info.addr.count = count * 2; } } -#endif /* !PJSIP_DONT_SWITCH_TO_TCP */ /* Process the addresses. */ stateless_send_transport_cb( stateless_data, tdata, -PJ_EPENDING); diff --git a/pjsip/src/pjsua-lib/pjsua_aud.c b/pjsip/src/pjsua-lib/pjsua_aud.c index d80981d6..cbe52daf 100644 --- a/pjsip/src/pjsua-lib/pjsua_aud.c +++ b/pjsip/src/pjsua-lib/pjsua_aud.c @@ -26,7 +26,7 @@ #define NULL_SND_DEV_ID -99 /***************************************************************************** -/* + * * Prototypes */ /* Open sound dev */ @@ -43,7 +43,7 @@ static pj_status_t create_aud_param(pjmedia_aud_param *param, unsigned bits_per_sample); /***************************************************************************** -/* + * * Call API that are closely tied to PJMEDIA */ /* @@ -223,7 +223,7 @@ on_return: /***************************************************************************** -/* + * * Audio media with PJMEDIA backend */ @@ -806,13 +806,13 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source, source, sink)); pj_log_push_indent(); - /* If sound device idle timer is active, cancel it first. */ PJSUA_LOCK(); + + /* If sound device idle timer is active, cancel it first. */ if (pjsua_var.snd_idle_timer.id) { pjsip_endpt_cancel_timer(pjsua_var.endpt, &pjsua_var.snd_idle_timer); pjsua_var.snd_idle_timer.id = PJ_FALSE; } - PJSUA_UNLOCK(); /* For audio switchboard (i.e. APS-Direct): @@ -910,8 +910,6 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source, if (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL && !pjsua_var.no_snd) { - pj_status_t status; - status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error opening sound device", status); @@ -926,9 +924,13 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source, } } - status = pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0); - on_return: + PJSUA_UNLOCK(); + + if (status == PJ_SUCCESS) { + status = pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0); + } + pj_log_pop_indent(); return status; } @@ -1851,8 +1853,11 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev, capture_dev, playback_dev)); pj_log_push_indent(); + PJSUA_LOCK(); + /* Null-sound */ if (capture_dev==NULL_SND_DEV_ID && playback_dev==NULL_SND_DEV_ID) { + PJSUA_UNLOCK(); status = pjsua_set_null_snd_dev(); pj_log_pop_indent(); return status; @@ -1903,10 +1908,12 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev, pjsua_var.no_snd = PJ_FALSE; pjsua_var.snd_is_on = PJ_TRUE; + PJSUA_UNLOCK(); pj_log_pop_indent(); return PJ_SUCCESS; on_error: + PJSUA_UNLOCK(); pj_log_pop_indent(); return status; } @@ -1920,6 +1927,8 @@ on_error: PJ_DEF(pj_status_t) pjsua_get_snd_dev(int *capture_dev, int *playback_dev) { + PJSUA_LOCK(); + if (capture_dev) { *capture_dev = pjsua_var.cap_dev; } @@ -1927,6 +1936,7 @@ PJ_DEF(pj_status_t) pjsua_get_snd_dev(int *capture_dev, *playback_dev = pjsua_var.play_dev; } + PJSUA_UNLOCK(); return PJ_SUCCESS; } @@ -1942,6 +1952,7 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void) PJ_LOG(4,(THIS_FILE, "Setting null sound device..")); pj_log_push_indent(); + PJSUA_LOCK(); /* Close existing sound device */ close_snd_dev(); @@ -1969,6 +1980,7 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void) if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to create null sound device", status); + PJSUA_UNLOCK(); pj_log_pop_indent(); return status; } @@ -1983,6 +1995,7 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void) pjsua_var.no_snd = PJ_FALSE; pjsua_var.snd_is_on = PJ_TRUE; + PJSUA_UNLOCK(); pj_log_pop_indent(); return PJ_SUCCESS; } @@ -1994,10 +2007,14 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void) */ PJ_DEF(pjmedia_port*) pjsua_set_no_snd_dev(void) { + PJSUA_LOCK(); + /* Close existing sound device */ close_snd_dev(); - pjsua_var.no_snd = PJ_TRUE; + + PJSUA_UNLOCK(); + return pjmedia_conf_get_master_port(pjsua_var.mconf); } @@ -2007,13 +2024,18 @@ PJ_DEF(pjmedia_port*) pjsua_set_no_snd_dev(void) */ PJ_DEF(pj_status_t) pjsua_set_ec(unsigned tail_ms, unsigned options) { + pj_status_t status = PJ_SUCCESS; + + PJSUA_LOCK(); + pjsua_var.media_cfg.ec_tail_len = tail_ms; if (pjsua_var.snd_port) - return pjmedia_snd_port_set_ec( pjsua_var.snd_port, pjsua_var.pool, - tail_ms, options); + status = pjmedia_snd_port_set_ec(pjsua_var.snd_port, pjsua_var.pool, + tail_ms, options); - return PJ_SUCCESS; + PJSUA_UNLOCK(); + return status; } @@ -2050,6 +2072,8 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap, return PJMEDIA_EAUD_INVCAP; } + PJSUA_LOCK(); + /* If sound is active, set it immediately */ if (pjsua_snd_is_active()) { pjmedia_aud_stream *strm; @@ -2060,8 +2084,10 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap, status = PJ_SUCCESS; } - if (status != PJ_SUCCESS) + if (status != PJ_SUCCESS) { + PJSUA_UNLOCK(); return status; + } /* Save in internal param for later device open */ if (keep) { @@ -2069,6 +2095,7 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap, cap, pval); } + PJSUA_UNLOCK(); return status; } @@ -2078,6 +2105,10 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap, PJ_DEF(pj_status_t) pjsua_snd_get_setting( pjmedia_aud_dev_cap cap, void *pval) { + pj_status_t status; + + PJSUA_LOCK(); + /* If sound device has never been opened before, open it to * retrieve the initial setting from the device (e.g. audio * volume) @@ -2093,12 +2124,15 @@ PJ_DEF(pj_status_t) pjsua_snd_get_setting( pjmedia_aud_dev_cap cap, pjmedia_aud_stream *strm; strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port); - return pjmedia_aud_stream_get_cap(strm, cap, pval); + status = pjmedia_aud_stream_get_cap(strm, cap, pval); } else { /* Otherwise retrieve from internal param */ - return pjmedia_aud_param_get_cap(&pjsua_var.aud_param, - cap, pval); + status = pjmedia_aud_param_get_cap(&pjsua_var.aud_param, + cap, pval); } + + PJSUA_UNLOCK(); + return status; } #endif /* PJSUA_MEDIA_HAS_PJMEDIA */ diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index 6a4e4dc7..6f0d1048 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -2929,12 +2929,10 @@ static void pjsua_call_on_state_changed(pjsip_inv_session *inv, pjsua_call *call; pj_log_push_indent(); - PJSUA_LOCK(); call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id]; if (!call) { - PJSUA_UNLOCK(); pj_log_pop_indent(); return; } @@ -3077,21 +3075,21 @@ static void pjsua_call_on_state_changed(pjsip_inv_session *inv, /* Destroy media session when invite session is disconnected. */ if (inv->state == PJSIP_INV_STATE_DISCONNECTED) { - pj_assert(call != NULL); - - if (call) - pjsua_media_channel_deinit(call->index); + PJSUA_LOCK(); + + pjsua_media_channel_deinit(call->index); /* Free call */ call->inv = NULL; + + pj_assert(pjsua_var.call_cnt > 0); --pjsua_var.call_cnt; /* Reset call */ reset_call(call->index); + PJSUA_UNLOCK(); } - - PJSUA_UNLOCK(); pj_log_pop_indent(); } @@ -3202,7 +3200,6 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv, //const pj_str_t st_update = {"UPDATE", 6}; pj_log_push_indent(); - PJSUA_LOCK(); call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id]; @@ -3279,7 +3276,6 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv, pjsua_var.ua_cfg.cb.on_call_media_state(call->index); on_return: - PJSUA_UNLOCK(); pj_log_pop_indent(); } @@ -3392,8 +3388,6 @@ static void pjsua_call_on_rx_offer(pjsip_inv_session *inv, unsigned i; pj_status_t status; - PJSUA_LOCK(); - call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id]; /* Supply candidate answer */ @@ -3480,7 +3474,6 @@ static void pjsua_call_on_rx_offer(pjsip_inv_session *inv, } on_return: - PJSUA_UNLOCK(); pj_log_pop_indent(); } @@ -3495,7 +3488,6 @@ static void pjsua_call_on_create_offer(pjsip_inv_session *inv, pj_status_t status; pj_log_push_indent(); - PJSUA_LOCK(); call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id]; @@ -3520,7 +3512,6 @@ static void pjsua_call_on_create_offer(pjsip_inv_session *inv, } on_return: - PJSUA_UNLOCK(); pj_log_pop_indent(); } @@ -3983,7 +3974,6 @@ static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv, pjsua_call *call; pj_log_push_indent(); - PJSUA_LOCK(); call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id]; @@ -3999,6 +3989,17 @@ static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv, goto on_return; } + /* https://trac.pjsip.org/repos/ticket/1452: + * If a request is retried due to 401/407 challenge, don't process the + * transaction first but wait until we've retried it. + */ + if (tsx->role == PJSIP_ROLE_UAC && + (tsx->status_code==401 || tsx->status_code==407) && + tsx->last_tx && tsx->last_tx->auth_retry) + { + goto on_return; + } + /* Notify application callback first */ if (pjsua_var.ua_cfg.cb.on_call_tsx_state) { (*pjsua_var.ua_cfg.cb.on_call_tsx_state)(call->index, tsx, e); @@ -4124,8 +4125,6 @@ static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv, } on_return: - - PJSUA_UNLOCK(); pj_log_pop_indent(); } @@ -4139,7 +4138,6 @@ static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv, pjsip_redirect_op op; pj_log_push_indent(); - PJSUA_LOCK(); if (pjsua_var.ua_cfg.cb.on_call_redirected) { op = (*pjsua_var.ua_cfg.cb.on_call_redirected)(call->index, @@ -4152,7 +4150,6 @@ static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv, op = PJSIP_REDIRECT_STOP; } - PJSUA_UNLOCK(); pj_log_pop_indent(); return op; diff --git a/pjsip/src/pjsua-lib/pjsua_dump.c b/pjsip/src/pjsua-lib/pjsua_dump.c index 7279e512..c629e106 100644 --- a/pjsip/src/pjsua-lib/pjsua_dump.c +++ b/pjsip/src/pjsua-lib/pjsua_dump.c @@ -413,7 +413,6 @@ static void dump_media_session(const char *indent, const char *type2 = pj_ice_get_cand_type_name(ii->comp[jj].rcand_type); char addr1[PJ_INET6_ADDRSTRLEN+10]; char addr2[PJ_INET6_ADDRSTRLEN+10]; - const char *comp_name[2] = {"rtp ", "rtcp"}; if (pj_sockaddr_has_addr(&ii->comp[jj].lcand_addr)) pj_sockaddr_print(&ii->comp[jj].lcand_addr, addr1, sizeof(addr1), 3); diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index 2810a24b..56e5bce2 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -97,8 +97,8 @@ pj_status_t pjsua_media_subsys_init(const pjsua_media_config *cfg) goto on_error; #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) - /* Initialize SRTP library. */ - status = pjmedia_srtp_init_lib(); + /* Initialize SRTP library (ticket #788). */ + status = pjmedia_srtp_init_lib(pjsua_var.med_endpt); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error initializing SRTP library", status); |