comparison mgw/dtmf_ctrl.c @ 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 529906fddcfa
children 0047c4c08d9e
comparison
equal deleted inserted replaced
169:648a64b2e16b 170:a6eb2de277f6
19 #include "int_defs.h" 19 #include "int_defs.h"
20 #include "dtmf_defs.h" 20 #include "dtmf_defs.h"
21 21
22 extern struct endpoint *find_ep_by_id(); 22 extern struct endpoint *find_ep_by_id();
23 23
24 extern struct timeval cur_event_time;
25 extern struct dtmf_desc dtmf_table[]; 24 extern struct dtmf_desc dtmf_table[];
26 extern int dtmf_timer_running;
27
28 struct endpoint *dtmf_list_head;
29
30 static void
31 add_to_dtmf_list(new_ep)
32 struct endpoint *new_ep;
33 {
34 struct endpoint *ep, **epp;
35
36 for (epp = &dtmf_list_head; *epp; epp = &ep->dtmf_next)
37 ;
38 *epp = new_ep;
39 new_ep->dtmf_pp = epp;
40 }
41
42 void
43 dtmf_stop_immediate(ep)
44 struct endpoint *ep;
45 {
46 if (ep->dtmf_frames_sent)
47 ep->dtmf_aftermath = 1;
48 *ep->dtmf_pp = ep->dtmf_next;
49 if (ep->dtmf_next)
50 ep->dtmf_next->dtmf_pp = ep->dtmf_pp;
51 ep->dtmf_pp = 0;
52 ep->dtmf_next = 0;
53 if (!dtmf_list_head)
54 dtmf_timer_running = 0;
55 }
56 25
57 void 26 void
58 process_dtmf_start(conn, req, resp) 27 process_dtmf_start(conn, req, resp)
59 struct ctrl_conn *conn; 28 struct ctrl_conn *conn;
60 struct tmgw_ctrl_req *req; 29 struct tmgw_ctrl_req *req;
61 struct tmgw_ctrl_resp *resp; 30 struct tmgw_ctrl_resp *resp;
62 { 31 {
63 struct endpoint *ep; 32 struct endpoint *ep;
64 struct dtmf_desc *desc; 33 struct dtmf_desc *desc;
65 struct timeval tv_last, tv_diff;
66 unsigned delta_frames;
67 34
68 ep = find_ep_by_id(conn, req->ep_id); 35 ep = find_ep_by_id(conn, req->ep_id);
69 if (!ep) { 36 if (!ep) {
70 protocol_err: resp->res = TMGW_RESP_ERR_PROT; 37 protocol_err: resp->res = TMGW_RESP_ERR_PROT;
71 return; 38 return;
79 break; 46 break;
80 if (!desc->digit) { 47 if (!desc->digit) {
81 resp->res = TMGW_RESP_ERR_PARAM; 48 resp->res = TMGW_RESP_ERR_PARAM;
82 return; 49 return;
83 } 50 }
84 if (ep->dtmf_pp) { 51 if (ep->dtmf_sample_ptr) {
85 resp->res = TMGW_RESP_ERR_BUSY; 52 resp->res = TMGW_RESP_ERR_BUSY;
86 return; 53 return;
87 } 54 }
88 if (!ep->g2p_state) { 55 /* start it */
89 resp->res = TMGW_RESP_ERR_NOTRDY; 56 ep->dtmf_sample_ptr = desc->samples;
90 return;
91 }
92 /* figure out starting timestamp */
93 if (ep->dtmf_aftermath)
94 tv_last = ep->dtmf_last_time;
95 else {
96 ep->dtmf_last_ts = ep->g2p_last_ts;
97 tv_last = ep->g2p_local_time;
98 }
99 ep->dtmf_m_bit = 0;
100 if (timercmp(&cur_event_time, &tv_last, >)) {
101 timersub(&cur_event_time, &tv_last, &tv_diff);
102 delta_frames = tv_diff.tv_sec * 50 + tv_diff.tv_usec / 20000;
103 if (delta_frames) {
104 ep->dtmf_last_ts += delta_frames * SAMPLES_PER_FRAME;
105 ep->dtmf_m_bit = 1;
106 }
107 }
108 /* initialize other state vars */
109 ep->dtmf_frames_sent = 0; 57 ep->dtmf_frames_sent = 0;
110 ep->dtmf_sample_ptr = desc->samples;
111 ep->dtmf_stop_req = 0;
112 /* link it and start it */
113 add_to_dtmf_list(ep);
114 start_dtmf_timer();
115 /* return success */ 58 /* return success */
116 resp->res = TMGW_RESP_OK; 59 resp->res = TMGW_RESP_OK;
117 } 60 }
118 61
119 void 62 void
129 protocol_err: resp->res = TMGW_RESP_ERR_PROT; 72 protocol_err: resp->res = TMGW_RESP_ERR_PROT;
130 return; 73 return;
131 } 74 }
132 if (ep->ep_type != TMGW_EP_TYPE_GATEWAY) 75 if (ep->ep_type != TMGW_EP_TYPE_GATEWAY)
133 goto protocol_err; 76 goto protocol_err;
134 /* return OK whether we stop a tone or if there was none running */ 77 ep->dtmf_sample_ptr = 0;
135 resp->res = TMGW_RESP_OK; 78 resp->res = TMGW_RESP_OK;
136 if (ep->dtmf_pp) {
137 ep->dtmf_stop_req = 1;
138 if (ep->dtmf_frames_sent >= DTMF_MIN_FRAMES)
139 dtmf_stop_immediate(ep);
140 }
141 } 79 }