diff test-v22/rtp_rx.c @ 10:3c5734b88c20

sipout-test-v22 put together
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 07 Mar 2024 02:33:49 -0800
parents test-fsk/rtp_rx.c@eaf0e8f81a22
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-v22/rtp_rx.c	Thu Mar 07 02:33:49 2024 -0800
@@ -0,0 +1,148 @@
+/*
+ * In this module we implement our RTP handling: obtaining a PSTN-side
+ * RTP endpoint from themwi-rtp-mgr, then handling read select on RTP
+ * and RTCP UDP sockets.
+ */
+
+#include <sys/types.h>
+#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 "../include/pstn_defs.h"
+#include "../librtpalloc/rtp_alloc_simple.h"
+
+extern const uint16_t pcmu_decode_table[256];
+extern const uint16_t pcma_decode_table[256];
+
+extern int rtp_out_enable;	/* misusing the flag :-( */
+
+struct sockaddr_in rtp_local_addr;
+int rtp_udp_fd, rtcp_udp_fd;
+
+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()
+{
+	int rc;
+	struct rtp_alloc_simple res;
+
+	rc = rtp_alloc_simple(TMGW_EP_TYPE_PSTN_ONLY, &res);
+	if (rc < 0)
+		exit(1);	/* error msg already printed */
+	bcopy(&res.pstn_addr, &rtp_local_addr, sizeof(struct sockaddr_in));
+	rtp_udp_fd = res.pstn_rtp_fd;
+	rtcp_udp_fd = res.pstn_rtcp_fd;
+}
+
+void
+rtp_rx_select()
+{
+	struct rtp_packet pkt;
+	struct sockaddr_in sin_from;
+	socklen_t addrlen;
+	int16_t seq_delta;
+	int32_t ts_delta;
+	const uint16_t *pcm_dec_table;
+	int16_t pcm_samples[FRAME_20MS];
+	unsigned n;
+	int rc;
+
+	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:
+		pcm_dec_table = pcmu_decode_table;
+		break;
+	case PSTN_CODEC_PCMA:
+		pcm_dec_table = pcma_decode_table;
+		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;
+	}
+	/* ignore early RTP during ringing, before answer supervision */
+	if (!rtp_out_enable)
+		return;
+	/* feed samples to modem Rx */
+	for (n = 0; n < FRAME_20MS; n++)
+		pcm_samples[n] = pcm_dec_table[pkt.payload[n]];
+	process_rx_frame(pcm_samples);
+}
+
+void
+rtcp_rx_select()
+{
+	u_char buf[512];
+
+	recv(rtcp_udp_fd, buf, sizeof buf, 0);
+	if (!got_some_rtcp) {
+		printf("Got some RTCP\n");
+		got_some_rtcp = 1;
+	}
+}