From 8012177d76bd1682d1592fdda3e7e9dac4e2c58f Mon Sep 17 00:00:00 2001 From: Grzegorz Sluja <grzegorz.sluja@iopsys.eu> Date: Thu, 26 Oct 2023 13:44:23 +0000 Subject: [PATCH] Parse RTCP SR and RR packets for inter-arrival-jitter calculations --- src/channels/chan_voicemngr.c | 28 +++++++++++++++++++++------- src/channels/chan_voicemngr.h | 2 ++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/channels/chan_voicemngr.c b/src/channels/chan_voicemngr.c index 4934f45..48f4632 100644 --- a/src/channels/chan_voicemngr.c +++ b/src/channels/chan_voicemngr.c @@ -5641,21 +5641,28 @@ static void chan_voicemngr_process_incoming_rtcp_packet(struct chan_voicemngr_su struct rtcp_header_t *rtcp_hdr = (struct rtcp_header_t *)rtcp_frame; uint8_t *packet_end = rtcp_frame + rtcp_size; + /* + RTCP packet with RC=0 in the RTCP header does not contain any reception report block + so we cannot get any parameters from such packets for calculations + */ + if (!RTCP_GET_RC(rtcp_hdr)) + return; + while ((uint8_t *)rtcp_hdr + sizeof(struct rtcp_header_t) <= packet_end && // Minimum RTCP packet size validation RTCP_GET_VERSION(rtcp_hdr) == RTP_VERSION && // RTP version validation RTCP_PKT_END(rtcp_hdr) <= packet_end) { // Packet length validation switch (rtcp_hdr->pt) { case RTCP_SR: + case RTCP_RR: p->remote_jitter_count++; - p->farEndInterarrivalJitter = RTCP_SR_GET_INTERARRIVAL_JITTER(rtcp_hdr); + p->farEndInterarrivalJitter = (rtcp_hdr->pt == RTCP_SR ? RTCP_SR_GET_INTERARRIVAL_JITTER(rtcp_hdr) : + RTCP_RR_GET_INTERARRIVAL_JITTER(rtcp_hdr)); p->totalFarEndInterarrivalJitter += p->farEndInterarrivalJitter; - /* Intentional fall through */ - case RTCP_RR: + break; case RTCP_SDES: case RTCP_XR: case RTCP_BYE: break; - default: ast_log(LOG_ERROR, "Unknown incoming RTCP packet type:%hhu\n", rtcp_hdr->pt); break; @@ -5670,21 +5677,28 @@ static void chan_voicemngr_process_outgoing_rtcp_packet(struct chan_voicemngr_su struct rtcp_header_t *rtcp_hdr = (struct rtcp_header_t *)rtcp_frame; uint8_t *packet_end = rtcp_frame + rtcp_size; + /* + RTCP packet with RC=0 in the RTCP header does not contain any reception report block + so we cannot get any parameters from such packets for calculations + */ + if (!RTCP_GET_RC(rtcp_hdr)) + return; + while ((uint8_t *)rtcp_hdr + sizeof(struct rtcp_header_t) <= packet_end && // Minimum RTCP packet size validation RTCP_GET_VERSION(rtcp_hdr) == RTP_VERSION && // RTP version validation RTCP_PKT_END(rtcp_hdr) <= packet_end) { // Packet length validation switch (rtcp_hdr->pt) { case RTCP_SR: + case RTCP_RR: p->local_jitter_count++; - p->receiveInterarrivalJitter = RTCP_SR_GET_INTERARRIVAL_JITTER(rtcp_hdr); + p->receiveInterarrivalJitter = (rtcp_hdr->pt == RTCP_SR ? RTCP_SR_GET_INTERARRIVAL_JITTER(rtcp_hdr) : + RTCP_RR_GET_INTERARRIVAL_JITTER(rtcp_hdr)); p->totalReceiveInterarrivalJitter += p->receiveInterarrivalJitter; break; - case RTCP_RR: case RTCP_SDES: case RTCP_XR: case RTCP_BYE: break; - default: ast_log(LOG_ERROR, "Unknown outgoing RTCP packet type:%hhu\n", rtcp_hdr->pt); break; diff --git a/src/channels/chan_voicemngr.h b/src/channels/chan_voicemngr.h index 38343ab..2c2312c 100644 --- a/src/channels/chan_voicemngr.h +++ b/src/channels/chan_voicemngr.h @@ -138,7 +138,9 @@ struct __attribute__((packed)) rtcp_header_t { }; #define RTCP_PKT_END(header) ((uint8_t *)(header) + (ntohs((header)->length) + 1) * 4) #define RTCP_GET_VERSION(header) ((header)->v_p_rc >> 6) +#define RTCP_GET_RC(header) ((header)->v_p_rc & 0x1F) #define RTCP_SR_GET_INTERARRIVAL_JITTER(header) ntohl(*((uint32_t *)(header) + 10)) +#define RTCP_RR_GET_INTERARRIVAL_JITTER(header) ntohl(*((uint32_t *)(header) + 5)) struct chan_voicemngr_subchannel { int id; -- GitLab