diff --git a/src/channels/chan_voicemngr.c b/src/channels/chan_voicemngr.c
index 8385295190e61ba9db8769d83250ded6b3b32598..edc2005de3cb571158824fc7a6be0b69b9552ba2 100644
--- a/src/channels/chan_voicemngr.c
+++ b/src/channels/chan_voicemngr.c
@@ -39,7 +39,8 @@
 #include <signal.h>
 #include <semaphore.h>
 #include <sys/types.h>
-#include <sys/stat.h>															// mkfifo()
+#include <sys/stat.h>  // mkfifo()
+
 #include "asterisk/lock.h"
 #include "asterisk/channel.h"
 #include "asterisk/options.h"
@@ -78,7 +79,7 @@ static int cwtimeout_cb(const void *data);
 static int cwbeep_cb(const void *data);
 static int r4hanguptimeout_cb(const void *data);
 static void brcm_generate_rtp_packet(struct brcm_subchannel *p, uint8_t *packet_buf, int type, int marker, int dtmf_timestamp, int seqno);
-static void brcm_interpret_rtcp_packet(struct brcm_subchannel *p, uint8_t *rtcp_frame, uint32_t rtcp_size);
+static void brcm_process_rtcp_packet(struct brcm_subchannel *p, uint8_t *rtcp_frame, uint32_t rtcp_size);
 static int brcm_mute_connection(struct brcm_subchannel *p);
 static int brcm_unmute_connection(struct brcm_subchannel *p);
 static int brcm_close_connection(struct brcm_subchannel *p);
@@ -134,6 +135,16 @@ static int endpt_get_rtp_stats(int line);
 static int is_call_waiting_enabled(const char *sip_account);
 static int has_call_in_sip_client(const char *sip_account);
 
+/* Global jitter buffer configuration - by default, jb is disabled */
+static struct ast_jb_conf default_jbconf =
+{
+	.flags = 0,
+	.max_size = -1,
+	.resync_threshold = -1,
+	.impl = "",
+	.target_extra = -1,
+};
+
 /* Global brcm channel parameters */
 static const char tdesc[] = "Broadcom SLIC Driver";
 static const char config[] = "chan_telephony.conf";
@@ -1572,7 +1583,7 @@ static int brcm_write(struct ast_channel *ast, struct ast_frame *frame)
 		/* copy frame data to audio packet */
 		memcpy(ap->rtp, frame->data.ptr, frame->datalen);
 
-		brcm_interpret_rtcp_packet(sub, ap->rtp, ap->rtp_size);
+		brcm_process_rtcp_packet(sub, ap->rtp, ap->rtp_size);
 
 		pe_bus_send(audio_tx_bus, (uint8_t *)ap, packet_size);
 		free(ap);
@@ -5123,9 +5134,9 @@ static int brcm_close_connection(struct brcm_subchannel *sub)
 	return 0;
 }
 
-
 /* Generate rtp payload, 12 bytes of header and 160 bytes of ulaw payload */
-static void brcm_generate_rtp_packet(struct brcm_subchannel *sub, uint8_t *packet_buf, int type, int marker, int dtmf_timestamp, int seqno) {
+static void brcm_generate_rtp_packet(struct brcm_subchannel *sub, uint8_t *packet_buf, int type, int marker, int dtmf_timestamp, int seqno)
+{
 	unsigned short* packet_buf16 = (unsigned short*)packet_buf;
 	unsigned int*   packet_buf32 = (unsigned int*)packet_buf;
 
@@ -5137,35 +5148,44 @@ static void brcm_generate_rtp_packet(struct brcm_subchannel *sub, uint8_t *packe
 	packet_buf[1] = type;
 	packet_buf[1] |= marker?0x80:0x00;
 	packet_buf16[1] = htons(seqno ? seqno : sub->sequence_number++); //Add sequence number
-	packet_buf32[1] = htonl(sub->time_stamp);	//Add timestamp
+	packet_buf32[1] = htonl(sub->time_stamp); //Add timestamp
 	sub->time_stamp += sub->period*8;
-	packet_buf32[2] = sub->ssrc;	//Random SSRC
+	packet_buf32[2] = sub->ssrc;
 }
 
-static void brcm_interpret_rtcp_packet(struct brcm_subchannel *p, uint8_t *rtcp_frame, uint32_t rtcp_size) {
-	unsigned int *rtcp_word = (unsigned int *)(rtcp_frame); // 32 bits packet
-	unsigned int packetwords = rtcp_size / 4; // number of packets
-	unsigned int position = 0;
-	unsigned int pt;
+/*
+ * This function does the followings.
+ * - Replace SSRC with the value from the sub-channel, which is also used by the corresponding RTP packets within
+ *   the same session. Both RTP and RTCP packets in the same session must have the same SSRC value.
+ * - Accumulate "Interarrival jitter" for farEndInterrivalJitter and jitter_count which are used to calculate
+ *   averageFarEndInterarrivalJitter.
+ */
+static void brcm_process_rtcp_packet(struct brcm_subchannel *p, uint8_t *rtcp_frame, uint32_t rtcp_size)
+{
+	struct rtcp_header_t *rtcp_hdr = (struct rtcp_header_t *)rtcp_frame;
+	uint8_t *packet_end = rtcp_frame + rtcp_size;
 
-	while (position < packetwords) {
-		unsigned int temp_word = ntohl(rtcp_word[position]);
-		pt = (temp_word >> 16) & 0xFF;
-		switch (pt) {
+	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:
 				p->jitter_count++;
-				p->farEndInterrivalJitter += ntohl(rtcp_word[position+10]);
+				p->farEndInterrivalJitter += RTCP_SR_GET_INTERARRIVAL_JITTER(rtcp_hdr);
 				/* Intentional fall through */
 			case RTCP_RR:
 			case RTCP_SDES:
 			case RTCP_XR:
-				//replacing ssrc
-				rtcp_word[position + 1] = p->ssrc;
+				// Replace SSRC for all types of RTCP packets above
+				rtcp_hdr->ssrc = p->ssrc;
 				break;
+
 			default:
+				ast_log(LOG_ERROR, "Unknown RTCP packet type:%hhu\n", rtcp_hdr->pt);
 				break;
-			}
-		position++;
+		}
+		// Move to the next RTCP header for a compound RTCP packet which contains more than one packet types
+		rtcp_hdr = (struct rtcp_header_t *)RTCP_PKT_END(rtcp_hdr);
 	}
 }
 
@@ -5276,4 +5296,13 @@ static int feature_access_code_match(char *sequence)
 	return retval;
 }
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Broadcom SLIC channel");
+/*
+ * To avoid the following loading error.
+ *
+ * module_load_error: Module 'chan_voicemngr.so' was not compiled with the same compile-time options as this version of Asterisk.
+ * module_load_error: Module 'chan_voicemngr.so' will not be initialized as it may cause instability.
+ */
+#undef AST_BUILDOPT_SUM
+#define AST_BUILDOPT_SUM ""
+
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "IOPSYS voicemngr channel");
diff --git a/src/channels/chan_voicemngr.h b/src/channels/chan_voicemngr.h
index a4cd44db272b2de1b268e16dbd4460372ace6a2e..173c2b796146f1c81a6f1958f8aa7afd8f3f7aaf 100644
--- a/src/channels/chan_voicemngr.h
+++ b/src/channels/chan_voicemngr.h
@@ -5,15 +5,11 @@
 #ifndef CHAN_VOICEMNGR_H
 #define CHAN_VOICEMNGR_H
 
-/* Change this value when needed */
-#define CHANNEL_VERSION "1.2"
+#define CHANNEL_VERSION     "1.2"
 
-#define DEFAULT_CALLER_ID "Unknown"
-#define PHONE_MAX_BUF 480
+#define PHONE_MAX_BUF       480
 #define CALL_STATUS_MAX_LEN 14
 
-#define TIMEMSEC 1000
-
 // RTP payload type
 #define RTP_PT_PCMU 0
 #define RTP_PT_G726 2
@@ -24,25 +20,24 @@
 #define RTP_PT_G729 18
 #define RTP_PT_DTMF 101
 
-// Marker bit
-#define RTP_MARKER_BIT  (1<<7)
-
-// RTCP packet type
-#define RTCP_SR      200
-#define RTCP_RR      201
-#define RTCP_SDES    202
-#define RTCP_XR      207
-
-#define NOT_INITIALIZED -1
-//#define EPSTATUS_DRIVER_ERROR -1
-#define MAX_NUM_LINEID 30
+#define NOT_INITIALIZED    -1
+#define MAX_NUM_LINEID     30
 #define PACKET_BUFFER_SIZE 1024
-#define NUM_SUBCHANNELS 2
+#define NUM_SUBCHANNELS    2
 
 #define BEGIN 0
 #define CONT  1
 #define END   2
 
+#define DEFAULT_CALL_WAITING_TIMEOUT   20   // In seconds
+#define DEFAULT_CALL_WAITING_BEEP_FREQ 5    // In seconds
+#define DEFAULT_R4_HANGUP_TIMEOUT      5000 // In milliseconds
+#define DEFAULT_ONHOLD_HANGUP_TIMEOUT  20   // In seconds
+
+// RTP header info
+#define RTP_VERSION     2
+#define RTP_MARKER_BIT  (1<<7)
+
 enum brcm_channel_state {
 	ONHOOK,
 	OFFHOOK,
@@ -60,7 +55,7 @@ enum brcm_channel_state {
 	ALLOCATED,
 };
 
-enum LINE_EVENT {																// Events from low level line (endpoint etc.)
+enum LINE_EVENT { // Events from low level line (endpoint etc.)
 	EVENT_DTMF0,
 	EVENT_DTMF1,
 	EVENT_DTMF2,
@@ -117,6 +112,26 @@ typedef enum callid_state {
 	CALLID_ESTABLISHED = 1
 } callid_state;
 
+/*
+ * Common part of RTCP header according to https://datatracker.ietf.org/doc/html/rfc1889#section-6.3.1
+ */
+#define RTCP_SR      200
+#define RTCP_RR      201
+#define RTCP_SDES    202
+#define RTCP_XR      207
+struct __attribute__((packed)) rtcp_header_t {
+	uint8_t  v_p_rc; // Version, padding and reception report count
+	uint8_t  pt;     // Packet type
+	/* The length of RTCP packet in 32-bit words minus 1, including the header and padding if any.
+	 * For a compound RTCP packet which contains more than one payload type, e.g. SR + SDES + XR, length is
+	 * just for one single RTCP packet instead of all packets. */
+	uint16_t length;
+	uint32_t ssrc;   // Synchronization source identifier for the originator
+};
+#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_SR_GET_INTERARRIVAL_JITTER(header) ntohl(*((uint32_t *)(header) + 10))
+
 struct brcm_subchannel {
 	int id;
 	int call_id;			/* The call_id of connection assigned by pjsip */
@@ -145,7 +160,6 @@ struct brcm_subchannel {
 	char blind_xfer_target[32];	/* Transfer target for unattended call transfer */
 };
 
-
 struct brcm_channel_tech {
 	int (* signal_ringing)(struct brcm_pvt *p);
 	int (* signal_ringing_callerid_pending)(struct brcm_pvt *p);
@@ -155,7 +169,6 @@ struct brcm_channel_tech {
 	int (* release)(struct brcm_pvt *p);
 };
 
-
 struct brcm_pvt {
 	ast_mutex_t lock;
 	int fd;							/* Raw file descriptor for this device */
@@ -195,8 +208,6 @@ enum rtp_type {
 	BRCM_RTCP_RR
 };
 
-
-
 /* Mapping of DTMF to char/name/intval */
 typedef struct DTMF_CHARNAME_MAP
 {
@@ -242,9 +253,9 @@ typedef struct {
 	int autodial_timeoutmsec;
 	int ringsignal;
 	int timeoutmsec;
-        int interdigitopenmsec;
-        int minimumnumberdigits;
-        char terminationdigit;
+	int interdigitopenmsec;
+	int minimumnumberdigits;
+	char terminationdigit;
 	int period;
 	int hangup_xfer;
 	int dialtone_timeoutmsec;
@@ -252,13 +263,12 @@ typedef struct {
 	int offhook_silence_timeoutmsec;
 	int do_not_disturb;
 	int anonymouscallenable;
-        int calleridenable;
-        int calleridnameenable;
+	int calleridenable;
+	int calleridnameenable;
 	flash_spec flashSpec;
 	int mwi_enabled;
 } channel_settings;
 
-
 /* Caller ID */
 #define CLID_MAX_DATE	10
 #define CLID_MAX_NUMBER	21
@@ -269,23 +279,4 @@ typedef struct CLID_STRING
 	char number_name[CLID_MAX_NUMBER + CLID_MAX_NAME + 4]; // 4 = comma, quotation marks and null terminator
 } CLID_STRING;
 
-
-/* Global jitterbuffer configuration - by default, jb is disabled */
-static struct ast_jb_conf default_jbconf =
-{
-	.flags = 0,
-	.max_size = -1,
-	.resync_threshold = -1,
-	.impl = "",
-	.target_extra = -1,
-};
-
-
-#define DEFAULT_CALL_WAITING_TIMEOUT 20 // In seconds
-#define DEFAULT_CALL_WAITING_BEEP_FREQ 5 // In seconds
-
-#define DEFAULT_R4_HANGUP_TIMEOUT 5000 // In milliseconds
-#define DEFAULT_ONHOLD_HANGUP_TIMEOUT 20 // In seconds
-
-
 #endif /* CHAN_VOICEMNGR_H */