This source file includes following definitions.
- FIO_EVENT_CB_FUNCTION
- handle_SIGINT
- launch_channel
- on_info
- on_hangup
- on_ring
- on_restart
- on_anything
- chan_ended
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include "freetdm.h"
17 #include <sangoma_pri.h>
18 #include <signal.h>
19 #include <sys/types.h>
20 #include <sys/time.h>
21 #include <sys/resource.h>
22 #include <sys/wait.h>
23
24 typedef struct {
25 int pid;
26 q931_call call;
27 void *pri;
28 int ready;
29 }call_info_t;
30
31
32 #define SANGOMA_MAX_CHAN_PER_SPAN 32
33
34 static call_info_t pidmap[SANGOMA_MAX_CHAN_PER_SPAN];
35
36 FIO_EVENT_CB_FUNCTION(my_ftdm_event_handler)
37 {
38 if (event->e_type = FTDM_EVENT_DTMF) {
39 char *dtmf = event->data;
40 printf("DTMF %s\n", dtmf);
41 }
42 }
43
44
45 #define BYTES 320
46 #define MAX_BYTES 1000
47
48 static int ready = 1;
49
50 static void handle_SIGINT(int sig)
51 {
52 if (sig) {
53 ready = 0;
54 }
55
56 return;
57 }
58
59 static void launch_channel(struct sangoma_pri *spri, int channo)
60 {
61 pid_t pid;
62 int fd = 0, file = 0, inlen = 0, outlen = 0;
63 unsigned char inframe[MAX_BYTES], outframe[MAX_BYTES];
64 fd_set readfds;
65 int mtu_mru=BYTES / 2;
66 int err;
67 ftdm_channel_t *chan;
68 ftdm_codec_t codec = FTDM_CODEC_SLIN;
69 unsigned ms = 20;
70 unsigned int lead = 50;
71 int ifd = -1;
72 ftdm_tone_type_t tt = FTDM_TONE_DTMF;
73 char dtmf[] = "1234567890";
74 int loops = 0;
75
76 pid = fork();
77
78 if (pid) {
79 pidmap[channo-1].pid = pid;
80 printf("-- Launching process %d to handle channel %d\n", pid, channo);
81 return;
82 }
83
84 signal(SIGINT, handle_SIGINT);
85
86
87
88 memset(inframe, 0, MAX_BYTES);
89 memset(outframe, 0, MAX_BYTES);
90
91 if (ftdm_channel_open(spri->span, channo, &chan) != FTDM_SUCCESS) {
92 printf("DEBUG cant open fd!\n");
93 }
94
95
96
97 #if 1
98 if (ftdm_channel_command(chan, FTDM_COMMAND_SET_CODEC, &codec) != FTDM_SUCCESS) {
99 printf("Critical Error: Failed to set driver codec!\n");
100 ftdm_channel_close(&chan);
101 exit(-1);
102 }
103 #endif
104
105 #if 1
106 if (ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_DTMF_DETECT, &tt) != FTDM_SUCCESS) {
107 printf("Critical Error: Failed to set dtmf detect!\n");
108 ftdm_channel_close(&chan);
109 exit(-1);
110 }
111 ftdm_channel_set_event_callback(chan, my_ftdm_event_handler);
112 #endif
113
114
115 if (ftdm_channel_command(chan, FTDM_COMMAND_SET_INTERVAL, &ms) != FTDM_SUCCESS) {
116 printf("Critical Error: Failed to set codec interval!\n");
117 ftdm_channel_close(&chan);
118 exit(-1);
119 }
120
121 file = open("sound.raw", O_RDONLY);
122 if (file < 0){
123 printf("Critical Error: Failed to open sound file!\n");
124 ftdm_channel_close(&chan);
125 exit(-1);
126 }
127
128
129 while(ready) {
130 ftdm_wait_flag_t flags = FTDM_READ;
131 ftdm_size_t len;
132 loops++;
133
134 if (lead) {
135 lead--;
136 }
137
138 if (!lead && loops == 300) {
139 #if 1
140 if (ftdm_channel_command(chan, FTDM_COMMAND_SEND_DTMF, dtmf) != FTDM_SUCCESS) {
141 printf("Critical Error: Failed to send dtmf\n");
142 ftdm_channel_close(&chan);
143 exit(-1);
144 }
145 #endif
146
147 }
148
149 if (ftdm_channel_wait(chan, &flags, 2000) != FTDM_SUCCESS) {
150 printf("wait FAIL! [%s]\n", chan->last_error);
151 break;
152 }
153
154 if (flags & FTDM_READ) {
155 len = MAX_BYTES;
156 if (ftdm_channel_read(chan, inframe, &len) == FTDM_SUCCESS) {
157
158
159 if(!lead && (outlen = read(file, outframe, len)) <= 0) {
160 break;
161 }
162
163 } else {
164 printf("READ FAIL! %d [%s]\n", len, chan->last_error);
165 break;
166 }
167 if (lead) {
168 continue;
169 }
170 ftdm_channel_write(chan, outframe, sizeof(outframe), &len);
171 } else {
172 printf("BREAK");
173 break;
174 }
175 }
176
177 printf("loop done\n");
178
179
180 close(file);
181
182
183 pri_hangup(spri->pri, channo, 16);
184 if (ftdm_channel_close(&chan) != FTDM_SUCCESS) {
185 printf("Critical Error: Failed to close channel [%s]\n", chan->last_error);
186 }
187
188 printf("Call Handler: Process Finished\n");
189 exit(0);
190 }
191
192
193
194
195 static int on_info(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
196 {
197 printf( "number is: %s\n", event->ring.callednum);
198 if(strlen(event->ring.callednum) > 3) {
199 printf( "final number is: %s\n", event->ring.callednum);
200 pri_answer(spri->pri, event->ring.call, 0, 1);
201 }
202 return 0;
203 }
204
205 static int on_hangup(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
206 {
207
208 printf("-- Hanging up channel %d\n", event->hangup.channel);
209 if(pidmap[event->hangup.channel-1].pid) {
210 pri_hangup(spri->pri, event->hangup.call, 16);
211 pri_destroycall(spri->pri, event->hangup.call);
212 kill(pidmap[event->hangup.channel-1].pid, SIGINT);
213 pidmap[event->hangup.channel-1].pid = 0;
214 }
215 return 0;
216 }
217
218 static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
219 {
220 printf("-- Ring on channel %d (from %s to %s), answering...\n", event->ring.channel, event->ring.callingnum, event->ring.callednum);
221 pri_answer(spri->pri, event->ring.call, event->ring.channel, 1);
222 memcpy(&pidmap[event->ring.channel-1].call, event->ring.call, sizeof(q931_call));
223 pidmap[event->ring.channel-1].pri=spri->pri;
224 pidmap[event->ring.channel-1].call = *event->ring.call;
225 launch_channel(spri, event->ring.channel);
226 return 0;
227 }
228
229 static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
230 {
231 printf("-- Restarting channel %d\n", event->restart.channel);
232 return 0;
233 }
234
235 static int on_anything(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
236 {
237 printf("%s: Caught Event %d (%s)\n", __FUNCTION__, event_type, sangoma_pri_event_str(event_type));
238 return 0;
239 }
240
241
242 static void chan_ended(int sig)
243 {
244 int status;
245 int x;
246 struct rusage rusage;
247 pid_t pid;
248 pid = wait4(-1, &status, WNOHANG, &rusage);
249
250 printf("-- PID %d ended\n", pid);
251
252 for (x=0;x<SANGOMA_MAX_CHAN_PER_SPAN;x++) {
253 if (pid == pidmap[x].pid) {
254 pidmap[x].pid = 0;
255 if (pidmap[x].pri){
256 int err=pri_hangup(pidmap[x].pri, &pidmap[x].call, 16);
257
258 printf("Hanging up on PID %i Err=%i\n",pid,err);
259 }
260
261 pidmap[x].pri=NULL;
262 signal(SIGCHLD, chan_ended);
263 return;
264 }
265 }
266
267 if (pid > -1) {
268 fprintf(stderr, "--!! Unknown PID %d exited\n", pid);
269 signal(SIGCHLD, chan_ended);
270 return;
271 }
272 }
273
274
275 int main(int argc, char *argv[])
276 {
277 struct sangoma_pri spri;
278 int debug = 0;
279 if (argv[1]) {
280 debug = atoi(argv[1]);
281 }
282
283 ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG);
284 if (ftdm_global_init() != FTDM_SUCCESS) {
285 fprintf(stderr, "Error loading FreeTDM\n");
286 exit(-1);
287 }
288
289 printf("FreeTDM loaded\n");
290
291
292 debug = PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE;
293 printf("WTF %d\n", debug);
294
295 if (sangoma_init_pri(&spri,
296 1,
297 24,
298 SANGOMA_PRI_SWITCH_DMS100,
299 SANGOMA_PRI_CPE,
300 debug) < 0) {
301 return -1;
302 }
303
304
305
306
307 SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_ANY, on_anything);
308 SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_RING, on_ring);
309 SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_HANGUP, on_hangup);
310 SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_HANGUP_REQ, on_hangup);
311 SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_INFO_RECEIVED, on_info);
312 SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_RESTART, on_restart);
313
314 signal(SIGCHLD, chan_ended);
315 sangoma_run_pri(&spri);
316 return 0;
317 }
318
319
320
321
322
323
324
325
326
327
328