summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2008-03-11 21:38:05 +0000
committerBenny Prijono <bennylp@teluu.com>2008-03-11 21:38:05 +0000
commit4e1d5dc0d96e099f12ea0127434b4f7029e95b2b (patch)
tree8471f75aefe77e864a4c9216f29ad04f2c8bf945
parentcedeaec6e1f22463dc1e13e3dee467fc4dcd4019 (diff)
Ticket #479: allow media transport framework to return transport specific info (for example, to know whether SRTP is enabled)
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1860 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/include/pjmedia/config.h21
-rw-r--r--pjmedia/include/pjmedia/transport.h70
-rw-r--r--pjmedia/include/pjmedia/transport_srtp.h24
-rw-r--r--pjmedia/src/pjmedia/transport_ice.c17
-rw-r--r--pjmedia/src/pjmedia/transport_srtp.c30
-rw-r--r--pjmedia/src/pjmedia/transport_udp.c13
-rw-r--r--pjsip-apps/src/samples/simpleua.c9
-rw-r--r--pjsip-apps/src/samples/siprtp.c4
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c38
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c16
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c6
11 files changed, 204 insertions, 44 deletions
diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h
index 0640b184..38dd872c 100644
--- a/pjmedia/include/pjmedia/config.h
+++ b/pjmedia/include/pjmedia/config.h
@@ -525,6 +525,27 @@
/**
+ * Transport info (pjmedia_transport_info) contains a socket info and list
+ * of transport specific info, since transports can be chained together
+ * (for example, SRTP transport uses UDP transport as the underlying
+ * transport). This constant specifies maximum number of transport specific
+ * infos that can be held in a transport info.
+ */
+#ifndef PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT
+# define PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT 4
+#endif
+
+
+/**
+ * Maximum size in bytes of storage buffer of a transport specific info.
+ */
+#ifndef PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE
+# define PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE (12*sizeof(long))
+#endif
+
+
+
+/**
* @}
*/
diff --git a/pjmedia/include/pjmedia/transport.h b/pjmedia/include/pjmedia/transport.h
index 2629cf87..fcf120da 100644
--- a/pjmedia/include/pjmedia/transport.h
+++ b/pjmedia/include/pjmedia/transport.h
@@ -207,12 +207,18 @@ PJ_BEGIN_DECL
#include <pjmedia/sdp.h>
+
/**
* Forward declaration for media transport.
*/
typedef struct pjmedia_transport pjmedia_transport;
/**
+ * Forward declaration for media transport info.
+ */
+typedef struct pjmedia_transport_info pjmedia_transport_info;
+
+/**
* This enumeration specifies the general behaviour of media processing
*/
typedef enum pjmedia_tranport_media_option
@@ -228,6 +234,7 @@ typedef enum pjmedia_tranport_media_option
} pjmedia_tranport_media_option;
+
/**
* This structure describes the operations for the stream transport.
*/
@@ -239,7 +246,7 @@ struct pjmedia_transport_op
* Application should call #pjmedia_transport_get_info() instead
*/
pj_status_t (*get_info)(pjmedia_transport *tp,
- pjmedia_sock_info *info);
+ pjmedia_transport_info *info);
/**
* This function is called by the stream when the transport is about
@@ -368,7 +375,14 @@ typedef enum pjmedia_transport_type
PJMEDIA_TRANSPORT_TYPE_UDP,
/** Media transport using ICE */
- PJMEDIA_TRANSPORT_TYPE_ICE
+ PJMEDIA_TRANSPORT_TYPE_ICE,
+
+ /**
+ * Media transport SRTP, this transport is actually security adapter to be
+ * stacked with other transport to enable encryption on the underlying
+ * transport.
+ */
+ PJMEDIA_TRANSPORT_TYPE_SRTP
} pjmedia_transport_type;
@@ -390,6 +404,56 @@ struct pjmedia_transport
pjmedia_transport_op *op;
};
+/**
+ * This structure describes buffer storage of transport specific info.
+ * The actual transport specific info contents will be defined by transport
+ * implementation. Note that some transport implementations do not need to
+ * provide specific info, since the general socket info is enough.
+ */
+typedef struct pjmedia_transport_specific_info
+{
+ /**
+ * Specify media transport type.
+ */
+ pjmedia_transport_type type;
+
+ /**
+ * Specify storage buffer size of transport specific info.
+ */
+ int cbsize;
+
+ /**
+ * Storage buffer of transport specific info.
+ */
+ char buffer[PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE];
+
+} pjmedia_transport_specific_info;
+
+
+/**
+ * This structure describes transport informations, including general
+ * socket information and specific information of single transport or
+ * stacked transports (e.g: SRTP stacked on top of UDP)
+ */
+struct pjmedia_transport_info
+{
+ /**
+ * General socket info.
+ */
+ pjmedia_sock_info sock_info;
+
+ /**
+ * Specifies number of transport specific info included.
+ */
+ int specific_info_cnt;
+
+ /**
+ * Buffer storage of transport specific info.
+ */
+ pjmedia_transport_specific_info spc_info[PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT];
+
+};
+
/**
* Get media socket info from the specified transport. The socket info
@@ -403,7 +467,7 @@ struct pjmedia_transport
* @return PJ_SUCCESS on success.
*/
PJ_INLINE(pj_status_t) pjmedia_transport_get_info(pjmedia_transport *tp,
- pjmedia_sock_info *info)
+ pjmedia_transport_info *info)
{
if (tp->op->get_info)
return (*tp->op->get_info)(tp, info);
diff --git a/pjmedia/include/pjmedia/transport_srtp.h b/pjmedia/include/pjmedia/transport_srtp.h
index a04e28b6..d2b6a015 100644
--- a/pjmedia/include/pjmedia/transport_srtp.h
+++ b/pjmedia/include/pjmedia/transport_srtp.h
@@ -160,6 +160,30 @@ typedef struct pjmedia_srtp_setting
/**
+ * This structure specifies SRTP transport specific info. This will fit
+ * into \a buffer field of pjmedia_transport_specific_info.
+ */
+typedef struct pjmedia_srtp_info
+{
+ /**
+ * Specify whether the SRTP transport is active for SRTP session.
+ */
+ pj_bool_t active;
+
+ /**
+ * Specify the policy used by the SRTP session for receive direction.
+ */
+ pjmedia_srtp_crypto rx_policy;
+
+ /**
+ * Specify the policy used by the SRTP session for transmit direction.
+ */
+ pjmedia_srtp_crypto tx_policy;
+
+} pjmedia_srtp_info;
+
+
+/**
* Initialize SRTP setting with its default values.
*
* @param opt SRTP setting to be initialized.
diff --git a/pjmedia/src/pjmedia/transport_ice.c b/pjmedia/src/pjmedia/transport_ice.c
index 8a6124f3..0534ad4b 100644
--- a/pjmedia/src/pjmedia/transport_ice.c
+++ b/pjmedia/src/pjmedia/transport_ice.c
@@ -55,7 +55,7 @@ struct transport_ice
* These are media transport operations.
*/
static pj_status_t transport_get_info (pjmedia_transport *tp,
- pjmedia_sock_info *info);
+ pjmedia_transport_info *info);
static pj_status_t transport_attach (pjmedia_transport *tp,
void *user_data,
const pj_sockaddr_t *rem_addr,
@@ -673,20 +673,20 @@ static pj_status_t transport_media_stop(pjmedia_transport *tp)
static pj_status_t transport_get_info(pjmedia_transport *tp,
- pjmedia_sock_info *info)
+ pjmedia_transport_info *info)
{
struct transport_ice *tp_ice = (struct transport_ice*)tp;
pj_ice_strans *ice_st = tp_ice->ice_st;
pj_ice_strans_comp *comp;
- pj_bzero(info, sizeof(*info));
- info->rtp_sock = info->rtcp_sock = PJ_INVALID_SOCKET;
+ pj_bzero(&info->sock_info, sizeof(info->sock_info));
+ info->sock_info.rtp_sock = info->sock_info.rtcp_sock = PJ_INVALID_SOCKET;
/* Retrieve address of default candidate for component 1 (RTP) */
comp = ice_st->comp[0];
pj_assert(comp->default_cand >= 0);
- info->rtp_sock = comp->sock;
- pj_memcpy(&info->rtp_addr_name,
+ info->sock_info.rtp_sock = comp->sock;
+ pj_memcpy(&info->sock_info.rtp_addr_name,
&comp->cand_list[comp->default_cand].addr,
sizeof(pj_sockaddr_in));
@@ -694,12 +694,13 @@ static pj_status_t transport_get_info(pjmedia_transport *tp,
if (ice_st->comp_cnt > 1) {
comp = ice_st->comp[1];
pj_assert(comp->default_cand >= 0);
- info->rtp_sock = comp->sock;
- pj_memcpy(&info->rtcp_addr_name,
+ info->sock_info.rtp_sock = comp->sock;
+ pj_memcpy(&info->sock_info.rtcp_addr_name,
&comp->cand_list[comp->default_cand].addr,
sizeof(pj_sockaddr_in));
}
+ info->specific_info_cnt = 0;
return PJ_SUCCESS;
}
diff --git a/pjmedia/src/pjmedia/transport_srtp.c b/pjmedia/src/pjmedia/transport_srtp.c
index 5dadb207..3bd95c88 100644
--- a/pjmedia/src/pjmedia/transport_srtp.c
+++ b/pjmedia/src/pjmedia/transport_srtp.c
@@ -125,7 +125,7 @@ static void srtp_rtcp_cb( void *user_data, void *pkt, pj_ssize_t size);
* These are media transport operations.
*/
static pj_status_t transport_get_info (pjmedia_transport *tp,
- pjmedia_sock_info *info);
+ pjmedia_transport_info *info);
static pj_status_t transport_attach (pjmedia_transport *tp,
void *user_data,
const pj_sockaddr_t *rem_addr,
@@ -551,12 +551,34 @@ PJ_DEF(pjmedia_transport *) pjmedia_transport_srtp_get_member(
static pj_status_t transport_get_info(pjmedia_transport *tp,
- pjmedia_sock_info *info)
+ pjmedia_transport_info *info)
{
transport_srtp *srtp = (transport_srtp*) tp;
+ pjmedia_srtp_info srtp_info;
+ int spc_info_idx;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(tp && info, PJ_EINVAL);
+ PJ_ASSERT_RETURN(info->specific_info_cnt <
+ PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT, PJ_ETOOMANY);
+ PJ_ASSERT_RETURN(sizeof(pjmedia_srtp_info) <=
+ PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE, PJ_ENOMEM);
+
+ status = pjmedia_transport_get_info(srtp->real_tp, info);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ srtp_info.active = srtp->session_inited;
+ srtp_info.rx_policy = srtp->rx_policy;
+ srtp_info.tx_policy = srtp->tx_policy;
- /* put SRTP info as well? */
- return pjmedia_transport_get_info(srtp->real_tp, info);
+ spc_info_idx = info->specific_info_cnt++;
+ info->spc_info[spc_info_idx].type = PJMEDIA_TRANSPORT_TYPE_SRTP;
+ info->spc_info[spc_info_idx].cbsize = sizeof(srtp_info);
+ pj_memcpy(&info->spc_info[spc_info_idx].buffer, &srtp_info,
+ sizeof(srtp_info));
+
+ return PJ_SUCCESS;
}
static pj_status_t transport_attach(pjmedia_transport *tp,
diff --git a/pjmedia/src/pjmedia/transport_udp.c b/pjmedia/src/pjmedia/transport_udp.c
index a341d44a..f4e12cd1 100644
--- a/pjmedia/src/pjmedia/transport_udp.c
+++ b/pjmedia/src/pjmedia/transport_udp.c
@@ -101,7 +101,7 @@ static void on_rx_rtcp(pj_ioqueue_key_t *key,
* These are media transport operations.
*/
static pj_status_t transport_get_info (pjmedia_transport *tp,
- pjmedia_sock_info *info);
+ pjmedia_transport_info *info);
static pj_status_t transport_attach (pjmedia_transport *tp,
void *user_data,
const pj_sockaddr_t *rem_addr,
@@ -584,15 +584,16 @@ static void on_rx_rtcp(pj_ioqueue_key_t *key,
/* Called to get the transport info */
static pj_status_t transport_get_info(pjmedia_transport *tp,
- pjmedia_sock_info *info)
+ pjmedia_transport_info *info)
{
struct transport_udp *udp = (struct transport_udp*)tp;
PJ_ASSERT_RETURN(tp && info, PJ_EINVAL);
- info->rtp_sock = udp->rtp_sock;
- info->rtp_addr_name = udp->rtp_addr_name;
- info->rtcp_sock = udp->rtcp_sock;
- info->rtcp_addr_name = udp->rtcp_addr_name;
+ info->sock_info.rtp_sock = udp->rtp_sock;
+ info->sock_info.rtp_addr_name = udp->rtp_addr_name;
+ info->sock_info.rtcp_sock = udp->rtcp_sock;
+ info->sock_info.rtcp_addr_name = udp->rtcp_addr_name;
+ info->specific_info_cnt = 0;
return PJ_SUCCESS;
}
diff --git a/pjsip-apps/src/samples/simpleua.c b/pjsip-apps/src/samples/simpleua.c
index 313deee9..634bc539 100644
--- a/pjsip-apps/src/samples/simpleua.c
+++ b/pjsip-apps/src/samples/simpleua.c
@@ -81,7 +81,7 @@ static pjsip_endpoint *g_endpt; /* SIP endpoint. */
static pj_caching_pool cp; /* Global pool factory. */
static pjmedia_endpt *g_med_endpt; /* Media endpoint. */
-static pjmedia_sock_info g_med_skinfo; /* Socket info for media */
+static pjmedia_transport_info g_med_tpinfo; /* Socket info for media */
static pjmedia_transport *g_med_transport;/* Media stream transport */
/* Call variables: */
@@ -301,7 +301,7 @@ int main(int argc, char *argv[])
* need this info to create SDP (i.e. the address and port info in
* the SDP).
*/
- pjmedia_transport_get_info(g_med_transport, &g_med_skinfo);
+ pjmedia_transport_get_info(g_med_transport, &g_med_tpinfo);
/*
@@ -364,7 +364,8 @@ int main(int argc, char *argv[])
status = pjmedia_endpt_create_sdp( g_med_endpt, /* the media endpt */
dlg->pool, /* pool. */
1, /* # of streams */
- &g_med_skinfo, /* RTP sock info */
+ &g_med_tpinfo.sock_info,
+ /* RTP sock info */
&local_sdp); /* the SDP result */
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
@@ -571,7 +572,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
*/
status = pjmedia_endpt_create_sdp( g_med_endpt, rdata->tp_info.pool, 1,
- &g_med_skinfo,
+ &g_med_tpinfo.sock_info,
&local_sdp);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
diff --git a/pjsip-apps/src/samples/siprtp.c b/pjsip-apps/src/samples/siprtp.c
index 5f0a3379..53abcdee 100644
--- a/pjsip-apps/src/samples/siprtp.c
+++ b/pjsip-apps/src/samples/siprtp.c
@@ -1005,7 +1005,7 @@ static pj_status_t create_sdp( pj_pool_t *pool,
pjmedia_sdp_session *sdp;
pjmedia_sdp_media *m;
pjmedia_sdp_attr *attr;
- pjmedia_sock_info tpinfo;
+ pjmedia_transport_info tpinfo;
struct media_stream *audio = &call->media[0];
PJ_ASSERT_RETURN(pool && p_sdp, PJ_EINVAL);
@@ -1047,7 +1047,7 @@ static pj_status_t create_sdp( pj_pool_t *pool,
/* Standard media info: */
m->desc.media = pj_str("audio");
- m->desc.port = pj_ntohs(tpinfo.rtp_addr_name.ipv4.sin_port);
+ m->desc.port = pj_ntohs(tpinfo.sock_info.rtp_addr_name.ipv4.sin_port);
m->desc.port_count = 1;
m->desc.transport = pj_str("RTP/AVP");
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 403a473a..6329732a 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -2200,6 +2200,7 @@ PJ_DEF(pj_status_t) pjsua_call_dump( pjsua_call_id call_id,
char *p, *end;
pj_status_t status;
int len;
+ pjmedia_transport_info tp_info;
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
PJ_EINVAL);
@@ -2258,6 +2259,31 @@ PJ_DEF(pj_status_t) pjsua_call_dump( pjsua_call_id call_id,
*p = '\0';
}
+ /* Get SRTP status */
+ pjmedia_transport_get_info(call->med_tp, &tp_info);
+ if (tp_info.specific_info_cnt > 0) {
+ int i;
+ for (i = 0; i < tp_info.specific_info_cnt; ++i) {
+ if (tp_info.spc_info[i].type == PJMEDIA_TRANSPORT_TYPE_SRTP)
+ {
+ pjmedia_srtp_info *srtp_info =
+ (pjmedia_srtp_info*) tp_info.spc_info[i].buffer;
+
+ len = pj_ansi_snprintf(p, end-p,
+ "%s SRTP status: %s Crypto-suite: %s",
+ indent,
+ (srtp_info->active?"Active":"Not active"),
+ srtp_info->tx_policy.name.ptr);
+ if (len > 0 && len < end-p) {
+ p += len;
+ *p++ = '\n';
+ *p = '\0';
+ }
+ break;
+ }
+ }
+ }
+
/* Dump session statistics */
if (with_media && call->session)
dump_media_session(indent, p, end-p, call->session);
@@ -2442,11 +2468,11 @@ static void call_disconnect( pjsip_inv_session *inv,
code==PJSIP_SC_NOT_ACCEPTABLE_HERE)
{
pjmedia_sdp_session *local_sdp;
- pjmedia_sock_info si;
+ pjmedia_transport_info ti;
- call->med_tp->op->get_info(call->med_tp, &si);
+ pjmedia_transport_get_info(call->med_tp, &ti);
status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, tdata->pool,
- 1, &si, &local_sdp);
+ 1, &ti.sock_info, &local_sdp);
if (status == PJ_SUCCESS) {
pjsip_create_sdp_body(tdata->pool, local_sdp,
&tdata->msg->body);
@@ -2551,15 +2577,15 @@ static pj_status_t create_inactive_sdp(pjsua_call *call,
pj_status_t status;
pjmedia_sdp_conn *conn;
pjmedia_sdp_attr *attr;
- pjmedia_sock_info skinfo;
+ pjmedia_transport_info tp_info;
pjmedia_sdp_session *sdp;
/* Get media socket info */
- pjmedia_transport_get_info(call->med_tp, &skinfo);
+ pjmedia_transport_get_info(call->med_tp, &tp_info);
/* Create new offer */
status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, pjsua_var.pool, 1,
- &skinfo, &sdp);
+ &tp_info.sock_info, &sdp);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
return status;
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 40471583..ef838ba8 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -260,7 +260,7 @@ static pj_bool_t options_on_rx_request(pjsip_rx_data *rdata)
{
pjsip_tx_data *tdata;
pjsip_response_addr res_addr;
- pjmedia_sock_info skinfo;
+ pjmedia_transport_info tpinfo;
pjmedia_sdp_session *sdp;
const pjsip_hdr *cap_hdr;
pj_status_t status;
@@ -320,11 +320,11 @@ static pj_bool_t options_on_rx_request(pjsip_rx_data *rdata)
}
/* Get media socket info */
- pjmedia_transport_get_info(pjsua_var.calls[0].med_tp, &skinfo);
+ pjmedia_transport_get_info(pjsua_var.calls[0].med_tp, &tpinfo);
/* Add SDP body, using call0's RTP address */
status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, tdata->pool, 1,
- &skinfo, &sdp);
+ &tpinfo.sock_info, &sdp);
if (status == PJ_SUCCESS) {
pjsip_create_sdp_body(tdata->pool, sdp, &tdata->msg->body);
}
@@ -2060,17 +2060,17 @@ PJ_DEF(void) pjsua_dump(pj_bool_t detail)
PJ_LOG(3,(THIS_FILE, "Dumping media transports:"));
for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
pjsua_call *call = &pjsua_var.calls[i];
- pjmedia_sock_info skinfo;
+ pjmedia_transport_info tpinfo;
char addr_buf[80];
- /* MSVC complains about skinfo not being initialized */
- pj_bzero(&skinfo, sizeof(skinfo));
+ /* MSVC complains about tpinfo not being initialized */
+ pj_bzero(&tpinfo, sizeof(tpinfo));
- pjmedia_transport_get_info(call->med_tp, &skinfo);
+ pjmedia_transport_get_info(call->med_tp, &tpinfo);
PJ_LOG(3,(THIS_FILE, " %s: %s",
(pjsua_var.media_cfg.enable_ice ? "ICE" : "UDP"),
- pj_sockaddr_print(&skinfo.rtp_addr_name, addr_buf,
+ pj_sockaddr_print(&tpinfo.sock_info.rtp_addr_name, addr_buf,
sizeof(addr_buf), 3)));
}
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index dea8b5b7..238b1fb5 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -814,7 +814,7 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id,
{
enum { MAX_MEDIA = 1, MEDIA_IDX = 0 };
pjmedia_sdp_session *sdp;
- pjmedia_sock_info skinfo;
+ pjmedia_transport_info tpinfo;
pjsua_call *call = &pjsua_var.calls[call_id];
pj_status_t status;
@@ -826,11 +826,11 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id,
}
/* Get media socket info */
- pjmedia_transport_get_info(call->med_tp, &skinfo);
+ pjmedia_transport_get_info(call->med_tp, &tpinfo);
/* Create SDP */
status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, pool, MAX_MEDIA,
- &skinfo, &sdp);
+ &tpinfo.sock_info, &sdp);
if (status != PJ_SUCCESS) {
if (sip_status_code) *sip_status_code = 500;
goto on_error;