changeset 188:6aecee01cf0a

sip-manual-out: add RTP stream continuity analysis
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 17 Mar 2023 01:14:57 -0800
parents 258932879f8b
children 1266e024de6c
files include/rtp_defs.h sip-manual-out/rtp.c
diffstat 2 files changed, 96 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/rtp_defs.h	Fri Mar 17 01:14:57 2023 -0800
@@ -0,0 +1,19 @@
+/*
+ * This header file holds some definitions for RTP, as this protocol
+ * functions in our GSM and PSTN environment.
+ */
+
+#define	RTP_PACKET_SIZE_PSTN	172
+#define	RTP_PACKET_SIZE_GSM_FR	45
+#define	RTP_PACKET_SIZE_GSM_EFR	43
+#define	RTP_PACKET_SIZE_BFI	14
+#define	RTP_MAX_PAYLOAD		160
+
+struct rtp_packet {
+	uint8_t		v_p_x_cc;
+	uint8_t		m_pt;
+	uint16_t	seq;
+	uint32_t	tstamp;
+	uint32_t	ssrc;
+	uint8_t		payload[RTP_MAX_PAYLOAD];
+};
--- a/sip-manual-out/rtp.c	Thu Mar 16 23:46:17 2023 -0800
+++ b/sip-manual-out/rtp.c	Fri Mar 17 01:14:57 2023 -0800
@@ -8,16 +8,24 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
 #include "../include/tmgw_const.h"
+#include "../include/rtp_defs.h"
 #include "../librtpalloc/rtp_alloc_simple.h"
 
 struct sockaddr_in rtp_local_addr;
 int rtp_udp_fd, rtcp_udp_fd;
 
-static int got_some_rtp, got_some_rtcp;
+static int rtp_start_flag, rtp_bad_flag, rtp_ssrc_chg_flag;
+static int rtp_seq_brk_flag, rtp_seq_zero_flag, rtp_seq_neg_flag;
+static int rtp_ts_brk_flag;
+static uint32_t rtp_ssrc;
+static uint32_t rtp_last_ts;
+static uint16_t rtp_last_seq;
+static int got_some_rtcp;
 
 void
 obtain_rtp_endp()
@@ -36,12 +44,75 @@
 void
 rtp_rx_select()
 {
-	u_char buf[512];
+	struct rtp_packet pkt;
+	struct sockaddr_in sin_from;
+	socklen_t addrlen;
+	int16_t seq_delta;
+	int32_t ts_delta;
+	int rc;
 
-	recv(rtp_udp_fd, buf, sizeof buf, 0);
-	if (!got_some_rtp) {
-		printf("Got some RTP\n");
-		got_some_rtp = 1;
+	addrlen = sizeof(struct sockaddr_in);
+	rc = recvfrom(rtp_udp_fd, &pkt, sizeof pkt, 0,
+			(struct sockaddr *) &sin_from, &addrlen);
+	if (rc < 0)
+		return;
+	if (rc != RTP_PACKET_SIZE_PSTN) {
+bad_rtp_pkt:	if (!rtp_bad_flag) {
+			printf("Got a bad RTP packet\n");
+			rtp_bad_flag = 1;
+		}
+		return;
+	}
+	if (pkt.v_p_x_cc != 0x80)
+		goto bad_rtp_pkt;
+	switch (pkt.m_pt & 0x7F) {
+	case PSTN_CODEC_PCMU:
+	case PSTN_CODEC_PCMA:
+		break;
+	default:
+		goto bad_rtp_pkt;
+	}
+	if (rtp_start_flag && pkt.ssrc != rtp_ssrc) {
+		if (!rtp_ssrc_chg_flag) {
+			printf("Rx RTP stream changed SSRC\n");
+			rtp_ssrc_chg_flag = 1;
+		}
+	} else if (rtp_start_flag) {
+		seq_delta = ntohs(pkt.seq) - rtp_last_seq;
+		ts_delta = ntohl(pkt.tstamp) - rtp_last_ts;
+		if (seq_delta == 0) {
+			if (!rtp_seq_zero_flag) {
+				printf("Rx RTP seq zero increment\n");
+				rtp_seq_zero_flag = 1;
+			}
+			return;
+		}
+		if (seq_delta < 0) {
+			if (!rtp_seq_neg_flag) {
+				printf("Rx RTP seq negative increment\n");
+				rtp_seq_neg_flag = 1;
+			}
+			return;
+		}
+		if (seq_delta != 1) {
+			if (!rtp_seq_brk_flag) {
+				printf("Rx RTP stream seq break\n");
+				rtp_seq_brk_flag = 1;
+			}
+		} else if (ts_delta != 160) {
+			if (!rtp_ts_brk_flag) {
+				printf("Rx RTP stream tstamp break\n");
+				rtp_ts_brk_flag = 1;
+			}
+		}
+	}
+	rtp_ssrc = pkt.ssrc;
+	rtp_last_ts = ntohl(pkt.tstamp);
+	rtp_last_seq = ntohs(pkt.seq);
+	if (!rtp_start_flag) {
+		printf("Rx RTP stream begins with seq=%u ts=%u\n",
+			rtp_last_seq, rtp_last_ts);
+		rtp_start_flag = 1;
 	}
 }