diff test-voice/rtp_tx.c @ 0:35c0d9f03c0a

beginning with sipout-test-voice, a copy of sip-manual-out from themwi-system-sw
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 03 Mar 2024 23:20:19 -0800
parents
children 059b79c9f0c3
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-voice/rtp_tx.c	Sun Mar 03 23:20:19 2024 -0800
@@ -0,0 +1,132 @@
+/*
+ * In this module we implement outgoing RTP stream generation.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "../include/tmgw_const.h"
+#include "../include/rtp_defs.h"
+#include "../libutil/osmo_bits.h"
+
+extern struct sockaddr_in rtp_local_addr, rtp_remote_addr;
+extern int rtp_udp_fd, rtcp_udp_fd, pcma_selected;
+extern struct timeval cur_event_time;
+
+static uint32_t rtp_ssrc;
+static uint32_t rtp_out_ts;
+static uint16_t rtp_out_seq;
+
+static uint8_t pcm_fill_octet;
+
+static uint16_t tfo_fill_buf[9], tfo_req_buf[7];
+static uint16_t *is_out_ptr;
+static unsigned is_out_count;
+static int tfo_stop_req;
+
+void
+assign_rtpout_ssrc()
+{
+	rtp_ssrc = cur_event_time.tv_sec ^ cur_event_time.tv_usec ^ getpid();
+}
+
+void
+init_pcm_fill_octet()
+{
+	if (pcma_selected)
+		pcm_fill_octet = 0xD5;
+	else
+		pcm_fill_octet = 0xFF;
+}
+
+void
+prepare_tfo_fill()
+{
+	tfo_fill_buf[0] = 0x15A;
+	tfo_fill_buf[1] = 0x1A9;
+	tfo_fill_buf[2] = 0x129;
+	tfo_fill_buf[3] = 0x15A;
+	tfo_fill_buf[4] = 0x1A9;
+	tfo_fill_buf[5] = 0x129;
+	tfo_fill_buf[6] = 0x15A;
+	tfo_fill_buf[7] = 0x1A9;
+	tfo_fill_buf[8] = 0x129;
+}
+
+static void
+insert_is_msg(payload, word)
+	uint8_t *payload;
+	uint16_t word;
+{
+	ubit_t is_bits[10];
+	uint8_t *bytep;
+	unsigned n;
+
+	uint16_to_bits(word, is_bits, 10);
+	for (n = 0; n < 10; n++) {
+		bytep = payload + n * 16;
+		*bytep &= 0xFE;
+		*bytep |= is_bits[n];
+	}
+}
+
+void
+generate_rtp_packet()
+{
+	struct rtp_packet pkt;
+	socklen_t addrlen;
+
+	pkt.v_p_x_cc = 0x80;
+	pkt.m_pt = pcma_selected ? PSTN_CODEC_PCMA : PSTN_CODEC_PCMU;
+	pkt.seq = htons(rtp_out_seq++);
+	pkt.tstamp = htonl(rtp_out_ts);
+	rtp_out_ts += 160;
+	pkt.ssrc = rtp_ssrc;
+	memset(pkt.payload, pcm_fill_octet, RTP_MAX_PAYLOAD);
+	if (is_out_count) {
+		insert_is_msg(pkt.payload, *is_out_ptr++);
+		is_out_count--;
+		if (!is_out_count && !tfo_stop_req) {
+			is_out_ptr = tfo_req_buf;
+			is_out_count = 7;
+		}
+	}
+	addrlen = sizeof(struct sockaddr_in);
+	sendto(rtp_udp_fd, &pkt, RTP_PACKET_SIZE_PSTN, 0,
+		(struct sockaddr *) &rtp_remote_addr, addrlen);
+}
+
+void
+set_pcm_fill_octet(oct)
+	unsigned oct;
+{
+	pcm_fill_octet = oct;
+}
+
+void
+send_tfo_req(sig, codec)
+	unsigned sig, codec;
+{
+	tfo_req_buf[0] = 0x15A;
+	tfo_req_buf[1] = 0x1A9;
+	tfo_req_buf[2] = 0x05D;
+	tfo_req_buf[3] = 0x14E;
+	tfo_req_buf[4] = 0x14B;
+	encode_tfo_ext_words(sig, codec, 0, tfo_req_buf + 5);
+	is_out_ptr = tfo_fill_buf;
+	is_out_count = 9;
+	tfo_stop_req = 0;
+}
+
+void
+stop_tfo_out()
+{
+	tfo_stop_req = 1;
+}