diff options
-rw-r--r-- | pjsip-apps/src/pjsua/pjsua_app.c | 36 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 20 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_acc.c | 1 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 1 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_media.c | 40 |
5 files changed, 92 insertions, 6 deletions
diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c index 6bb23d23..aed2dd53 100644 --- a/pjsip-apps/src/pjsua/pjsua_app.c +++ b/pjsip-apps/src/pjsua/pjsua_app.c @@ -178,7 +178,8 @@ static void usage(void) puts ("SIP Account options:"); puts (" --use-ims Enable 3GPP/IMS related settings on this account"); #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) - puts (" --use-srtp=N Use SRTP? 0:disabled, 1:optional, 2:mandatory (def:0)"); + puts (" --use-srtp=N Use SRTP? 0:disabled, 1:optional, 2:mandatory,"); + puts (" 3:optional by duplicating media offer (def:0)"); puts (" --srtp-secure=N SRTP require secure SIP? 0:no, 1:tls, 1:sips (def:1)"); #endif puts (" --registrar=url Set the URL of registrar server"); @@ -1092,10 +1093,16 @@ static pj_status_t parse_args(int argc, char *argv[], #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) case OPT_USE_SRTP: app_config.cfg.use_srtp = my_atoi(pj_optarg); - if (!pj_isdigit(*pj_optarg) || app_config.cfg.use_srtp > 2) { + if (!pj_isdigit(*pj_optarg) || app_config.cfg.use_srtp > 3) { PJ_LOG(1,(THIS_FILE, "Invalid value for --use-srtp option")); return -1; } + if ((int)app_config.cfg.use_srtp == 3) { + /* SRTP optional mode with duplicated media offer */ + app_config.cfg.use_srtp = PJMEDIA_SRTP_OPTIONAL; + app_config.cfg.srtp_optional_dup_offer = PJ_TRUE; + cur_acc->srtp_optional_dup_offer = PJ_TRUE; + } cur_acc->use_srtp = app_config.cfg.use_srtp; break; case OPT_SRTP_SECURE: @@ -1503,8 +1510,20 @@ static void write_account_settings(int acc_index, pj_str_t *result) #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) /* SRTP */ if (acc_cfg->use_srtp) { - pj_ansi_sprintf(line, "--use-srtp %i\n", - (int)acc_cfg->use_srtp); + int use_srtp = (int)acc_cfg->use_srtp; + if (use_srtp == PJMEDIA_SRTP_OPTIONAL && + acc_cfg->srtp_optional_dup_offer) + { + use_srtp = 3; + } + pj_ansi_sprintf(line, "--use-srtp %i\n", use_srtp); + pj_strcat2(result, line); + } + if (acc_cfg->srtp_secure_signaling != + PJSUA_DEFAULT_SRTP_SECURE_SIGNALING) + { + pj_ansi_sprintf(line, "--srtp-secure %d\n", + acc_cfg->srtp_secure_signaling); pj_strcat2(result, line); } #endif @@ -1736,8 +1755,13 @@ static int write_settings(const struct app_config *config, /* SRTP */ #if PJMEDIA_HAS_SRTP if (app_config.cfg.use_srtp != PJSUA_DEFAULT_USE_SRTP) { - pj_ansi_sprintf(line, "--use-srtp %d\n", - app_config.cfg.use_srtp); + int use_srtp = (int)app_config.cfg.use_srtp; + if (use_srtp == PJMEDIA_SRTP_OPTIONAL && + app_config.cfg.srtp_optional_dup_offer) + { + use_srtp = 3; + } + pj_ansi_sprintf(line, "--use-srtp %d\n", use_srtp); pj_strcat2(&cfg, line); } if (app_config.cfg.srtp_secure_signaling != diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 5d228083..58574e92 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -1083,6 +1083,16 @@ typedef struct pjsua_config * Default: #PJSUA_DEFAULT_SRTP_SECURE_SIGNALING */ int srtp_secure_signaling; + + /** + * Specify whether SRTP in PJMEDIA_SRTP_OPTIONAL mode should compose + * duplicated media in SDP offer, i.e: unsecured and secured version. + * Otherwise, the SDP media will be composed as unsecured media but + * with SDP "crypto" attribute. + * + * Default: PJ_FALSE + */ + pj_bool_t srtp_optional_dup_offer; #endif /** @@ -2126,6 +2136,16 @@ typedef struct pjsua_acc_config * Default: #PJSUA_DEFAULT_SRTP_SECURE_SIGNALING */ int srtp_secure_signaling; + + /** + * Specify whether SRTP in PJMEDIA_SRTP_OPTIONAL mode should compose + * duplicated media in SDP offer, i.e: unsecured and secured version. + * Otherwise, the SDP media will be composed as unsecured media but + * with SDP "crypto" attribute. + * + * Default: PJ_FALSE + */ + pj_bool_t srtp_optional_dup_offer; #endif /** diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index 6af6b3d4..3ddcdd59 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -751,6 +751,7 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id, #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) acc->cfg.use_srtp = cfg->use_srtp; acc->cfg.srtp_secure_signaling = cfg->srtp_secure_signaling; + acc->cfg.srtp_optional_dup_offer = cfg->srtp_optional_dup_offer; #endif /* Global outbound proxy */ diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index dd892373..5d231cbf 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -175,6 +175,7 @@ PJ_DEF(void) pjsua_acc_config_default(pjsua_acc_config *cfg) #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; + cfg->srtp_optional_dup_offer = pjsua_var.ua_cfg.srtp_optional_dup_offer; #endif cfg->reg_retry_interval = PJSUA_REG_RETRY_INTERVAL; } diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index c0a7c3c2..ed5a99ad 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -1369,6 +1369,46 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id, return status; } +#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) + /* Check if SRTP is in optional mode and configured to use duplicated + * media, i.e: secured and unsecured version, in the SDP offer. + */ + if (!rem_sdp && + pjsua_var.acc[call->acc_id].cfg.use_srtp == PJMEDIA_SRTP_OPTIONAL && + pjsua_var.acc[call->acc_id].cfg.srtp_optional_dup_offer) + { + unsigned i; + + for (i = 0; i < sdp->media_count; ++i) { + pjmedia_sdp_media *m = sdp->media[i]; + + /* Check if this media is unsecured but has SDP "crypto" + * attribute. + */ + if (pj_stricmp2(&m->desc.transport, "RTP/AVP") == 0 && + pjmedia_sdp_media_find_attr2(m, "crypto", NULL) != NULL) + { + pjmedia_sdp_media *new_m; + + /* Duplicate this media and apply secured transport */ + new_m = pjmedia_sdp_media_clone(pool, m); + pj_strdup2(pool, &new_m->desc.transport, "RTP/SAVP"); + + /* Remove the "crypto" attribute in the unsecured media */ + pjmedia_sdp_media_remove_all_attr(m, "crypto"); + + /* Insert the new media before the unsecured media */ + if (sdp->media_count < PJMEDIA_MAX_SDP_MEDIA) { + pj_array_insert(sdp->media, sizeof(new_m), + sdp->media_count, i, &new_m); + ++sdp->media_count; + ++i; + } + } + } + } +#endif + /* Update currently advertised RTP source address */ pj_memcpy(&call->med_rtp_addr, &tpinfo.sock_info.rtp_addr_name, sizeof(pj_sockaddr)); |