From 8686b3135348bcd69bdb3c3cb6660a82d989bb30 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Wed, 23 Jan 2008 20:39:07 +0000 Subject: Ticket #61: Implement SRTP support in PJMEDIA and PJSUA-LIB, and updated applications because of the changes. This is a major modification back ported from SRTP branch. See ticket #61 for changelog detail of this commit git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1735 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsua-lib/pjsua.h | 75 ++++++++++++++++ pjsip/include/pjsua-lib/pjsua_internal.h | 9 +- pjsip/src/pjsua-lib/pjsua_call.c | 147 ++++++++++++++++++++++++++----- pjsip/src/pjsua-lib/pjsua_core.c | 8 ++ pjsip/src/pjsua-lib/pjsua_media.c | 128 +++++++++++++++++---------- 5 files changed, 293 insertions(+), 74 deletions(-) (limited to 'pjsip') diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index a1c5c86d..d78eeb78 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -403,7 +403,28 @@ typedef int pjsua_conf_port_id; # define PJSUA_ACC_MAX_PROXIES 8 #endif +#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) +/** + * Default value of SRTP mode usage. Valid values are PJMEDIA_SRTP_DISABLED, + * PJMEDIA_SRTP_OPTIONAL, and PJMEDIA_SRTP_MANDATORY. + */ +#ifndef PJSUA_DEFAULT_USE_SRTP + #define PJSUA_DEFAULT_USE_SRTP PJMEDIA_SRTP_DISABLED +#endif + +/** + * Default value of secure signaling requirement for SRTP. + * Valid values are: + * 0: SRTP does not require secure signaling + * 1: SRTP requires secure transport such as TLS + * 2: SRTP requires secure end-to-end transport (SIPS) + */ +#ifndef PJSUA_DEFAULT_SRTP_SECURE_SIGNALING + #define PJSUA_DEFAULT_SRTP_SECURE_SIGNALING 1 +#endif + +#endif /** * Logging configuration, which can be (optionally) specified when calling @@ -1034,6 +1055,36 @@ typedef struct pjsua_config */ pj_str_t user_agent; +#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) + /** + * Specify default value of secure media transport usage. + * Valid values are PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, and + * PJMEDIA_SRTP_MANDATORY. + * + * Note that this setting can be further customized in account + * configuration (#pjsua_acc_config). + * + * Default: #PJSUA_DEFAULT_USE_SRTP + */ + pjmedia_srtp_use use_srtp; + + /** + * Specify whether SRTP requires secure signaling to be used. This option + * is only used when \a use_srtp option above is non-zero. + * + * Valid values are: + * 0: SRTP does not require secure signaling + * 1: SRTP requires secure transport such as TLS + * 2: SRTP requires secure end-to-end transport (SIPS) + * + * Note that this setting can be further customized in account + * configuration (#pjsua_acc_config). + * + * Default: #PJSUA_DEFAULT_SRTP_SECURE_SIGNALING + */ + int srtp_secure_signaling; +#endif + } pjsua_config; @@ -1971,6 +2022,30 @@ typedef struct pjsua_acc_config */ pj_str_t ka_data; +#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) + /** + * Specify whether secure media transport should be used for this account. + * Valid values are PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, and + * PJMEDIA_SRTP_MANDATORY. + * + * Default: #PJSUA_DEFAULT_USE_SRTP + */ + pjmedia_srtp_use use_srtp; + + /** + * Specify whether SRTP requires secure signaling to be used. This option + * is only used when \a use_srtp option above is non-zero. + * + * Valid values are: + * 0: SRTP does not require secure signaling + * 1: SRTP requires secure transport such as TLS + * 2: SRTP requires secure end-to-end transport (SIPS) + * + * Default: #PJSUA_DEFAULT_SRTP_SECURE_SIGNALING + */ + int srtp_secure_signaling; +#endif + } pjsua_acc_config; diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h index 943eb694..261cea0e 100644 --- a/pjsip/include/pjsua-lib/pjsua_internal.h +++ b/pjsip/include/pjsua-lib/pjsua_internal.h @@ -50,7 +50,8 @@ typedef struct pjsua_call int conf_slot; /**< Slot # in conference bridge. */ pjsip_evsub *xfer_sub; /**< Xfer server subscription, if this call was triggered by xfer. */ - pjmedia_transport *med_tp; /**< Media transport. */ + pjmedia_transport *med_tp; /**< Current media transport. */ + pjmedia_transport *med_orig; /**< Original media transport */ pj_timer_entry refresh_tm;/**< Timer to send re-INVITE. */ pj_timer_entry hangup_tm; /**< Timer to hangup call. */ pj_stun_nat_type rem_nat_type; /**< NAT type of remote endpoint. */ @@ -313,12 +314,14 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata); * Media channel. */ pj_status_t pjsua_media_channel_init(pjsua_call_id call_id, - pjsip_role_e role); + pjsip_role_e role, + int security_level); pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id, pj_pool_t *pool, + const pjmedia_sdp_session *rem_sdp, pjmedia_sdp_session **p_sdp); pj_status_t pjsua_media_channel_update(pjsua_call_id call_id, - const pjmedia_sdp_session *local_sdp, + pjmedia_sdp_session *local_sdp, const pjmedia_sdp_session *remote_sdp); pj_status_t pjsua_media_channel_deinit(pjsua_call_id call_id); diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index 68a18350..6cff391c 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -255,6 +255,44 @@ static pjsua_call_id alloc_call_id(void) return PJSUA_INVALID_ID; } +static pj_bool_t pj_stristr(const pj_str_t *str, const pj_str_t *substr) +{ + int i; + + for (i=0; i<(str->slen-substr->slen); ++i) { + pj_str_t s; + s.ptr = str->ptr+i; + s.slen = substr->slen; + + if (pj_stricmp(&s, substr)==0) + return PJ_TRUE; + } + return PJ_FALSE; +} + +/* Get signaling secure level. + * Return: + * 0: if signaling is not secure + * 1: if TLS transport is used for immediate hop + * 2: if end-to-end signaling is secure. + * + * NOTE: + * THIS IS WRONG. It should take into account the route-set. + */ +static int get_secure_level(const pj_str_t *dst_uri) +{ + const pj_str_t tls = pj_str(";transport=tls"); + const pj_str_t sips = pj_str("sips:"); + + PJ_TODO(Fix_get_secure_level); + + if (pj_stristr(dst_uri, &sips)) + return 2; + if (pj_stristr(dst_uri, &tls)) + return 1; + return 0; +} + /* * Make outgoing call to the specified URI using the specified account. */ @@ -362,7 +400,8 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id, } /* Init media channel */ - status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC); + status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC, + get_secure_level(dest_uri)); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error initializing media channel", status); goto on_error; @@ -372,7 +411,7 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id, #if LATE_SDP offer = NULL; #else - status = pjsua_media_channel_create_sdp(call->index, dlg->pool, &offer); + status = pjsua_media_channel_create_sdp(call->index, dlg->pool, NULL, &offer); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "pjmedia unable to create SDP", status); goto on_error; @@ -519,7 +558,8 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) int acc_id; pjsua_call *call; int call_id = -1; - pjmedia_sdp_session *answer; + int secure_level; + pjmedia_sdp_session *offer, *answer; pj_status_t status; /* Don't want to handle anything but INVITE */ @@ -614,9 +654,44 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) } } + /* + * 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 + * the call. + */ + acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata); + +#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) + /* Get signaling security level, only when required by SRTP */ + if (pjsua_var.acc[acc_id].cfg.srtp_secure_signaling < 2) { + secure_level = PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport)!=0; + } else +#endif + + { + char *uri; + int uri_len; + pj_str_t dst; + + uri = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE); + uri_len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, + rdata->msg_info.msg->line.req.uri, + uri, PJSIP_MAX_URL_SIZE); + if (uri_len < 1) { + pjsua_perror(THIS_FILE, "Error analyzing dst URI", + PJSIP_EURITOOLONG); + uri_len = 0; + } + + dst.ptr = uri; + dst.slen = uri_len; + + secure_level = get_secure_level(&dst); + } /* Init media channel */ - status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS); + status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, + secure_level); if (status != PJ_SUCCESS) { pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL, NULL, NULL); @@ -624,9 +699,26 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) return PJ_TRUE; } + /* Parse SDP from incoming request */ + if (rdata->msg_info.msg->body) { + status = pjmedia_sdp_parse(rdata->tp_info.pool, + rdata->msg_info.msg->body->data, + rdata->msg_info.msg->body->len, &offer); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, "Error parsing SDP in incoming INVITE", status); + pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 400, NULL, + NULL, NULL); + pjsua_media_channel_deinit(call->index); + PJSUA_UNLOCK(); + return PJ_TRUE; + } + } else { + offer = NULL; + } /* Get media capability from media endpoint: */ - status = pjsua_media_channel_create_sdp(call->index, rdata->tp_info.pool, &answer); + status = pjsua_media_channel_create_sdp(call->index, rdata->tp_info.pool, + offer, &answer); if (status != PJ_SUCCESS) { pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL, NULL, NULL); @@ -635,20 +727,13 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) 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 - * the call. - */ - acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata); - /* Verify that we can handle the request. */ options |= PJSIP_INV_SUPPORT_100REL; if (pjsua_var.acc[acc_id].cfg.require_100rel) options |= PJSIP_INV_REQUIRE_100REL; - status = pjsip_inv_verify_request(rdata, &options, answer, NULL, - pjsua_var.endpt, &response); + status = pjsip_inv_verify_request2(rdata, &options, offer, answer, NULL, + pjsua_var.endpt, &response); if (status != PJ_SUCCESS) { /* @@ -1338,7 +1423,8 @@ PJ_DEF(pj_status_t) pjsua_call_reinvite( pjsua_call_id call_id, } /* Init media channel */ - status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC); + status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC, + get_secure_level(&dlg->remote.info_str)); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error initializing media channel", status); pjsip_dlg_dec_lock(dlg); @@ -1348,7 +1434,8 @@ 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, &sdp); + status = pjsua_media_channel_create_sdp(call->index, call->inv->pool, + NULL, &sdp); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint", status); @@ -1406,7 +1493,8 @@ PJ_DEF(pj_status_t) pjsua_call_update( pjsua_call_id call_id, return status; /* Init media channel */ - status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC); + status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC, + get_secure_level(&dlg->remote.info_str)); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error initializing media channel", status); pjsip_dlg_dec_lock(dlg); @@ -1414,7 +1502,8 @@ PJ_DEF(pj_status_t) pjsua_call_update( pjsua_call_id call_id, } /* Create SDP */ - status = pjsua_media_channel_create_sdp(call->index, call->inv->pool, &sdp); + status = pjsua_media_channel_create_sdp(call->index, call->inv->pool, + NULL, &sdp); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint", status); @@ -2355,7 +2444,8 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv, pj_status_t status) { pjsua_call *call; - const pjmedia_sdp_session *local_sdp; + const pjmedia_sdp_session *c_local; + pjmedia_sdp_session *local_sdp; const pjmedia_sdp_session *remote_sdp; PJSUA_LOCK(); @@ -2384,7 +2474,7 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv, /* Get local and remote SDP */ - status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp); + status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &c_local); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to retrieve currently active local SDP", @@ -2393,6 +2483,7 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv, PJSUA_UNLOCK(); return; } + local_sdp = (pjmedia_sdp_session*) c_local; status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp); if (status != PJ_SUCCESS) { @@ -2524,19 +2615,23 @@ static void pjsua_call_on_rx_offer(pjsip_inv_session *inv, "(media in offer is %s)", call->index, remote_state)); status = create_inactive_sdp( call, &answer ); } else { + int secure_level; PJ_LOG(4,(THIS_FILE, "Call %d: received updated media offer", call->index)); /* Init media channel */ - status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS); + secure_level = get_secure_level(&call->inv->dlg->remote.info_str); + status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, + secure_level); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error initializing media channel", status); PJSUA_UNLOCK(); return; } - status = pjsua_media_channel_create_sdp(call->index, call->inv->pool, &answer); + status = pjsua_media_channel_create_sdp(call->index, call->inv->pool, + offer, &answer); } if (status != PJ_SUCCESS) { @@ -2576,19 +2671,23 @@ static void pjsua_call_on_create_offer(pjsip_inv_session *inv, call->index)); status = create_inactive_sdp( call, offer ); } else { + int secure_level; PJ_LOG(4,(THIS_FILE, "Call %d: asked to send a new offer", call->index)); /* Init media channel */ - status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC); + secure_level = get_secure_level(&call->inv->dlg->remote.info_str); + status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC, + secure_level); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error initializing media channel", status); PJSUA_UNLOCK(); return; } - status = pjsua_media_channel_create_sdp(call->index, call->inv->pool, offer); + status = pjsua_media_channel_create_sdp(call->index, call->inv->pool, + NULL, offer); } if (status != PJ_SUCCESS) { diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index d0d0ad4b..edb537c4 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -87,6 +87,10 @@ PJ_DEF(void) pjsua_config_default(pjsua_config *cfg) cfg->max_calls = 4; cfg->thread_cnt = 1; cfg->nat_type_in_sdp = 1; +#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) + cfg->use_srtp = PJSUA_DEFAULT_USE_SRTP; + cfg->srtp_secure_signaling = PJSUA_DEFAULT_SRTP_SECURE_SIGNALING; +#endif } PJ_DEF(void) pjsua_config_dup(pj_pool_t *pool, @@ -142,6 +146,10 @@ PJ_DEF(void) pjsua_acc_config_default(pjsua_acc_config *cfg) cfg->require_100rel = pjsua_var.ua_cfg.require_100rel; cfg->ka_interval = 15; cfg->ka_data = pj_str("\r\n"); +#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) + cfg->use_srtp = pjsua_var.ua_cfg.use_srtp; + cfg->srtp_secure_signaling = pjsua_var.ua_cfg.srtp_secure_signaling; +#endif } PJ_DEF(void) pjsua_buddy_config_default(pjsua_buddy_config *cfg) diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index 89fc1e36..eab0b524 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -534,6 +534,7 @@ static pj_status_t create_udp_media_transports(pjsua_transport_config *cfg) status); goto on_error; } + status = pjmedia_transport_udp_attach(pjsua_var.med_endpt, NULL, &skinfo, 0, &pjsua_var.calls[i].med_tp); @@ -543,13 +544,13 @@ static pj_status_t create_udp_media_transports(pjsua_transport_config *cfg) goto on_error; } - pjmedia_transport_udp_simulate_lost(pjsua_var.calls[i].med_tp, - PJMEDIA_DIR_ENCODING, - pjsua_var.media_cfg.tx_drop_pct); + pjmedia_transport_simulate_lost(pjsua_var.calls[i].med_tp, + PJMEDIA_DIR_ENCODING, + pjsua_var.media_cfg.tx_drop_pct); - pjmedia_transport_udp_simulate_lost(pjsua_var.calls[i].med_tp, - PJMEDIA_DIR_DECODING, - pjsua_var.media_cfg.rx_drop_pct); + pjmedia_transport_simulate_lost(pjsua_var.calls[i].med_tp, + PJMEDIA_DIR_DECODING, + pjsua_var.media_cfg.rx_drop_pct); } @@ -645,13 +646,13 @@ static pj_status_t create_ice_media_transports(pjsua_transport_config *cfg) goto on_error; } - pjmedia_ice_simulate_lost(pjsua_var.calls[i].med_tp, - PJMEDIA_DIR_ENCODING, - pjsua_var.media_cfg.tx_drop_pct); + pjmedia_transport_simulate_lost(pjsua_var.calls[i].med_tp, + PJMEDIA_DIR_ENCODING, + pjsua_var.media_cfg.tx_drop_pct); - pjmedia_ice_simulate_lost(pjsua_var.calls[i].med_tp, - PJMEDIA_DIR_DECODING, - pjsua_var.media_cfg.rx_drop_pct); + pjmedia_transport_simulate_lost(pjsua_var.calls[i].med_tp, + PJMEDIA_DIR_DECODING, + pjsua_var.media_cfg.rx_drop_pct); status = pjmedia_ice_start_init(pjsua_var.calls[i].med_tp, 0, &addr, &pjsua_var.stun_srv.ipv4, NULL); @@ -744,32 +745,65 @@ PJ_DEF(pj_status_t) pjsua_media_transports_create( pj_status_t pjsua_media_channel_init(pjsua_call_id call_id, - pjsip_role_e role) + pjsip_role_e role, + int security_level) { pjsua_call *call = &pjsua_var.calls[call_id]; - if (pjsua_var.media_cfg.enable_ice) { - pj_ice_sess_role ice_role; - pj_status_t status; +#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) + pjsua_acc *acc = &pjsua_var.acc[call->acc_id]; + pjmedia_srtp_setting srtp_opt; + pjmedia_transport *srtp; + pj_status_t status; +#endif + + PJ_UNUSED_ARG(role); - ice_role = (role==PJSIP_ROLE_UAC ? PJ_ICE_SESS_ROLE_CONTROLLING : - PJ_ICE_SESS_ROLE_CONTROLLED); + /* Return error if media transport has not been created yet + * (e.g. application is starting) + */ + if (call->med_tp == NULL) { + return PJ_EBUSY; + } - /* Restart ICE */ - pjmedia_ice_stop_ice(call->med_tp); + /* Stop media transport (for good measure!) */ + pjmedia_transport_media_stop(call->med_tp); - status = pjmedia_ice_init_ice(call->med_tp, ice_role, NULL, NULL); - if (status != PJ_SUCCESS) - return status; +#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) + /* Check if SRTP requires secure signaling */ + if (acc->cfg.use_srtp != PJMEDIA_SRTP_DISABLED) { + if (security_level < acc->cfg.srtp_secure_signaling) { + return PJSIP_ESESSIONINSECURE; + } } + /* Always create SRTP adapter */ + pjmedia_srtp_setting_default(&srtp_opt); + srtp_opt.close_member_tp = PJ_FALSE; + srtp_opt.use = acc->cfg.use_srtp; + status = pjmedia_transport_srtp_create(pjsua_var.med_endpt, + call->med_tp, + &srtp_opt, &srtp); + if (status != PJ_SUCCESS) + return status; + + /* Set SRTP as current media transport */ + call->med_orig = call->med_tp; + call->med_tp = srtp; +#else + call->med_orig = call->med_tp; + PJ_UNUSED_ARG(security_level); +#endif + return PJ_SUCCESS; } pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id, pj_pool_t *pool, + const pjmedia_sdp_session *rem_sdp, pjmedia_sdp_session **p_sdp) { + enum { MAX_MEDIA = 1, MEDIA_IDX = 0 }; pjmedia_sdp_session *sdp; pjmedia_sock_info skinfo; pjsua_call *call = &pjsua_var.calls[call_id]; @@ -786,7 +820,7 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id, pjmedia_transport_get_info(call->med_tp, &skinfo); /* Create SDP */ - status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, pool, 1, + status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, pool, MAX_MEDIA, &skinfo, &sdp); if (status != PJ_SUCCESS) goto on_error; @@ -815,11 +849,11 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id, } - if (pjsua_var.media_cfg.enable_ice) { - status = pjmedia_ice_modify_sdp(call->med_tp, pool, sdp); - if (status != PJ_SUCCESS) - goto on_error; - } + /* Give the SDP to media transport */ + status = pjmedia_transport_media_create(call->med_tp, pool, + sdp, rem_sdp, MEDIA_IDX); + if (status != PJ_SUCCESS) + goto on_error; *p_sdp = sdp; return PJ_SUCCESS; @@ -858,10 +892,12 @@ pj_status_t pjsua_media_channel_deinit(pjsua_call_id call_id) stop_media_session(call_id); - if (pjsua_var.media_cfg.enable_ice) { - pjmedia_ice_stop_ice(call->med_tp); - } + pjmedia_transport_media_stop(call->med_tp); + if (call->med_tp != call->med_orig) { + pjmedia_transport_close(call->med_tp); + call->med_tp = call->med_orig; + } return PJ_SUCCESS; } @@ -877,14 +913,14 @@ static void dtmf_callback(pjmedia_stream *strm, void *user_data, if (pjsua_var.ua_cfg.cb.on_dtmf_digit) { pjsua_call_id call_id; - call_id = (pjsua_call_id)user_data; + call_id = (pjsua_call_id)(long)user_data; pjsua_var.ua_cfg.cb.on_dtmf_digit(call_id, digit); } } pj_status_t pjsua_media_channel_update(pjsua_call_id call_id, - const pjmedia_sdp_session *local_sdp, + pjmedia_sdp_session *local_sdp, const pjmedia_sdp_session *remote_sdp) { unsigned i; @@ -911,7 +947,8 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id, /* Find which session is audio (we only support audio for now) */ for (i=0; i < sess_info.stream_cnt; ++i) { if (sess_info.stream_info[i].type == PJMEDIA_TYPE_AUDIO && - sess_info.stream_info[i].proto == PJMEDIA_TP_PROTO_RTP_AVP) + (sess_info.stream_info[i].proto == PJMEDIA_TP_PROTO_RTP_AVP || + sess_info.stream_info[i].proto == PJMEDIA_TP_PROTO_RTP_SAVP)) { si = &sess_info.stream_info[i]; break; @@ -945,21 +982,18 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id, call->media_dir = PJMEDIA_DIR_NONE; - /* Shutdown ICE session */ - if (pjsua_var.media_cfg.enable_ice) { - pjmedia_ice_stop_ice(call->med_tp); - } + /* Shutdown transport's session */ + pjmedia_transport_media_stop(call->med_tp); /* No need because we need keepalive? */ } else { - /* Start ICE */ - if (pjsua_var.media_cfg.enable_ice) { - status = pjmedia_ice_start_ice(call->med_tp, call->inv->pool, - remote_sdp, 0); - if (status != PJ_SUCCESS) - return status; - } + /* Start media transport */ + status = pjmedia_transport_media_start(call->med_tp, + call->inv->pool, + local_sdp, remote_sdp, 0); + if (status != PJ_SUCCESS) + return status; /* Override ptime, if this option is specified. */ if (pjsua_var.media_cfg.ptime != 0) { @@ -1000,7 +1034,7 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id, if (pjsua_var.ua_cfg.cb.on_dtmf_digit) { pjmedia_session_set_dtmf_callback(call->session, 0, &dtmf_callback, - (void*)(call->index)); + (void*)(long)(call->index)); } /* Get the port interface of the first stream in the session. -- cgit v1.2.3