diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 0a4ac93643..d2421fac97 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -42,6 +42,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_RTP_MAX_BUF_LEN 16384 #define SWITCH_RTCP_MAX_BUF_LEN 16384 +#define SWITCH_RTP_MAX_BUF_LEN_WORDS 4094 /* (max / 4) - 2 */ #define SWITCH_RTP_MAX_CRYPTO_LEN 64 #define SWITCH_RTP_KEY_LEN 30 #define SWITCH_RTP_CRYPTO_KEY_32 "AES_CM_128_HMAC_SHA1_32" diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 56df24a743..1fa34bbce2 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -767,6 +767,11 @@ typedef struct { unsigned ssrc:32; /* synchronization source */ } switch_rtp_hdr_t; +typedef struct { + unsigned length:16; /* length */ + unsigned profile:16; /* defined by profile */ +} switch_rtp_hdr_ext_t; + #else /* BIG_ENDIAN */ typedef struct { @@ -781,6 +786,11 @@ typedef struct { unsigned ssrc:32; /* synchronization source */ } switch_rtp_hdr_t; +typedef struct { + unsigned profile:16; /* defined by profile */ + unsigned length:16; /* length */ +} switch_rtp_hdr_ext_t; + #endif #ifdef _MSC_VER diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 2469029298..df4c63baa7 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -97,13 +97,18 @@ static switch_hash_t *alloc_hash = NULL; typedef struct { srtp_hdr_t header; char body[SWITCH_RTP_MAX_BUF_LEN]; + switch_rtp_hdr_ext_t *ext; + char *ebody; } rtp_msg_t; +#define RTP_BODY(_s) (char *) (_s->recv_msg.ebody ? _s->recv_msg.ebody : _s->recv_msg.body) + typedef struct { switch_rtcp_hdr_t header; char body[SWITCH_RTCP_MAX_BUF_LEN]; } rtcp_msg_t; + typedef enum { VAD_FIRE_TALK = (1 << 0), VAD_FIRE_NOT_TALK = (1 << 1) @@ -345,7 +350,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ #ifdef DEBUG_2833 if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d %ld\n", rtp_session->dtmf_data.in_digit_sanity, bytes); } #endif @@ -364,7 +369,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ if (bytes > rtp_header_len && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833) && rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { switch_size_t len = bytes - rtp_header_len; - unsigned char *packet = (unsigned char *) rtp_session->recv_msg.body; + unsigned char *packet = (unsigned char *) RTP_BODY(rtp_session); int end; uint16_t duration; char key; @@ -372,6 +377,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ uint32_t ts; if (!(packet[0] || packet[1] || packet[2] || packet[3]) && len >= 8) { + switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session"); packet += 4; len -= 4; @@ -398,7 +404,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ } } #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned) packet[1], (unsigned) packet[2], (unsigned) packet[3]); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned char) packet[0], (unsigned char) packet[1], (unsigned char) packet[2], (unsigned char) packet[3]); #endif if (in_digit_seq > rtp_session->dtmf_data.in_digit_seq) { @@ -407,7 +413,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ #ifdef DEBUG_2833 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n", - key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, + key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : ""); #endif @@ -488,7 +494,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ } else if (!rtp_session->dtmf_data.in_digit_ts) { #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "start %d\n", ts); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "start %d [%c]\n", ts, key); #endif rtp_session->dtmf_data.in_digit_ts = ts; rtp_session->dtmf_data.last_in_digit_ts = ts; @@ -2872,14 +2878,28 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t switch_assert(bytes); more: *bytes = sizeof(rtp_msg_t); + status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, bytes); ts = ntohl(rtp_session->recv_msg.header.ts); + rtp_session->recv_msg.ebody = NULL; if (*bytes) { uint16_t seq = ntohs((uint16_t) rtp_session->recv_msg.header.seq); + + if (rtp_session->recv_msg.header.x) { /* header extensions */ + rtp_session->recv_msg.ext = (switch_rtp_hdr_ext_t *) rtp_session->recv_msg.body; + + rtp_session->recv_msg.ext->length = ntohs(rtp_session->recv_msg.ext->length); + rtp_session->recv_msg.ext->profile = ntohs(rtp_session->recv_msg.ext->profile); + + if (rtp_session->recv_msg.ext->length < SWITCH_RTP_MAX_BUF_LEN_WORDS) { + rtp_session->recv_msg.ebody = rtp_session->recv_msg.body + (rtp_session->recv_msg.ext->length * 4) + 4; + } + } + +#ifdef DEBUG_MISSED_SEQ if (rtp_session->last_seq && rtp_session->last_seq+1 != seq) { -#ifdef DEBUG_MISSED_SEQ //2012-11-28 18:33:11.799070 [ERR] switch_rtp.c:2883 Missed -65536 RTP frames from sequence [65536] to [-1] (missed). Time since last read [20021] switch_size_t flushed_packets_diff = rtp_session->stats.inbound.flush_packet_count - rtp_session->last_flush_packet_count; switch_size_t num_missed = (switch_size_t)seq - (rtp_session->last_seq+1); @@ -2913,8 +2933,9 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t flushed_packets_diff, rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); } } -#endif + } +#endif rtp_session->last_seq = seq; } @@ -3026,7 +3047,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_BYTESWAP) && rtp_session->recv_msg.header.pt == rtp_session->rpayload) { - switch_swap_linear((int16_t *)rtp_session->recv_msg.body, (int) *bytes - rtp_header_len); + switch_swap_linear((int16_t *)RTP_BODY(rtp_session), (int) *bytes - rtp_header_len); } if (rtp_session->jb && !rtp_session->pause_jb && rtp_session->recv_msg.header.version == 2 && *bytes) { @@ -3042,7 +3063,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (stfu_n_eat(rtp_session->jb, rtp_session->last_read_ts, ntohs((uint16_t) rtp_session->recv_msg.header.seq), rtp_session->recv_msg.header.pt, - rtp_session->recv_msg.body, *bytes - rtp_header_len, rtp_session->timer.samplecount) == STFU_ITS_TOO_LATE) { + RTP_BODY(rtp_session), *bytes - rtp_header_len, rtp_session->timer.samplecount) == STFU_ITS_TOO_LATE) { goto more; } @@ -3056,7 +3077,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (rtp_session->jb && !rtp_session->pause_jb) { if ((jb_frame = stfu_n_read_a_frame(rtp_session->jb))) { - memcpy(rtp_session->recv_msg.body, jb_frame->data, jb_frame->dlen); + memcpy(RTP_BODY(rtp_session), jb_frame->data, jb_frame->dlen); if (jb_frame->plc) { (*flags) |= SFF_PLC; @@ -3679,7 +3700,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } if (bytes && rtp_session->recv_msg.header.version != 2) { - uint8_t *data = (uint8_t *) rtp_session->recv_msg.body; + uint8_t *data = (uint8_t *) RTP_BODY(rtp_session); if (rtp_session->recv_msg.header.version == 0) { if (rtp_session->ice.ice_user) { @@ -3724,7 +3745,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ timer_check: if (do_cng) { - uint8_t *data = (uint8_t *) rtp_session->recv_msg.body; + uint8_t *data = (uint8_t *) RTP_BODY(rtp_session); do_2833(rtp_session, session); @@ -3915,7 +3936,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_read(switch_rtp_t *rtp_session, void *datalen = bytes; - memcpy(data, rtp_session->recv_msg.body, bytes); + memcpy(data, RTP_BODY(rtp_session), bytes); return SWITCH_STATUS_SUCCESS; } @@ -3979,7 +4000,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp bytes = rtp_common_read(rtp_session, &frame->payload, &frame->flags, io_flags); - frame->data = rtp_session->recv_msg.body; + frame->data = RTP_BODY(rtp_session); frame->packet = &rtp_session->recv_msg; frame->packetlen = bytes; frame->source = __FILE__; @@ -4067,7 +4088,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read(switch_rtp_t *rtp_sessi } bytes = rtp_common_read(rtp_session, payload_type, flags, io_flags); - *data = rtp_session->recv_msg.body; + *data = RTP_BODY(rtp_session); if (bytes < 0) { *datalen = 0;