summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.symbian/pjmediaU.def27
-rw-r--r--pjmedia/include/pjmedia/stream.h4
-rw-r--r--pjmedia/include/pjmedia/transport_udp.h26
-rw-r--r--pjmedia/include/pjmedia/types.h4
-rw-r--r--pjmedia/src/pjmedia/endpoint.c61
-rw-r--r--pjmedia/src/pjmedia/session.c90
-rw-r--r--pjmedia/src/pjmedia/transport_udp.c149
-rw-r--r--pjsip-apps/src/samples/siprtp.c2
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c10
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c7
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c10
11 files changed, 265 insertions, 125 deletions
diff --git a/build.symbian/pjmediaU.def b/build.symbian/pjmediaU.def
index f1cfcc02..9f3fc842 100644
--- a/build.symbian/pjmediaU.def
+++ b/build.symbian/pjmediaU.def
@@ -174,16 +174,17 @@ EXPORTS
pjmedia_transport_udp_close @ 173 NONAME
pjmedia_transport_udp_create @ 174 NONAME
pjmedia_transport_udp_create2 @ 175 NONAME
- pjmedia_transport_udp_get_info @ 176 NONAME
- pjmedia_transport_udp_simulate_lost @ 177 NONAME
- pjmedia_wav_player_port_create @ 178 NONAME
- pjmedia_wav_player_port_get_pos @ 179 NONAME
- pjmedia_wav_player_port_set_pos @ 180 NONAME
- pjmedia_wav_player_set_eof_cb @ 181 NONAME
- pjmedia_wav_playlist_create @ 182 NONAME
- pjmedia_wav_playlist_set_eof_cb @ 183 NONAME
- pjmedia_wav_writer_port_create @ 184 NONAME
- pjmedia_wav_writer_port_get_pos @ 185 NONAME
- pjmedia_wav_writer_port_set_cb @ 186 NONAME
- pjmedia_wave_hdr_file_to_host @ 187 NONAME
- pjmedia_wave_hdr_host_to_file @ 188 NONAME
+ pjmedia_transport_udp_create3 @ 176 NONAME
+ pjmedia_transport_udp_get_info @ 177 NONAME
+ pjmedia_transport_udp_simulate_lost @ 178 NONAME
+ pjmedia_wav_player_port_create @ 179 NONAME
+ pjmedia_wav_player_port_get_pos @ 180 NONAME
+ pjmedia_wav_player_port_set_pos @ 181 NONAME
+ pjmedia_wav_player_set_eof_cb @ 182 NONAME
+ pjmedia_wav_playlist_create @ 183 NONAME
+ pjmedia_wav_playlist_set_eof_cb @ 184 NONAME
+ pjmedia_wav_writer_port_create @ 185 NONAME
+ pjmedia_wav_writer_port_get_pos @ 186 NONAME
+ pjmedia_wav_writer_port_set_cb @ 187 NONAME
+ pjmedia_wave_hdr_file_to_host @ 188 NONAME
+ pjmedia_wave_hdr_host_to_file @ 189 NONAME
diff --git a/pjmedia/include/pjmedia/stream.h b/pjmedia/include/pjmedia/stream.h
index e951b0de..4967c380 100644
--- a/pjmedia/include/pjmedia/stream.h
+++ b/pjmedia/include/pjmedia/stream.h
@@ -90,8 +90,8 @@ struct pjmedia_stream_info
{
pjmedia_type type; /**< Media type (audio, video) */
pjmedia_dir dir; /**< Media direction. */
- pj_sockaddr_in rem_addr; /**< Remote RTP address */
- pj_sockaddr_in rem_rtcp; /**< Optional remote RTCP address. If
+ pj_sockaddr rem_addr; /**< Remote RTP address */
+ pj_sockaddr rem_rtcp; /**< Optional remote RTCP address. If
sin_family is zero, the RTP address
will be calculated from RTP. */
pjmedia_codec_info fmt; /**< Incoming codec format info. */
diff --git a/pjmedia/include/pjmedia/transport_udp.h b/pjmedia/include/pjmedia/transport_udp.h
index 745df46b..12f819d1 100644
--- a/pjmedia/include/pjmedia/transport_udp.h
+++ b/pjmedia/include/pjmedia/transport_udp.h
@@ -112,6 +112,32 @@ PJ_DECL(pj_status_t) pjmedia_transport_udp_create2(pjmedia_endpt *endpt,
pjmedia_transport **p_tp);
/**
+ * Another variant of #pjmedia_transport_udp_create() which allows
+ * the creation of IPv6 transport.
+ *
+ * @param endpt The media endpoint instance.
+ * @param af Address family, which can be pj_AF_INET() for IPv4 or
+ * pj_AF_INET6() for IPv6.
+ * @param name Optional name to be assigned to the transport.
+ * @param addr Optional local address to bind the sockets to. If this
+ * argument is NULL or empty, the sockets will be bound
+ * to all interface.
+ * @param port UDP port number for the RTP socket. The RTCP port number
+ * will be set to one above RTP port.
+ * @param options Options, bitmask of #pjmedia_transport_udp_options.
+ * @param p_tp Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_udp_create3(pjmedia_endpt *endpt,
+ int af,
+ const char *name,
+ const pj_str_t *addr,
+ int port,
+ unsigned options,
+ pjmedia_transport **p_tp);
+
+/**
* Get media socket info from the specified UDP transport.
*
* @param tp The UDP transport interface.
diff --git a/pjmedia/include/pjmedia/types.h b/pjmedia/include/pjmedia/types.h
index 8ff8fe60..ed080d27 100644
--- a/pjmedia/include/pjmedia/types.h
+++ b/pjmedia/include/pjmedia/types.h
@@ -141,7 +141,7 @@ typedef struct pjmedia_sock_info
* address (for example, this address can be the address resolved
* with STUN).
*/
- pj_sockaddr_in rtp_addr_name;
+ pj_sockaddr rtp_addr_name;
/** The RTCP socket handle. */
pj_sock_t rtcp_sock;
@@ -151,7 +151,7 @@ typedef struct pjmedia_sock_info
* address (for example, this address can be the address resolved
* with STUN).
*/
- pj_sockaddr_in rtcp_addr_name;
+ pj_sockaddr rtcp_addr_name;
} pjmedia_sock_info;
diff --git a/pjmedia/src/pjmedia/endpoint.c b/pjmedia/src/pjmedia/endpoint.c
index dbeefe7f..b0c1d4dc 100644
--- a/pjmedia/src/pjmedia/endpoint.c
+++ b/pjmedia/src/pjmedia/endpoint.c
@@ -34,6 +34,7 @@ static const pj_str_t STR_AUDIO = { "audio", 5};
static const pj_str_t STR_VIDEO = { "video", 5};
static const pj_str_t STR_IN = { "IN", 2 };
static const pj_str_t STR_IP4 = { "IP4", 3};
+static const pj_str_t STR_IP6 = { "IP6", 3};
static const pj_str_t STR_RTP_AVP = { "RTP/AVP", 7 };
static const pj_str_t STR_SDP_NAME = { "pjmedia", 7 };
static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
@@ -289,6 +290,7 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
{
pj_time_val tv;
unsigned i;
+ const pj_sockaddr *addr0;
pjmedia_sdp_session *sdp;
pjmedia_sdp_media *m;
pjmedia_sdp_attr *attr;
@@ -303,23 +305,38 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
/* Create and initialize basic SDP session */
sdp = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session);
+ addr0 = &sock_info[0].rtp_addr_name;
+
pj_gettimeofday(&tv);
sdp->origin.user = pj_str("-");
sdp->origin.version = sdp->origin.id = tv.sec + 2208988800UL;
sdp->origin.net_type = STR_IN;
- sdp->origin.addr_type = STR_IP4;
- pj_strdup2(pool, &sdp->origin.addr,
- pj_inet_ntoa(sock_info[0].rtp_addr_name.sin_addr));
+
+ if (addr0->addr.sa_family == pj_AF_INET()) {
+ sdp->origin.addr_type = STR_IP4;
+ pj_strdup2(pool, &sdp->origin.addr,
+ pj_inet_ntoa(addr0->ipv4.sin_addr));
+ } else if (addr0->addr.sa_family == pj_AF_INET6()) {
+ char tmp_addr[PJ_INET6_ADDRSTRLEN];
+
+ sdp->origin.addr_type = STR_IP6;
+ pj_strdup2(pool, &sdp->origin.addr,
+ pj_sockaddr_print(addr0, tmp_addr, sizeof(tmp_addr), 0));
+
+ } else {
+ pj_assert(!"Invalid address family");
+ return PJ_EAFNOTSUP;
+ }
+
sdp->name = STR_SDP_NAME;
/* Since we only support one media stream at present, put the
* SDP connection line in the session level.
*/
sdp->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
- sdp->conn->net_type = STR_IN;
- sdp->conn->addr_type = STR_IP4;
- pj_strdup2(pool, &sdp->conn->addr,
- pj_inet_ntoa(sock_info[0].rtp_addr_name.sin_addr));
+ sdp->conn->net_type = sdp->origin.net_type;
+ sdp->conn->addr_type = sdp->origin.addr_type;
+ sdp->conn->addr = sdp->origin.addr;
/* SDP time and attributes. */
@@ -334,7 +351,7 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
/* Standard media info: */
pj_strdup(pool, &m->desc.media, &STR_AUDIO);
- m->desc.port = pj_ntohs(sock_info[0].rtp_addr_name.sin_port);
+ m->desc.port = pj_sockaddr_get_port(addr0);
m->desc.port_count = 1;
pj_strdup (pool, &m->desc.transport, &STR_RTP_AVP);
@@ -344,15 +361,31 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
/* Add "rtcp" attribute */
#if defined(PJMEDIA_HAS_RTCP_IN_SDP) && PJMEDIA_HAS_RTCP_IN_SDP!=0
- if (sock_info->rtcp_addr_name.sin_family != 0) {
+ if (sock_info->rtcp_addr_name.addr.sa_family != 0) {
+ const pj_sockaddr *rtcp_addr = &sock_info->rtcp_addr_name;
+
attr = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_attr);
attr->name = pj_str("rtcp");
attr->value.ptr = (char*) pj_pool_alloc(pool, 80);
- attr->value.slen =
- pj_ansi_snprintf(attr->value.ptr, 80,
- "%u IN IP4 %s",
- pj_ntohs(sock_info[0].rtcp_addr_name.sin_port),
- pj_inet_ntoa(sock_info[0].rtcp_addr_name.sin_addr));
+ if (rtcp_addr->addr.sa_family == pj_AF_INET()) {
+ attr->value.slen =
+ pj_ansi_snprintf(attr->value.ptr, 80,
+ "%u IN IP4 %s",
+ pj_ntohs(rtcp_addr->ipv4.sin_port),
+ pj_inet_ntoa(rtcp_addr->ipv4.sin_addr));
+ } else if (rtcp_addr->addr.sa_family == pj_AF_INET6()) {
+ char tmp_addr[PJ_INET6_ADDRSTRLEN];
+ attr->value.slen =
+ pj_ansi_snprintf(attr->value.ptr, 80,
+ "%u IN IP6 %s",
+ pj_sockaddr_get_port(rtcp_addr),
+ pj_sockaddr_print(rtcp_addr, tmp_addr,
+ sizeof(tmp_addr), 0));
+
+ } else {
+ pj_assert(!"Unsupported address family");
+ return PJ_EAFNOTSUP;
+ }
pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);
}
#endif
diff --git a/pjmedia/src/pjmedia/session.c b/pjmedia/src/pjmedia/session.c
index c2c4be92..d0784a69 100644
--- a/pjmedia/src/pjmedia/session.c
+++ b/pjmedia/src/pjmedia/session.c
@@ -52,8 +52,9 @@ static const pj_str_t ID_AUDIO = { "audio", 5};
static const pj_str_t ID_VIDEO = { "video", 5};
static const pj_str_t ID_IN = { "IN", 2 };
static const pj_str_t ID_IP4 = { "IP4", 3};
-static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 };
-static const pj_str_t ID_SDP_NAME = { "pjmedia", 7 };
+static const pj_str_t ID_IP6 = { "IP6", 3};
+/*static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 };*/
+/*static const pj_str_t ID_SDP_NAME = { "pjmedia", 7 };*/
static const pj_str_t ID_RTPMAP = { "rtpmap", 6 };
static const pj_str_t ID_TELEPHONE_EVENT = { "telephone-event", 15 };
@@ -129,6 +130,8 @@ PJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp(
const pjmedia_sdp_media *rem_m;
const pjmedia_sdp_conn *local_conn;
const pjmedia_sdp_conn *rem_conn;
+ int rem_af, local_af;
+ pj_sockaddr local_addr;
pjmedia_sdp_rtpmap *rtpmap;
int local_fmtp_mode = 0, rem_fmtp_mode = 0;
unsigned i, pt, fmti;
@@ -185,11 +188,61 @@ PJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp(
return PJMEDIA_SDPNEG_EINVANSTP;
}
+ /* Check address family in remote SDP */
+ rem_af = pj_AF_UNSPEC();
+ if (pj_stricmp(&rem_conn->net_type, &ID_IN)==0) {
+ if (pj_stricmp(&rem_conn->addr_type, &ID_IP4)==0) {
+ rem_af = pj_AF_INET();
+ } else if (pj_stricmp(&rem_conn->addr_type, &ID_IP6)==0) {
+ rem_af = pj_AF_UNSPEC();
+ }
+ }
+
+ if (rem_af==pj_AF_UNSPEC()) {
+ /* Unsupported address family */
+ return PJ_EAFNOTSUP;
+ }
+
+ /* Set remote address: */
+ status = pj_sockaddr_init(rem_af, &si->rem_addr, &rem_conn->addr,
+ rem_m->desc.port);
+ if (status != PJ_SUCCESS) {
+ /* Invalid IP address. */
+ return PJMEDIA_EINVALIDIP;
+ }
+
+ /* Check address family of local info */
+ local_af = pj_AF_UNSPEC();
+ if (pj_stricmp(&local_conn->net_type, &ID_IN)==0) {
+ if (pj_stricmp(&local_conn->addr_type, &ID_IP4)==0) {
+ local_af = pj_AF_INET();
+ } else if (pj_stricmp(&local_conn->addr_type, &ID_IP6)==0) {
+ local_af = pj_AF_UNSPEC();
+ }
+ }
+
+ if (local_af==pj_AF_UNSPEC()) {
+ /* Unsupported address family */
+ return PJ_EAFNOTSUP;
+ }
+
+ /* Set remote address: */
+ status = pj_sockaddr_init(local_af, &local_addr, &local_conn->addr,
+ local_m->desc.port);
+ if (status != PJ_SUCCESS) {
+ /* Invalid IP address. */
+ return PJMEDIA_EINVALIDIP;
+ }
+
+ /* Local and remote address family must match */
+ if (local_af != rem_af)
+ return PJ_EAFNOTSUP;
+
/* Media direction: */
if (local_m->desc.port == 0 ||
- pj_inet_addr(&local_conn->addr).s_addr==0 ||
- pj_inet_addr(&rem_conn->addr).s_addr==0 ||
+ pj_sockaddr_has_addr(&local_addr)==PJ_FALSE ||
+ pj_sockaddr_has_addr(&si->rem_addr)==PJ_FALSE ||
pjmedia_sdp_media_find_attr(local_m, &STR_INACTIVE, NULL)!=NULL)
{
/* Inactive stream. */
@@ -216,15 +269,6 @@ PJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp(
}
-
- /* Set remote address: */
- status = pj_sockaddr_in_init(&si->rem_addr, &rem_conn->addr,
- rem_m->desc.port);
- if (status != PJ_SUCCESS) {
- /* Invalid IP address. */
- return PJMEDIA_EINVALIDIP;
- }
-
/* If "rtcp" attribute is present in the SDP, set the RTCP address
* from that attribute. Otherwise, calculate from RTP address.
*/
@@ -235,22 +279,24 @@ PJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp(
status = pjmedia_sdp_attr_get_rtcp(attr, &rtcp);
if (status == PJ_SUCCESS) {
if (rtcp.addr.slen) {
- status = pj_sockaddr_in_init(&si->rem_rtcp, &rtcp.addr,
- (pj_uint16_t)rtcp.port);
+ status = pj_sockaddr_init(rem_af, &si->rem_rtcp, &rtcp.addr,
+ (pj_uint16_t)rtcp.port);
} else {
- pj_sockaddr_in_init(&si->rem_rtcp, NULL,
- (pj_uint16_t)rtcp.port);
- si->rem_rtcp.sin_addr.s_addr = si->rem_addr.sin_addr.s_addr;
+ pj_sockaddr_init(rem_af, &si->rem_rtcp, NULL,
+ (pj_uint16_t)rtcp.port);
+ pj_memcpy(pj_sockaddr_get_addr(&si->rem_rtcp),
+ pj_sockaddr_get_addr(&si->rem_addr),
+ pj_sockaddr_get_addr_len(&si->rem_addr));
}
}
}
- if (si->rem_rtcp.sin_addr.s_addr == 0) {
+ if (!pj_sockaddr_has_addr(&si->rem_rtcp) == 0) {
int rtcp_port;
- pj_memcpy(&si->rem_rtcp, &si->rem_addr, sizeof(pj_sockaddr_in));
- rtcp_port = pj_ntohs(si->rem_addr.sin_port) + 1;
- si->rem_rtcp.sin_port = pj_htons((pj_uint16_t)rtcp_port);
+ pj_memcpy(&si->rem_rtcp, &si->rem_addr, sizeof(pj_sockaddr));
+ rtcp_port = pj_sockaddr_get_port(&si->rem_addr) + 1;
+ pj_sockaddr_set_port(&si->rem_rtcp, (pj_uint16_t)rtcp_port);
}
diff --git a/pjmedia/src/pjmedia/transport_udp.c b/pjmedia/src/pjmedia/transport_udp.c
index 4eca8763..05a2a816 100644
--- a/pjmedia/src/pjmedia/transport_udp.c
+++ b/pjmedia/src/pjmedia/transport_udp.c
@@ -51,8 +51,9 @@ struct transport_udp
unsigned options; /**< Transport options. */
void *user_data; /**< Only valid when attached */
pj_bool_t attached; /**< Has attachment? */
- pj_sockaddr_in rem_rtp_addr; /**< Remote RTP address */
- pj_sockaddr_in rem_rtcp_addr; /**< Remote RTCP address */
+ pj_sockaddr rem_rtp_addr; /**< Remote RTP address */
+ pj_sockaddr rem_rtcp_addr; /**< Remote RTCP address */
+ int addr_len; /**< Length of addresses. */
void (*rtp_cb)( void*, /**< To report incoming RTP. */
const void*,
pj_ssize_t);
@@ -64,19 +65,19 @@ struct transport_udp
unsigned rx_drop_pct; /**< Percent of rx pkts to drop. */
pj_sock_t rtp_sock; /**< RTP socket */
- pj_sockaddr_in rtp_addr_name; /**< Published RTP address. */
+ pj_sockaddr rtp_addr_name; /**< Published RTP address. */
pj_ioqueue_key_t *rtp_key; /**< RTP socket key in ioqueue */
pj_ioqueue_op_key_t rtp_read_op; /**< Pending read operation */
unsigned rtp_write_op_id;/**< Next write_op to use */
pending_write rtp_pending_write[MAX_PENDING]; /**< Pending write */
- pj_sockaddr_in rtp_src_addr; /**< Actual packet src addr. */
+ pj_sockaddr rtp_src_addr; /**< Actual packet src addr. */
unsigned rtp_src_cnt; /**< How many pkt from this addr. */
int rtp_addrlen; /**< Address length. */
char rtp_pkt[RTP_LEN];/**< Incoming RTP packet buffer */
pj_sock_t rtcp_sock; /**< RTCP socket */
- pj_sockaddr_in rtcp_addr_name; /**< Published RTCP address. */
- pj_sockaddr_in rtcp_src_addr; /**< Actual source RTCP address. */
+ pj_sockaddr rtcp_addr_name; /**< Published RTCP address. */
+ pj_sockaddr rtcp_src_addr; /**< Actual source RTCP address. */
int rtcp_addr_len; /**< Length of RTCP src address. */
pj_ioqueue_key_t *rtcp_key; /**< RTCP socket key in ioqueue */
pj_ioqueue_op_key_t rtcp_read_op; /**< Pending read operation */
@@ -150,6 +151,21 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_create2(pjmedia_endpt *endpt,
unsigned options,
pjmedia_transport **p_tp)
{
+ return pjmedia_transport_udp_create3(endpt, pj_AF_INET(), name,
+ addr, port, options, p_tp);
+}
+
+/**
+ * Create UDP stream transport.
+ */
+PJ_DEF(pj_status_t) pjmedia_transport_udp_create3(pjmedia_endpt *endpt,
+ int af,
+ const char *name,
+ const pj_str_t *addr,
+ int port,
+ unsigned options,
+ pjmedia_transport **p_tp)
+{
pjmedia_sock_info si;
pj_status_t status;
@@ -162,12 +178,15 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_create2(pjmedia_endpt *endpt,
si.rtp_sock = si.rtcp_sock = PJ_INVALID_SOCKET;
/* Create RTP socket */
- status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &si.rtp_sock);
+ status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &si.rtp_sock);
if (status != PJ_SUCCESS)
goto on_error;
/* Bind RTP socket */
- pj_sockaddr_in_init(&si.rtp_addr_name, addr, (pj_uint16_t)port);
+ status = pj_sockaddr_init(af, &si.rtp_addr_name, addr, (pj_uint16_t)port);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
status = pj_sock_bind(si.rtp_sock, &si.rtp_addr_name,
sizeof(si.rtp_addr_name));
if (status != PJ_SUCCESS)
@@ -175,12 +194,16 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_create2(pjmedia_endpt *endpt,
/* Create RTCP socket */
- status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &si.rtcp_sock);
+ status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &si.rtcp_sock);
if (status != PJ_SUCCESS)
goto on_error;
/* Bind RTCP socket */
- pj_sockaddr_in_init(&si.rtcp_addr_name, addr, (pj_uint16_t)(port+1));
+ status = pj_sockaddr_init(af, &si.rtcp_addr_name, addr,
+ (pj_uint16_t)(port+1));
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
status = pj_sock_bind(si.rtcp_sock, &si.rtcp_addr_name,
sizeof(si.rtcp_addr_name));
if (status != PJ_SUCCESS)
@@ -221,23 +244,21 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_attach( pjmedia_endpt *endpt,
/* Sanity check */
PJ_ASSERT_RETURN(endpt && si && p_tp, PJ_EINVAL);
- /* Check name */
- if (!name)
- name = "udpmedia";
-
/* Get ioqueue instance */
ioqueue = pjmedia_endpt_get_ioqueue(endpt);
-
/* Create transport structure */
pool = pjmedia_endpt_create_pool(endpt, name, 512, 512);
if (!pool)
return PJ_ENOMEM;
+ if (!name)
+ name = pool->obj_name;
+
tp = PJ_POOL_ZALLOC_T(pool, struct transport_udp);
tp->pool = pool;
tp->options = options;
- pj_ansi_strcpy(tp->base.name, name);
+ pj_ansi_strncpy(tp->base.name, name, PJ_MAX_OBJ_NAME-1);
tp->base.op = &transport_udp_op;
tp->base.type = PJMEDIA_TRANSPORT_TYPE_UDP;
@@ -248,19 +269,23 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_attach( pjmedia_endpt *endpt,
tp->rtcp_addr_name = si->rtcp_addr_name;
/* If address is 0.0.0.0, use host's IP address */
- if (tp->rtp_addr_name.sin_addr.s_addr == 0) {
+ if (!pj_sockaddr_has_addr(&tp->rtp_addr_name)) {
pj_sockaddr hostip;
- status = pj_gethostip(pj_AF_INET(), &hostip);
+ status = pj_gethostip(tp->rtp_addr_name.addr.sa_family, &hostip);
if (status != PJ_SUCCESS)
goto on_error;
- tp->rtp_addr_name.sin_addr.s_addr = hostip.ipv4.sin_addr.s_addr;
+ pj_memcpy(pj_sockaddr_get_addr(&tp->rtp_addr_name),
+ pj_sockaddr_get_addr(&hostip),
+ pj_sockaddr_get_addr_len(&hostip));
}
/* Same with RTCP */
- if (tp->rtcp_addr_name.sin_addr.s_addr == 0) {
- tp->rtcp_addr_name.sin_addr.s_addr = tp->rtp_addr_name.sin_addr.s_addr;
+ if (!pj_sockaddr_has_addr(&tp->rtcp_addr_name)) {
+ pj_memcpy(pj_sockaddr_get_addr(&tp->rtcp_addr_name),
+ pj_sockaddr_get_addr(&tp->rtp_addr_name),
+ pj_sockaddr_get_addr_len(&tp->rtp_addr_name));
}
/* Setup RTP socket with the ioqueue */
@@ -348,6 +373,7 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_close(pjmedia_transport *tp)
if (udp->rtp_key) {
pj_ioqueue_unregister(udp->rtp_key);
udp->rtp_key = NULL;
+ udp->rtp_sock = PJ_INVALID_SOCKET;
} else if (udp->rtp_sock != PJ_INVALID_SOCKET) {
pj_sock_close(udp->rtp_sock);
udp->rtp_sock = PJ_INVALID_SOCKET;
@@ -356,6 +382,7 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_close(pjmedia_transport *tp)
if (udp->rtcp_key) {
pj_ioqueue_unregister(udp->rtcp_key);
udp->rtcp_key = NULL;
+ udp->rtcp_sock = PJ_INVALID_SOCKET;
} else if (udp->rtcp_sock != PJ_INVALID_SOCKET) {
pj_sock_close(udp->rtcp_sock);
udp->rtcp_sock = PJ_INVALID_SOCKET;
@@ -408,45 +435,48 @@ static void on_rx_rtp( pj_ioqueue_key_t *key,
if (bytes_read>0 &&
(udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0)
{
- if ((udp->rem_rtp_addr.sin_addr.s_addr !=
- udp->rtp_src_addr.sin_addr.s_addr) ||
- (udp->rem_rtp_addr.sin_port !=
- udp->rtp_src_addr.sin_port))
- {
+ if (pj_sockaddr_cmp(&udp->rem_rtp_addr, &udp->rtp_src_addr) != 0) {
+
udp->rtp_src_cnt++;
if (udp->rtp_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) {
+ char addr_text[80];
+
/* Set remote RTP address to source address */
- udp->rem_rtp_addr = udp->rtp_src_addr;
+ pj_memcpy(&udp->rem_rtp_addr, &udp->rtp_src_addr,
+ sizeof(pj_sockaddr));
/* Reset counter */
udp->rtp_src_cnt = 0;
PJ_LOG(4,(udp->base.name,
- "Remote RTP address switched to %s:%d",
- pj_inet_ntoa(udp->rtp_src_addr.sin_addr),
- pj_ntohs(udp->rtp_src_addr.sin_port)));
+ "Remote RTP address switched to %s",
+ pj_sockaddr_print(&udp->rtp_src_addr, addr_text,
+ sizeof(addr_text), 3)));
/* Also update remote RTCP address if actual RTCP source
* address is not heard yet.
*/
- if (udp->rtcp_src_addr.sin_addr.s_addr == 0) {
+ if (!pj_sockaddr_has_addr(&udp->rtcp_src_addr)) {
pj_uint16_t port;
pj_memcpy(&udp->rem_rtcp_addr, &udp->rem_rtp_addr,
- sizeof(pj_sockaddr_in));
+ sizeof(pj_sockaddr));
+ pj_sockaddr_copy_addr(&udp->rem_rtcp_addr,
+ &udp->rem_rtp_addr);
port = (pj_uint16_t)
- (pj_ntohs(udp->rem_rtp_addr.sin_port)+1);
- udp->rem_rtcp_addr.sin_port = pj_htons(port);
+ (pj_sockaddr_get_port(&udp->rem_rtp_addr)+1);
+ pj_sockaddr_set_port(&udp->rem_rtcp_addr, port);
pj_memcpy(&udp->rtcp_src_addr, &udp->rem_rtcp_addr,
- sizeof(pj_sockaddr_in));
+ sizeof(pj_sockaddr));
PJ_LOG(4,(udp->base.name,
- "Remote RTCP address switched to %s:%d",
- pj_inet_ntoa(udp->rtcp_src_addr.sin_addr),
- pj_ntohs(udp->rtcp_src_addr.sin_port)));
+ "Remote RTCP address switched to %s",
+ pj_sockaddr_print(&udp->rtcp_src_addr,
+ addr_text,
+ sizeof(addr_text), 3)));
}
}
@@ -455,7 +485,7 @@ static void on_rx_rtp( pj_ioqueue_key_t *key,
read_next_packet:
bytes_read = sizeof(udp->rtp_pkt);
- udp->rtp_addrlen = sizeof(pj_sockaddr_in);
+ udp->rtp_addrlen = sizeof(udp->rtp_src_addr);
status = pj_ioqueue_recvfrom(udp->rtp_key, &udp->rtp_read_op,
udp->rtp_pkt, &bytes_read, 0,
&udp->rtp_src_addr,
@@ -496,17 +526,17 @@ static void on_rx_rtcp(pj_ioqueue_key_t *key,
*/
if (bytes_read>0 &&
(udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0 &&
- ((udp->rem_rtcp_addr.sin_addr.s_addr !=
- udp->rtcp_src_addr.sin_addr.s_addr) ||
- (udp->rem_rtcp_addr.sin_port !=
- udp->rtcp_src_addr.sin_port)))
+ pj_sockaddr_cmp(&udp->rem_rtcp_addr, &udp->rtcp_src_addr) != 0)
{
+ char addr_text[80];
+
pj_memcpy(&udp->rem_rtcp_addr, &udp->rtcp_src_addr,
- sizeof(pj_sockaddr_in));
+ sizeof(pj_sockaddr));
+
PJ_LOG(4,(udp->base.name,
- "Remote RTCP address switched to %s:%d",
- pj_inet_ntoa(udp->rtcp_src_addr.sin_addr),
- pj_ntohs(udp->rtcp_src_addr.sin_port)));
+ "Remote RTCP address switched to %s",
+ pj_sockaddr_print(&udp->rtcp_src_addr, addr_text,
+ sizeof(addr_text), 3)));
}
bytes_read = sizeof(udp->rtcp_pkt);
@@ -552,7 +582,7 @@ static pj_status_t transport_attach( pjmedia_transport *tp,
pj_ssize_t))
{
struct transport_udp *udp = (struct transport_udp*) tp;
- const pj_sockaddr_in *rtcp_addr;
+ const pj_sockaddr *rtcp_addr;
/* Validate arguments */
PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL);
@@ -563,20 +593,20 @@ static pj_status_t transport_attach( pjmedia_transport *tp,
/* "Attach" the application: */
/* Copy remote RTP address */
- pj_memcpy(&udp->rem_rtp_addr, rem_addr, sizeof(pj_sockaddr_in));
+ pj_memcpy(&udp->rem_rtp_addr, rem_addr, addr_len);
/* Copy remote RTP address, if one is specified. */
- rtcp_addr = (const pj_sockaddr_in*) rem_rtcp;
- if (rtcp_addr && rtcp_addr->sin_addr.s_addr != 0) {
- pj_memcpy(&udp->rem_rtcp_addr, rem_rtcp, sizeof(pj_sockaddr_in));
+ rtcp_addr = (const pj_sockaddr*) rem_rtcp;
+ if (rtcp_addr && pj_sockaddr_has_addr(rtcp_addr)) {
+ pj_memcpy(&udp->rem_rtcp_addr, rem_rtcp, addr_len);
} else {
- int rtcp_port;
+ unsigned rtcp_port;
/* Otherwise guess the RTCP address from the RTP address */
- pj_memcpy(&udp->rem_rtcp_addr, rem_addr, sizeof(pj_sockaddr_in));
- rtcp_port = pj_ntohs(udp->rem_rtp_addr.sin_port) + 1;
- udp->rem_rtcp_addr.sin_port = pj_htons((pj_uint16_t)rtcp_port);
+ pj_memcpy(&udp->rem_rtcp_addr, rem_addr, addr_len);
+ rtcp_port = pj_sockaddr_get_port(&udp->rem_rtp_addr) + 1;
+ pj_sockaddr_set_port(&udp->rem_rtcp_addr, (pj_uint16_t)rtcp_port);
}
/* Save the callbacks */
@@ -584,6 +614,9 @@ static pj_status_t transport_attach( pjmedia_transport *tp,
udp->rtcp_cb = rtcp_cb;
udp->user_data = user_data;
+ /* Save address length */
+ udp->addr_len = addr_len;
+
/* Last, mark transport as attached */
udp->attached = PJ_TRUE;
@@ -659,7 +692,7 @@ static pj_status_t transport_send_rtp( pjmedia_transport *tp,
&udp->rtp_pending_write[id].op_key,
pw->buffer, &sent, 0,
&udp->rem_rtp_addr,
- sizeof(pj_sockaddr_in));
+ udp->addr_len);
udp->rtp_write_op_id = (udp->rtp_write_op_id + 1) %
PJ_ARRAY_SIZE(udp->rtp_pending_write);
@@ -684,7 +717,7 @@ static pj_status_t transport_send_rtcp(pjmedia_transport *tp,
sent = size;
status = pj_ioqueue_sendto( udp->rtcp_key, &udp->rtcp_write_op,
pkt, &sent, 0,
- &udp->rem_rtcp_addr, sizeof(pj_sockaddr_in));
+ &udp->rem_rtcp_addr, udp->addr_len);
if (status==PJ_SUCCESS || status==PJ_EPENDING)
return PJ_SUCCESS;
diff --git a/pjsip-apps/src/samples/siprtp.c b/pjsip-apps/src/samples/siprtp.c
index 1ca46188..2fe135cb 100644
--- a/pjsip-apps/src/samples/siprtp.c
+++ b/pjsip-apps/src/samples/siprtp.c
@@ -1027,7 +1027,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.skinfo.rtp_addr_name.sin_port);
+ m->desc.port = pj_ntohs(tpinfo.skinfo.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 86525ca5..7359faa3 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -1824,16 +1824,16 @@ static void dump_media_session(const char *indent,
for (i=0; i<info.stream_cnt; ++i) {
pjmedia_rtcp_stat stat;
+ char rem_addr_buf[80];
const char *rem_addr;
- int rem_port;
const char *dir;
char last_update[64];
char packets[32], bytes[32], ipbytes[32], avg_bps[32], avg_ipbps[32];
pj_time_val media_duration, now;
pjmedia_session_get_stream_stat(session, i, &stat);
- rem_addr = pj_inet_ntoa(info.stream_info[i].rem_addr.sin_addr);
- rem_port = pj_ntohs(info.stream_info[i].rem_addr.sin_port);
+ rem_addr = pj_sockaddr_print(&info.stream_info[i].rem_addr,
+ rem_addr_buf, sizeof(rem_addr_buf), 3);
if (info.stream_info[i].dir == PJMEDIA_DIR_ENCODING)
dir = "sendonly";
@@ -1846,13 +1846,13 @@ static void dump_media_session(const char *indent,
len = pj_ansi_snprintf(buf, end-p,
- "%s #%d %.*s @%dKHz, %s, peer=%s:%d",
+ "%s #%d %.*s @%dKHz, %s, peer=%s",
indent, i,
(int)info.stream_info[i].fmt.encoding_name.slen,
info.stream_info[i].fmt.encoding_name.ptr,
info.stream_info[i].fmt.clock_rate / 1000,
dir,
- rem_addr, rem_port);
+ rem_addr);
if (len < 1 || len > end-p) {
*p = '\0';
return;
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 39a71f8e..ff9b36fa 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -2014,16 +2014,17 @@ PJ_DEF(void) pjsua_dump(pj_bool_t detail)
for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
pjsua_call *call = &pjsua_var.calls[i];
pjmedia_sock_info skinfo;
+ char addr_buf[80];
/* MSVC complains about skinfo not being initialized */
pj_bzero(&skinfo, sizeof(skinfo));
pjmedia_transport_get_info(call->med_tp, &skinfo);
- PJ_LOG(3,(THIS_FILE, " %s: %s:%d",
+ PJ_LOG(3,(THIS_FILE, " %s: %s",
(pjsua_var.media_cfg.enable_ice ? "ICE" : "UDP"),
- pj_inet_ntoa(skinfo.rtp_addr_name.sin_addr),
- (int)pj_ntohs(skinfo.rtp_addr_name.sin_port)));
+ pj_sockaddr_print(&skinfo.rtp_addr_name, addr_buf,
+ sizeof(addr_buf), 3)));
}
pjsip_tsx_layer_dump(detail);
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 6738284a..da6e0cb4 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -220,6 +220,7 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg,
pj_sockaddr_in bound_addr;
pj_sockaddr_in mapped_addr[2];
pj_status_t status = PJ_SUCCESS;
+ char addr_buf[80];
pj_sock_t sock[2];
/* Make sure STUN server resolution has completed */
@@ -229,7 +230,6 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg,
return status;
}
-
if (next_rtp_port == 0)
next_rtp_port = (pj_uint16_t)cfg->port;
@@ -378,11 +378,11 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg,
&mapped_addr[1], sizeof(pj_sockaddr_in));
PJ_LOG(4,(THIS_FILE, "RTP socket reachable at %s:%d",
- pj_inet_ntoa(skinfo->rtp_addr_name.sin_addr),
- pj_ntohs(skinfo->rtp_addr_name.sin_port)));
+ pj_sockaddr_print(&skinfo->rtp_addr_name, addr_buf,
+ sizeof(addr_buf), 3)));
PJ_LOG(4,(THIS_FILE, "RTCP socket reachable at %s:%d",
- pj_inet_ntoa(skinfo->rtcp_addr_name.sin_addr),
- pj_ntohs(skinfo->rtcp_addr_name.sin_port)));
+ pj_sockaddr_print(&skinfo->rtcp_addr_name, addr_buf,
+ sizeof(addr_buf), 3)));
next_rtp_port += 2;
return PJ_SUCCESS;