diff options
author | Liong Sauw Ming <ming@teluu.com> | 2011-06-16 05:10:45 +0000 |
---|---|---|
committer | Liong Sauw Ming <ming@teluu.com> | 2011-06-16 05:10:45 +0000 |
commit | d1fc1193fc57517f5adc32bc2e0b9077fd367304 (patch) | |
tree | d7e0d008d09a3468974bca26b23f97baf15c83e4 | |
parent | 6e5dd25621edefef5a17a000bd75b0d825d6c32f (diff) |
Closed #1173: PJSUA callback to allow creation of custom media transports by application
git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/1.x@3585 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 42 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_media.c | 25 |
2 files changed, 66 insertions, 1 deletions
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 404b140c..b52990eb 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -421,6 +421,22 @@ typedef struct pjsua_reg_info /** + * This enumeration specifies the options for custom media transport creation. + */ +typedef enum pjsua_create_media_transport_flag +{ + /** + * This flag indicates that the media transport must also close its + * "member" or "child" transport when pjmedia_transport_close() is + * called. If this flag is not specified, then the media transport + * must not call pjmedia_transport_close() of its member transport. + */ + PJSUA_MED_TP_CLOSE_MEMBER = 1 + +} pjsua_create_media_transport_flag; + + +/** * This structure describes application callback to receive various event * notification from PJSUA-API. All of these callbacks are OPTIONAL, * although definitely application would want to implement some of @@ -918,6 +934,32 @@ typedef struct pjsua_callback void (*on_ice_transport_error)(int index, pj_ice_strans_op op, pj_status_t status, void *param); + /** + * This callback can be used by application to implement custom media + * transport adapter for the call, or to replace the media transport + * with something completely new altogether. + * + * This callback is called when a new call is created. The library has + * created a media transport for the call, and it is provided as the + * \a base_tp argument of this callback. Upon returning, the callback + * must return an instance of media transport to be used by the call. + * + * @param call_id Call ID + * @param media_idx The media index in the SDP for which this media + * transport will be used. + * @param base_tp The media transport which otherwise will be + * used by the call has this callback not been + * implemented. + * @param flags Bitmask from pjsua_create_media_transport_flag. + * + * @return The callback must return an instance of media + * transport to be used by the call. + */ + pjmedia_transport* (*on_create_media_transport)(pjsua_call_id call_id, + unsigned media_idx, + pjmedia_transport *base_tp, + unsigned flags); + } pjsua_callback; diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index f6791131..bf121e78 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -1174,6 +1174,8 @@ pj_status_t pjsua_media_channel_init(pjsua_call_id call_id, { pjsua_call *call = &pjsua_var.calls[call_id]; pj_status_t status; + pj_bool_t use_custom_med_tp = PJ_FALSE; + unsigned custom_med_tp_flags = 0; #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) pjsua_acc *acc = &pjsua_var.acc[call->acc_id]; @@ -1192,11 +1194,17 @@ pj_status_t pjsua_media_channel_init(pjsua_call_id call_id, return PJ_EBUSY; } + if (!call->med_orig && + pjsua_var.ua_cfg.cb.on_create_media_transport) + { + use_custom_med_tp = PJ_TRUE; + } + #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) /* This function may be called when SRTP transport already exists * (e.g: in re-invite, update), don't need to destroy/re-create. */ - if (!call->med_orig || call->med_tp == call->med_orig) { + if (!call->med_orig) { /* Check if SRTP requires secure signaling */ if (acc->cfg.use_srtp != PJMEDIA_SRTP_DISABLED) { @@ -1210,6 +1218,8 @@ pj_status_t pjsua_media_channel_init(pjsua_call_id call_id, /* Always create SRTP adapter */ pjmedia_srtp_setting_default(&srtp_opt); srtp_opt.close_member_tp = PJ_FALSE; + if (use_custom_med_tp) + custom_med_tp_flags |= PJSUA_MED_TP_CLOSE_MEMBER; /* If media session has been ever established, let's use remote's * preference in SRTP usage policy, especially when it is stricter. */ @@ -1268,6 +1278,18 @@ pj_status_t pjsua_media_channel_init(pjsua_call_id call_id, PJ_LOG(4,(THIS_FILE, "Media index %d selected for call %d", call->audio_idx, call->index)); + if (use_custom_med_tp) { + /* Use custom media transport returned by the application */ + call->med_tp = (*pjsua_var.ua_cfg.cb.on_create_media_transport)( + call_id, call->audio_idx, call->med_tp, + custom_med_tp_flags); + if (!call->med_tp) { + if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE; + pjsua_media_channel_deinit(call_id); + return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE); + } + } + /* Create the media transport */ status = pjmedia_transport_media_create(call->med_tp, tmp_pool, 0, rem_sdp, call->audio_idx); @@ -1543,6 +1565,7 @@ pj_status_t pjsua_media_channel_deinit(pjsua_call_id call_id) if (call->med_orig && call->med_tp && call->med_tp != call->med_orig) { pjmedia_transport_close(call->med_tp); call->med_tp = call->med_orig; + call->med_orig = NULL; } check_snd_dev_idle(); |