# HG changeset patch # User Mychaela Falconia # Date 1668938327 28800 # Node ID a6eb2de277f6ff89cfc67bf0c1812536f4a4e23a # Parent 648a64b2e16bda639d042a0a9ed8573cb0046085 mgw: massive simplification for continuous RTP stream from BTS diff -r 648a64b2e16b -r a6eb2de277f6 mgw/Makefile --- 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 diff -r 648a64b2e16b -r a6eb2de277f6 mgw/dlcx.c --- 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) diff -r 648a64b2e16b -r a6eb2de277f6 mgw/dtmf_ctrl.c --- 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); - } } diff -r 648a64b2e16b -r a6eb2de277f6 mgw/dtmf_defs.h --- 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 { diff -r 648a64b2e16b -r a6eb2de277f6 mgw/dtmf_timer.c --- 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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; -} diff -r 648a64b2e16b -r a6eb2de277f6 mgw/gsm2pstn.c --- 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; diff -r 648a64b2e16b -r a6eb2de277f6 mgw/main.c --- 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 #include -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(); } } diff -r 648a64b2e16b -r a6eb2de277f6 mgw/mdcx.c --- 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) diff -r 648a64b2e16b -r a6eb2de277f6 mgw/struct.h --- 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 {