From 3958e2dbefc4f2db0b17de30ccff2bfa4d78f741 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Sat, 15 Sep 2007 08:55:00 +0000 Subject: Implemented ticket #373: Packet loss simulation in PJMEDIA ICE transport git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1436 74dad513-b988-da41-8d7b-12977e46ad98 --- pjmedia/include/pjmedia/transport_ice.h | 16 +++++++++++ pjmedia/src/pjmedia/transport_ice.c | 50 +++++++++++++++++++++++++++++++-- pjmedia/src/pjmedia/transport_udp.c | 11 +++----- 3 files changed, 68 insertions(+), 9 deletions(-) (limited to 'pjmedia') diff --git a/pjmedia/include/pjmedia/transport_ice.h b/pjmedia/include/pjmedia/transport_ice.h index 2a51ae76..da1e0512 100644 --- a/pjmedia/include/pjmedia/transport_ice.h +++ b/pjmedia/include/pjmedia/transport_ice.h @@ -216,6 +216,22 @@ PJ_DECL(pj_status_t) pjmedia_ice_start_ice(pjmedia_transport *tp, PJ_DECL(pj_status_t) pjmedia_ice_stop_ice(pjmedia_transport *tp); +/** + * Simulate packet lost in the specified direction (for testing purposes). + * When enabled, the transport will randomly drop packets to the specified + * direction. + * + * @param tp The ICE media transport. + * @param dir Media direction to which packets will be randomly dropped. + * @param pct_lost Percent lost (0-100). Set to zero to disable packet + * lost simulation. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pjmedia_ice_simulate_lost(pjmedia_transport *tp, + pjmedia_dir dir, + unsigned pct_lost); + diff --git a/pjmedia/src/pjmedia/transport_ice.c b/pjmedia/src/pjmedia/transport_ice.c index 4fa21c29..a45a3ac1 100644 --- a/pjmedia/src/pjmedia/transport_ice.c +++ b/pjmedia/src/pjmedia/transport_ice.c @@ -20,6 +20,8 @@ #include #include #include +#include + struct transport_ice { @@ -33,6 +35,9 @@ struct transport_ice pj_sockaddr_in remote_rtp; pj_sockaddr_in remote_rtcp; + unsigned tx_drop_pct; /**< Percent of tx pkts to drop. */ + unsigned rx_drop_pct; /**< Percent of rx pkts to drop. */ + void (*rtp_cb)(void*, const void*, pj_ssize_t); @@ -650,6 +655,17 @@ static pj_status_t tp_send_rtp(pjmedia_transport *tp, pj_size_t size) { struct transport_ice *tp_ice = (struct transport_ice*)tp; + + /* Simulate packet lost on TX direction */ + if (tp_ice->tx_drop_pct) { + if ((pj_rand() % 100) <= (int)tp_ice->tx_drop_pct) { + PJ_LOG(5,(tp_ice->ice_st->obj_name, + "TX RTP packet dropped because of pkt lost " + "simulation")); + return PJ_SUCCESS; + } + } + return pj_ice_strans_sendto(tp_ice->ice_st, 1, pkt, size, &tp_ice->remote_rtp, sizeof(pj_sockaddr_in)); @@ -678,9 +694,21 @@ static void ice_on_rx_data(pj_ice_strans *ice_st, unsigned comp_id, { struct transport_ice *tp_ice = (struct transport_ice*) ice_st->user_data; - if (comp_id==1 && tp_ice->rtp_cb) + if (comp_id==1 && tp_ice->rtp_cb) { + + /* Simulate packet lost on RX direction */ + if (tp_ice->rx_drop_pct) { + if ((pj_rand() % 100) <= (int)tp_ice->rx_drop_pct) { + PJ_LOG(5,(ice_st->obj_name, + "RX RTP packet dropped because of pkt lost " + "simulation")); + return; + } + } + (*tp_ice->rtp_cb)(tp_ice->stream, pkt, size); - else if (comp_id==2 && tp_ice->rtcp_cb) + + } else if (comp_id==2 && tp_ice->rtcp_cb) (*tp_ice->rtcp_cb)(tp_ice->stream, pkt, size); PJ_UNUSED_ARG(src_addr); @@ -733,3 +761,21 @@ static void ice_on_ice_complete(pj_ice_strans *ice_st, } +/* Simulate lost */ +PJ_DEF(pj_status_t) pjmedia_ice_simulate_lost( pjmedia_transport *tp, + pjmedia_dir dir, + unsigned pct_lost) +{ + struct transport_ice *ice = (struct transport_ice*) tp; + + PJ_ASSERT_RETURN(tp && pct_lost <= 100, PJ_EINVAL); + + if (dir & PJMEDIA_DIR_ENCODING) + ice->tx_drop_pct = pct_lost; + + if (dir & PJMEDIA_DIR_DECODING) + ice->rx_drop_pct = pct_lost; + + return PJ_SUCCESS; +} + diff --git a/pjmedia/src/pjmedia/transport_udp.c b/pjmedia/src/pjmedia/transport_udp.c index 6b1e265d..8f6eaa10 100644 --- a/pjmedia/src/pjmedia/transport_udp.c +++ b/pjmedia/src/pjmedia/transport_udp.c @@ -699,16 +699,13 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_simulate_lost(pjmedia_transport *tp, { struct transport_udp *udp = (struct transport_udp*)tp; - PJ_ASSERT_RETURN(tp && - (dir==PJMEDIA_DIR_ENCODING||dir==PJMEDIA_DIR_DECODING) && - pct_lost <= 100, PJ_EINVAL); + PJ_ASSERT_RETURN(tp && pct_lost <= 100, PJ_EINVAL); - if (dir == PJMEDIA_DIR_ENCODING) + if (dir & PJMEDIA_DIR_ENCODING) udp->tx_drop_pct = pct_lost; - else if (dir == PJMEDIA_DIR_DECODING) + + if (dir & PJMEDIA_DIR_DECODING) udp->rx_drop_pct = pct_lost; - else - return PJ_EINVAL; return PJ_SUCCESS; } -- cgit v1.2.3