summaryrefslogtreecommitdiff
path: root/pjsip/src/pjsua-lib
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2008-01-23 20:39:07 +0000
committerBenny Prijono <bennylp@teluu.com>2008-01-23 20:39:07 +0000
commit8686b3135348bcd69bdb3c3cb6660a82d989bb30 (patch)
tree31d9c111724f083782ba5782c58ab2d30a867933 /pjsip/src/pjsua-lib
parent5035ea445fbf6de061efacd90c66390ca15806ed (diff)
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
Diffstat (limited to 'pjsip/src/pjsua-lib')
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c147
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c8
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c128
3 files changed, 212 insertions, 71 deletions
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.