diff mgw/dtmf_timer.c @ 127:f062c32a5116

mgw: implement DTMF
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 01 Oct 2022 20:31:15 -0800
parents
children 529906fddcfa
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mgw/dtmf_timer.c	Sat Oct 01 20:31:15 2022 -0800
@@ -0,0 +1,90 @@
+/*
+ * 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++;
+	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;
+}