changeset 170:a6eb2de277f6

mgw: massive simplification for continuous RTP stream from BTS
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 20 Nov 2022 01:58:47 -0800
parents 648a64b2e16b
children 4f1f3f799295
files mgw/Makefile mgw/dlcx.c mgw/dtmf_ctrl.c mgw/dtmf_defs.h mgw/dtmf_timer.c mgw/gsm2pstn.c mgw/main.c mgw/mdcx.c mgw/struct.h
diffstat 9 files changed, 26 insertions(+), 223 deletions(-) [+]
line wrap: on
line diff
--- a/mgw/Makefile	Sat Nov 19 23:08:49 2022 -0800
+++ b/mgw/Makefile	Sun Nov 20 01:58:47 2022 -0800
@@ -2,8 +2,8 @@
 CFLAGS=	-O2
 PROG=	themwi-mgw
 OBJS=	crcx.o ctrl_prot.o ctrl_sock.o dlcx.o dtmf_ctrl.o dtmf_init.o \
-	dtmf_table.o dtmf_timer.o g711_decode.o g711_encode.o gsm2pstn.o main.o\
-	mdcx.o pstn2gsm.o readconf.o udpsink.o
+	dtmf_table.o g711_decode.o g711_encode.o gsm2pstn.o main.o mdcx.o \
+	pstn2gsm.o readconf.o udpsink.o
 LIBS=	../libutil/libutil.a
 INSTBIN=/usr/local/bin
 
--- a/mgw/dlcx.c	Sat Nov 19 23:08:49 2022 -0800
+++ b/mgw/dlcx.c	Sun Nov 20 01:58:47 2022 -0800
@@ -80,8 +80,6 @@
 
 	for (ep = delq; ep; ep = np) {
 		np = ep->next;
-		if (ep->dtmf_pp)
-			dtmf_stop_immediate(ep);
 		if (ep->ep_type & TMGW_EP_HAS_GSM_SOCK)
 			free_rtp_end(&ep->rtp_gsm);
 		if (ep->ep_type & TMGW_EP_HAS_PSTN_SOCK)
--- a/mgw/dtmf_ctrl.c	Sat Nov 19 23:08:49 2022 -0800
+++ b/mgw/dtmf_ctrl.c	Sun Nov 20 01:58:47 2022 -0800
@@ -21,38 +21,7 @@
 
 extern struct endpoint *find_ep_by_id();
 
-extern struct timeval cur_event_time;
 extern struct dtmf_desc dtmf_table[];
-extern int dtmf_timer_running;
-
-struct endpoint *dtmf_list_head;
-
-static void
-add_to_dtmf_list(new_ep)
-	struct endpoint *new_ep;
-{
-	struct endpoint *ep, **epp;
-
-	for (epp = &dtmf_list_head; *epp; epp = &ep->dtmf_next)
-		;
-	*epp = new_ep;
-	new_ep->dtmf_pp = epp;
-}
-
-void
-dtmf_stop_immediate(ep)
-	struct endpoint *ep;
-{
-	if (ep->dtmf_frames_sent)
-		ep->dtmf_aftermath = 1;
-	*ep->dtmf_pp = ep->dtmf_next;
-	if (ep->dtmf_next)
-		ep->dtmf_next->dtmf_pp = ep->dtmf_pp;
-	ep->dtmf_pp = 0;
-	ep->dtmf_next = 0;
-	if (!dtmf_list_head)
-		dtmf_timer_running = 0;
-}
 
 void
 process_dtmf_start(conn, req, resp)
@@ -62,8 +31,6 @@
 {
 	struct endpoint *ep;
 	struct dtmf_desc *desc;
-	struct timeval tv_last, tv_diff;
-	unsigned delta_frames;
 
 	ep = find_ep_by_id(conn, req->ep_id);
 	if (!ep) {
@@ -81,37 +48,13 @@
 		resp->res = TMGW_RESP_ERR_PARAM;
 		return;
 	}
-	if (ep->dtmf_pp) {
+	if (ep->dtmf_sample_ptr) {
 		resp->res = TMGW_RESP_ERR_BUSY;
 		return;
 	}
-	if (!ep->g2p_state) {
-		resp->res = TMGW_RESP_ERR_NOTRDY;
-		return;
-	}
-	/* figure out starting timestamp */
-	if (ep->dtmf_aftermath)
-		tv_last = ep->dtmf_last_time;
-	else {
-		ep->dtmf_last_ts = ep->g2p_last_ts;
-		tv_last = ep->g2p_local_time;
-	}
-	ep->dtmf_m_bit = 0;
-	if (timercmp(&cur_event_time, &tv_last, >)) {
-		timersub(&cur_event_time, &tv_last, &tv_diff);
-		delta_frames = tv_diff.tv_sec * 50 + tv_diff.tv_usec / 20000;
-		if (delta_frames) {
-			ep->dtmf_last_ts += delta_frames * SAMPLES_PER_FRAME;
-			ep->dtmf_m_bit = 1;
-		}
-	}
-	/* initialize other state vars */
+	/* start it */
+	ep->dtmf_sample_ptr = desc->samples;
 	ep->dtmf_frames_sent = 0;
-	ep->dtmf_sample_ptr = desc->samples;
-	ep->dtmf_stop_req = 0;
-	/* link it and start it */
-	add_to_dtmf_list(ep);
-	start_dtmf_timer();
 	/* return success */
 	resp->res = TMGW_RESP_OK;
 }
@@ -131,11 +74,6 @@
 	}
 	if (ep->ep_type != TMGW_EP_TYPE_GATEWAY)
 		goto protocol_err;
-	/* return OK whether we stop a tone or if there was none running */
+	ep->dtmf_sample_ptr = 0;
 	resp->res = TMGW_RESP_OK;
-	if (ep->dtmf_pp) {
-		ep->dtmf_stop_req = 1;
-		if (ep->dtmf_frames_sent >= DTMF_MIN_FRAMES)
-			dtmf_stop_immediate(ep);
-	}
 }
--- a/mgw/dtmf_defs.h	Sat Nov 19 23:08:49 2022 -0800
+++ b/mgw/dtmf_defs.h	Sun Nov 20 01:58:47 2022 -0800
@@ -1,9 +1,8 @@
 /*
  * This header file holds various internal definitions for DTMF generation,
- * including key tunable settings of min and max DTMF duration.
+ * including DTMF_MAX_FRAMES limit.
  */
 
-#define	DTMF_MIN_FRAMES		5	/* 100 ms */
 #define	DTMF_MAX_FRAMES		60	/* 1200 ms */
 
 struct dtmf_desc {
--- a/mgw/dtmf_timer.c	Sat Nov 19 23:08:49 2022 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * In this module we implement the timer function of DTMF 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 <syslog.h>
-#include "struct.h"
-#include "int_defs.h"
-#include "dtmf_defs.h"
-
-extern struct timeval cur_event_time;
-extern struct endpoint *dtmf_list_head;
-
-int dtmf_timer_running;
-struct timeval dtmf_next_time;
-
-void
-start_dtmf_timer()
-{
-	if (dtmf_timer_running)
-		return;
-	dtmf_next_time = cur_event_time;
-	dtmf_timer_running = 1;
-}
-
-dtmf_timer_one(ep)
-	struct endpoint *ep;
-{
-	struct rtp_packet pkt;
-	socklen_t addrlen;
-	unsigned frame_limit;
-
-	pkt.v_p_x_cc = 0x80;
-	pkt.m_pt = ep->pstn_payload_type;
-	if (ep->dtmf_m_bit) {
-		pkt.m_pt |= 0x80;
-		ep->dtmf_m_bit = 0;
-	}
-	pkt.seq = htons(++ep->g2p_out_seq);
-	ep->dtmf_last_ts += SAMPLES_PER_FRAME;
-	pkt.tstamp = htonl(ep->dtmf_last_ts);
-	pkt.ssrc = ep->g2p_ssrc;
-	g711_encode_frame(ep->dtmf_sample_ptr, pkt.payload,
-			  ep->pstn_payload_type);
-	ep->dtmf_sample_ptr += SAMPLES_PER_FRAME;
-	addrlen = sizeof(struct sockaddr_in);
-	sendto(ep->rtp_pstn.rtp_fd, &pkt, RTP_PACKET_SIZE_PSTN, 0,
-		(struct sockaddr *) &ep->rtp_pstn.remote_addr, addrlen);
-	ep->dtmf_frames_sent++;
-	ep->dtmf_last_time = cur_event_time;
-	frame_limit = ep->dtmf_stop_req ? DTMF_MIN_FRAMES : DTMF_MAX_FRAMES;
-	if (ep->dtmf_frames_sent >= frame_limit)
-		return 1;
-	else
-		return 0;
-}
-
-void
-dtmf_timer_process()
-{
-	struct endpoint *ep;
-	int fin;
-
-	for (ep = dtmf_list_head; ep; ep = ep->dtmf_next) {
-		fin = dtmf_timer_one(ep);
-		if (!fin)
-			continue;
-		ep->dtmf_aftermath = 1;
-		*ep->dtmf_pp = ep->dtmf_next;
-		if (ep->dtmf_next)
-			ep->dtmf_next->dtmf_pp = ep->dtmf_pp;
-		ep->dtmf_pp = 0;
-		ep->dtmf_next = 0;
-	}
-	if (dtmf_list_head) {
-		dtmf_next_time.tv_usec += 20000;
-		if (dtmf_next_time.tv_usec >= 1000000) {
-			dtmf_next_time.tv_usec -= 1000000;
-			dtmf_next_time.tv_sec++;
-		}
-	} else
-		dtmf_timer_running = 0;
-}
--- a/mgw/gsm2pstn.c	Sat Nov 19 23:08:49 2022 -0800
+++ b/mgw/gsm2pstn.c	Sun Nov 20 01:58:47 2022 -0800
@@ -21,8 +21,7 @@
 #include "struct.h"
 #include "select.h"
 #include "int_defs.h"
-
-extern struct timeval cur_event_time;
+#include "dtmf_defs.h"
 
 #define	ERR_WRONG_UDP_SRC	0x0001
 #define	ERR_BAD_RTP_PACKET	0x0002
@@ -83,8 +82,6 @@
 			ep->g2p_err_flags |= ERR_SSRC_CHANGE;
 		}
 		ep->g2p_state = 0;
-		if (ep->dtmf_pp)
-			dtmf_stop_immediate(ep);
 	}
 	if (ep->g2p_state) {
 		seq_delta = ntohs(pkt.seq) - ep->g2p_last_seq;
@@ -97,49 +94,29 @@
 				ep->g2p_err_flags |= ERR_SEQ_BREAK;
 			}
 			m_out = 1;
-		} else {
-			if (ts_delta == SAMPLES_PER_FRAME)
-				m_out = 0;
-			else if (ts_delta > 0 &&
-				 ts_delta % SAMPLES_PER_FRAME == 0)
-				m_out = 1;
-			else {
-				if (!(ep->g2p_err_flags & ERR_TSTAMP_BREAK)) {
-					syslog(LOG_ERR,
-						"GSM RTP stream tstamp break");
-					ep->g2p_err_flags |= ERR_TSTAMP_BREAK;
-				}
-				m_out = 1;
+		} else if (ts_delta != SAMPLES_PER_FRAME) {
+			if (!(ep->g2p_err_flags & ERR_TSTAMP_BREAK)) {
+				syslog(LOG_ERR, "GSM RTP stream tstamp break");
+				ep->g2p_err_flags |= ERR_TSTAMP_BREAK;
 			}
-		}
+			m_out = 1;
+		} else
+			m_out = 0;
 	} else
 		m_out = 1;
 	ep->g2p_state = 1;
 	ep->g2p_ssrc = pkt.ssrc;
 	ep->g2p_last_ts = ntohl(pkt.tstamp);
 	ep->g2p_last_seq = ntohs(pkt.seq);
-	ep->g2p_local_time = cur_event_time;
 	/* actual transcoding and forwarding */
 	if (!(ep->fwd_mode & TMGW_FWD_ENABLE_GSM2PSTN)) {
 		ep->g2p_drop_flag = 1;
 		return;
 	}
-	if (ep->dtmf_pp)
-		return;
 	if (ep->g2p_drop_flag) {
 		ep->g2p_drop_flag = 0;
 		m_out = 1;
 	}
-	if (ep->dtmf_aftermath) {
-		ts_delta = ep->g2p_last_ts - ep->dtmf_last_ts;
-		if (ts_delta <= 0)
-			return;
-		ep->dtmf_aftermath = 0;
-		if (ts_delta == SAMPLES_PER_FRAME)
-			m_out = 0;
-		else
-			m_out = 1;
-	}
 	switch (ep->gsm_payload_msg_type) {
 	case GSM_TCHF_FRAME:
 		if (bfi)
@@ -151,6 +128,13 @@
 		gsm_decode(ep->gsm_decoder_state, pkt.payload, pcm_samples);
 		break;
 	}
+	if (ep->dtmf_sample_ptr) {
+		bcopy(ep->dtmf_sample_ptr, pcm_samples, SAMPLES_PER_FRAME*2);
+		ep->dtmf_sample_ptr += SAMPLES_PER_FRAME;
+		ep->dtmf_frames_sent++;
+		if (ep->dtmf_frames_sent >= DTMF_MAX_FRAMES)
+			ep->dtmf_sample_ptr = 0;
+	}
 	pkt.m_pt = ep->pstn_payload_type;
 	if (m_out)
 		pkt.m_pt |= 0x80;
--- a/mgw/main.c	Sat Nov 19 23:08:49 2022 -0800
+++ b/mgw/main.c	Sun Nov 20 01:58:47 2022 -0800
@@ -14,13 +14,9 @@
 #include <syslog.h>
 #include <unistd.h>
 
-extern int dtmf_timer_running;
-extern struct timeval dtmf_next_time;
-
 fd_set select_for_read;
 void (*select_handlers[FD_SETSIZE])();
 void *select_data[FD_SETSIZE];
-struct timeval cur_event_time;
 
 static int max_fd;
 
@@ -39,7 +35,6 @@
 	char **argv;
 {
 	fd_set fds;
-	struct timeval timeout;
 	int cc, i;
 
 	openlog("themwi-mgw", 0, LOG_LOCAL5);
@@ -53,31 +48,19 @@
 	/* main select loop */
 	for (;;) {
 		bcopy(&select_for_read, &fds, sizeof(fd_set));
-		if (dtmf_timer_running) {
-			if (timercmp(&dtmf_next_time, &cur_event_time, >))
-				timersub(&dtmf_next_time, &cur_event_time,
-					 &timeout);
-			else
-				timerclear(&timeout);
-			cc = select(max_fd+1, &fds, 0, 0, &timeout);
-		} else
-			cc = select(max_fd+1, &fds, 0, 0, 0);
+		cc = select(max_fd+1, &fds, 0, 0, 0);
 		if (cc < 0) {
 			if (errno == EINTR)
 				continue;
 			syslog(LOG_CRIT, "select: %m");
 			exit(1);
 		}
-		gettimeofday(&cur_event_time, 0);
 		for (i = 0; cc && i <= max_fd; i++) {
 			if (FD_ISSET(i, &fds)) {
 				select_handlers[i](i, select_data[i]);
 				cc--;
 			}
 		}
-		if (dtmf_timer_running &&
-		    !timercmp(&cur_event_time, &dtmf_next_time, <))
-			dtmf_timer_process();
 		free_deleted_endpoints();
 	}
 }
--- a/mgw/mdcx.c	Sat Nov 19 23:08:49 2022 -0800
+++ b/mgw/mdcx.c	Sun Nov 20 01:58:47 2022 -0800
@@ -92,8 +92,8 @@
 			rc = gsm2pstn_init(ep);
 			if (rc != TMGW_RESP_OK)
 				return rc;
-		} else if (ep->dtmf_pp)
-			dtmf_stop_immediate(ep);
+		} else
+			ep->dtmf_sample_ptr = 0;
 		if (req->fwd_mode & TMGW_FWD_ENABLE_PSTN2GSM) {
 			rc = pstn2gsm_init(ep);
 			if (rc != TMGW_RESP_OK)
--- a/mgw/struct.h	Sat Nov 19 23:08:49 2022 -0800
+++ b/mgw/struct.h	Sun Nov 20 01:58:47 2022 -0800
@@ -39,15 +39,9 @@
 	uint16_t	g2p_out_seq;
 	int		g2p_drop_flag;
 	int		g2p_err_flags;
-	struct timeval	g2p_local_time;
 	/* DTMF generation toward PSTN */
+	int16_t		*dtmf_sample_ptr;
 	unsigned	dtmf_frames_sent;
-	uint32_t	dtmf_last_ts;
-	struct timeval	dtmf_last_time;
-	int16_t		*dtmf_sample_ptr;
-	int		dtmf_m_bit;
-	int		dtmf_stop_req;
-	int		dtmf_aftermath;
 	/* PSTN to GSM forwarding */
 	int		p2g_state;
 	uint32_t	p2g_ssrc;
@@ -59,8 +53,6 @@
 	/* linked list management */
 	unsigned	ep_id;
 	struct endpoint	*next;
-	struct endpoint	*dtmf_next;
-	struct endpoint	**dtmf_pp;
 };
 
 struct ctrl_conn {